From 36c7928c3e948cf8862d4b5c3df27c5a841cb503 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 25 Jun 2009 15:40:31 +0200 Subject: Staging: add rt3090 wireless driver This is the vendor driver for the Ralink RT3090 chipset. It should be later cleaned and ported to use the existing rt2x00 infrastructure or just replaced by the proper version. [ Unfortunately since it follows the same design/implementation like rt{286,287,307}0 drivers (already present in the staging tree) it is highly unlikely that it will see much love from the wireless development community.. ] However since the development of the cleaner/proper version can take significant time lets give distros (i.e. openSUSE seems to already have the package with the original vendor driver) and users "something" to use in the meantime. I forward ported it to 2.6.31-rc1, ported to the Linux build system and did some initial cleanups. More fixes/cleanups to come later (it seems that the driver can be made to share most of its code with the other Ralink drivers already present in the staging tree). Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 975ecddbce3..530a29cc8aa 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -75,6 +75,8 @@ source "drivers/staging/rt2870/Kconfig" source "drivers/staging/rt3070/Kconfig" +source "drivers/staging/rt3090/Kconfig" + source "drivers/staging/comedi/Kconfig" source "drivers/staging/asus_oled/Kconfig" -- cgit v1.2.3 From 5d1fe0c98f2aef99fb57aaf6dd25e793c186cea3 Mon Sep 17 00:00:00 2001 From: Forest Bond Date: Sat, 13 Jun 2009 07:39:00 -0400 Subject: Staging: vt6656: Integrate vt6656 into build system. Integrate drivers/staging/vt6656 into build system. Signed-off-by: Forest Bond Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/vt6656/Kconfig | 5 + drivers/staging/vt6656/Makefile | 243 +++++++--------------------------------- 4 files changed, 47 insertions(+), 204 deletions(-) create mode 100644 drivers/staging/vt6656/Kconfig (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 530a29cc8aa..f77b35ec288 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -123,6 +123,8 @@ source "drivers/staging/serqt_usb2/Kconfig" source "drivers/staging/vt6655/Kconfig" +source "drivers/staging/vt6656/Kconfig" + source "drivers/staging/cpc-usb/Kconfig" source "drivers/staging/pata_rdc/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 783dba49969..b21503569e9 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ +obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig new file mode 100644 index 00000000000..f823a74bbfc --- /dev/null +++ b/drivers/staging/vt6656/Kconfig @@ -0,0 +1,5 @@ +config VT6656 + tristate "VIA Technologies VT6656 support" + ---help--- + This is a vendor-written driver for VIA VT6656. + diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile index 7d20efef555..4467bb1a608 100644 --- a/drivers/staging/vt6656/Makefile +++ b/drivers/staging/vt6656/Makefile @@ -1,204 +1,39 @@ -# -# Build options: -# -# - -HOSTAP := 1 - - -KSP := /lib/modules/$(shell uname -r)/build \ - /usr/src/linux-$(shell uname -r) \ - /usr/src/linux-$(shell uname -r | sed 's/-.*//') \ - /usr/src/kernel-headers-$(shell uname -r) \ - /usr/src/kernel-source-$(shell uname -r) \ - /usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \ - /usr/src/linux - -test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir)) -KSP := $(foreach dir, $(KSP), $(test_dir)) - -KSRC := $(firstword $(KSP)) - -ifeq (,$(KSRC)) - $(error Linux kernel source not found) -endif - -# check kernel version -KVER := $(shell uname -r | cut -c1-3 | sed 's/2\.[56]/2\.6/') -KERVER2=$(shell uname -r | cut -d. -f2) - -ifeq ($(KVER), 2.6) -# 2.6 kernel -TARGET = vntwusb.ko - -else -TARGET = vntwusb.o - -endif - -INSTDIR := $(shell find /lib/modules/$(shell uname -r) -name $(TARGET) -printf "%h\n" | sort | head -1) -ifeq (,$(INSTDIR)) - ifeq (,$(KERVER2)) - ifneq (,$(wildcard /lib/modules/$(shell uname -r)/kernel)) - INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net - else - INSTDIR := /lib/modules/$(shell uname -r)/net - endif - else - ifneq ($(KERVER2),2) - INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net - else - INSTDIR := /lib/modules/$(shell uname -r)/net - endif - endif -endif - - -SRC = main_usb.c card.c mac.c baseband.c wctl.c 80211mgr.c \ - wcmd.c wmgr.c bssdb.c wpa2.c rxtx.c dpc.c power.c datarate.c \ - mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c \ - tkip.c michael.c rf.c iwctl.c wpactl.c aes_ccmp.c \ - usbpipe.c channel.c control.c firmware.c int.c - - -ifeq ($(HOSTAP), 1) -# CFLAGS += -DHOSTAP - EXTRA_CFLAGS += -DHOSTAP -endif - - -#CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/include -EXTRA_CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/include - -# build rule -ifeq ($(KVER), 2.6) -# 2.6 kernel - -ifndef KERNEL_CONF -KERNEL_CONF= $(KSRC)/.config -endif - -include ${KERNEL_CONF} - -obj-m += vntwusb.o - -vntwusb-objs := main_usb.o card.o mac.o baseband.o wctl.o 80211mgr.o \ - wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o \ - mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \ - michael.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o \ - usbpipe.o channel.o control.o firmware.o int.o - -.c.o: -# $(CC) $(CFLAGS) -o $@ $< - $(CC) $(EXTRA_CFLAGS) -o $@ $< - -default: - make -C $(KSRC) SUBDIRS=$(shell pwd) modules - -else - -# 2.2/2.4 kernel -OBJS := main_usb.o card.o mac.o baseband.o wctl.o 80211mgr.o \ - wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o \ - mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \ - michael.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o \ - usbpipe.o channel.o control.o - -VERSION_FILE := $(KSRC)/include/linux/version.h -CONFIG_FILE := $(KSRC)/include/linux/config.h - - -ifeq (,$(wildcard $(VERSION_FILE))) - $(error Linux kernel source not configured - missing version.h) -endif - -ifeq (,$(wildcard $(CONFIG_FILE))) - $(error Linux kernel source not configured - missing config.h) -endif - -ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version))) - CC := kgcc gcc cc -else - CC := gcc cc -endif - -test_cc = $(shell which $(cc) > /dev/null 2>&1 && echo $(cc)) -CC := $(foreach cc, $(CC), $(test_cc)) -CC := $(firstword $(CC)) - -#CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe -#CFLAGS += -I$(KSRC)/include -Wstrict-prototypes -fomit-frame-pointer -fno-strict-aliasing -#CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ -# echo "-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h") -EXTRA_CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe -EXTRA_CFLAGS += -I$(KSRC)/include -Wstrict-prototypes -fomit-frame-pointer -fno-strict-aliasing -EXTRA_CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ - echo "-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h") - -.SILENT: $(TARGET) clean - - -# look for SMP in config.h -#SMP := $(shell $(CC) $(CFLAGS) -E -dM $(CONFIG_FILE) | \ -# grep CONFIG_SMP | awk '{ print $$3 }') -SMP := $(shell $(CC) $(EXTRA_CFLAGS) -E -dM $(CONFIG_FILE) | \ - grep CONFIG_SMP | awk '{ print $$3 }') -ifneq ($(SMP),1) - SMP := 0 -endif - - -ifeq ($(SMP), 1) -# CFLAGS += -D__SMP__ - EXTRA_CFLAGS += -D__SMP__ -endif - - - -# check x86_64 -SUBARCH := $(shell uname -m) -ifeq ($(SUBARCH),x86_64) -# CFLAGS += -mcmodel=kernel -mno-red-zone - EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone -endif - - -$(TARGET): $(filter-out $(TARGET), $(SRC:.c=.o)) - $(LD) -r $^ -o $@ - echo; echo - echo "**************************************************" - echo "Build options:" - echo " VERSION $(KVER)" - echo -n " SMP " - if [ "$(SMP)" = "1" ]; \ - then echo "Enabled"; else echo "Disabled"; fi - - - -endif # ifeq ($(KVER),2.6) - - -ifeq ($(KVER), 2.6) -install: default -else -install: clean $(TARGET) -endif - mkdir -p $(MOD_ROOT)$(INSTDIR) - install -m 644 -o root $(TARGET) $(MOD_ROOT)$(INSTDIR) - -ifeq (,$(MOD_ROOT)) - /sbin/depmod -a || true -else - /sbin/depmod -b $(MOD_ROOT) -a || true -endif - - -uninstall: - rm -f $(INSTDIR)/$(TARGET) - /sbin/depmod -a - -clean: - rm -f $(TARGET) $(SRC:.c=.o) *~ *.o - rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o - --include .depend.mak +# TODO: all of these should be removed +EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -D__NO_VERSION__ +EXTRA_CFLAGS += -DHOSTAP + +vt6656-y += main_usb.o \ + card.o \ + mac.o \ + baseband.o \ + wctl.o \ + 80211mgr.o \ + wcmd.o\ + wmgr.o \ + bssdb.o \ + wpa2.o \ + rxtx.o \ + dpc.o \ + power.o \ + datarate.o \ + mib.o \ + rc4.o \ + tether.o \ + tcrc.o \ + ioctl.o \ + hostap.o \ + wpa.o \ + key.o \ + tkip.o \ + michael.o \ + rf.o \ + iwctl.o \ + wpactl.o \ + aes_ccmp.o \ + usbpipe.o \ + channel.o \ + control.o \ + firmware.o \ + int.o + +obj-$(CONFIG_VT6656) += vt6656.o -- cgit v1.2.3 From c4f3020fc40b7977090dba42e1165db653408440 Mon Sep 17 00:00:00 2001 From: Richard Ash Date: Tue, 23 Jun 2009 17:28:06 +0100 Subject: Staging: add Support for Quatech ESU2-100 USB 2.0 8-port serial adaptor The patch is of the "works as far as it goes" variety, in that the module compiles and loads, the device nodes are registered and the unit switched on, but nothing actually works. On the other hand, it doesn't panic the kernel, as far as I know. Signed-off-by: Richard Ash Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/quatech_usb2/Kconfig | 15 + drivers/staging/quatech_usb2/Makefile | 1 + drivers/staging/quatech_usb2/quatech_usb2.c | 611 ++++++++++++++++++++++++++++ 5 files changed, 630 insertions(+) create mode 100644 drivers/staging/quatech_usb2/Kconfig create mode 100644 drivers/staging/quatech_usb2/Makefile create mode 100644 drivers/staging/quatech_usb2/quatech_usb2.c (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index f77b35ec288..549ae79199e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -121,6 +121,8 @@ source "drivers/staging/octeon/Kconfig" source "drivers/staging/serqt_usb2/Kconfig" +source "drivers/staging/quatech_usb2/Kconfig" + source "drivers/staging/vt6655/Kconfig" source "drivers/staging/vt6656/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index b21503569e9..cb14ff2b257 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_PLAN9AUTH) += p9auth/ obj-$(CONFIG_HECI) += heci/ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ +obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ diff --git a/drivers/staging/quatech_usb2/Kconfig b/drivers/staging/quatech_usb2/Kconfig new file mode 100644 index 00000000000..1494f42f3da --- /dev/null +++ b/drivers/staging/quatech_usb2/Kconfig @@ -0,0 +1,15 @@ +config USB_SERIAL_QUATECH_USB2 + tristate "USB Quatech xSU2-[14]00 USB Serial Driver" + depends on USB_SERIAL + help + Say Y here if you want to use a Quatech USB2.0 to serial adaptor. This + driver supports the SSU2-100, DSU2-100, DSU2-400, QSU2-100, QSU2-400, + ESU2-400 and ESU2-100 USB2.0 to RS232 / 485 / 422 serial adaptors. + + Some hardware has an incorrect product string and announces itself as + ESU-100 (which uses the serqt driver) even though it is an ESU2-100. + Check the label on the bottom of your device. + + To compile this driver as a module, choose M here: the module will be + called quatech_usb2 . + diff --git a/drivers/staging/quatech_usb2/Makefile b/drivers/staging/quatech_usb2/Makefile new file mode 100644 index 00000000000..bcd1f890d16 --- /dev/null +++ b/drivers/staging/quatech_usb2/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2.o diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c new file mode 100644 index 00000000000..3544e700540 --- /dev/null +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -0,0 +1,611 @@ +/* + * Driver for Quatech Inc USB2.0 to serial adaptors. Largely unrelated to the + * serqt_usb driver, based on a re-write of the vendor supplied serqt_usb2 code, + * which is unrelated to the serqt_usb2 in the staging kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; + +/* Version Information */ +#define DRIVER_VERSION "v2.00" +#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc" +#define DRIVER_DESC "Quatech USB 2.0 to Serial Driver" + +/* vendor and device IDs */ +#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ +#define QUATECH_SSU2_100 0xC120 /* RS232 single port */ +#define QUATECH_DSU2_100 0xC140 /* RS232 dual port */ +#define QUATECH_DSU2_400 0xC150 /* RS232/422/485 dual port */ +#define QUATECH_QSU2_100 0xC160 /* RS232 four port */ +#define QUATECH_QSU2_400 0xC170 /* RS232/422/485 four port */ +#define QUATECH_ESU2_100 0xC1A0 /* RS232 eight port */ +#define QUATECH_ESU2_400 0xC180 /* RS232/422/485 eight port */ + +/* magic numbers go here, when we find out which ones are needed */ + +#define QU2BOXPWRON 0x8000 /* magic number to turn FPGA power on */ +#define QU2BOX232 0x40 /* RS232 mode on MEI devices */ +#define QU2BOXSPD9600 0x60 /* set speed to 9600 baud */ +/* directions for USB transfers */ +#define USBD_TRANSFER_DIRECTION_IN 0xc0 +#define USBD_TRANSFER_DIRECTION_OUT 0x40 +/* special Quatech command IDs */ +#define QT_SET_GET_DEVICE 0xc2 +#define QT_OPEN_CLOSE_CHANNEL 0xca +/*#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc +#define QT_SET_ATF 0xcd +#define QT_GET_SET_REGISTER 0xc0*/ +#define QT_GET_SET_UART 0xc1 +/*#define QT_HW_FLOW_CONTROL_MASK 0xc5 +#define QT_SW_FLOW_CONTROL_MASK 0xc6 +#define QT_SW_FLOW_CONTROL_DISABLE 0xc7 +#define QT_BREAK_CONTROL 0xc8 +#define QT_STOP_RECEIVE 0xe0 +#define QT_FLUSH_DEVICE 0xc4*/ +#define QT_GET_SET_QMCR 0xe1 +/* port setting constants */ +#define SERIAL_MCR_DTR 0x01 +#define SERIAL_MCR_RTS 0x02 +#define SERIAL_MCR_LOOP 0x10 + +#define SERIAL_MSR_CTS 0x10 +#define SERIAL_MSR_CD 0x80 +#define SERIAL_MSR_RI 0x40 +#define SERIAL_MSR_DSR 0x20 +#define SERIAL_MSR_MASK 0xf0 + +#define SERIAL_8_DATA 0x03 +#define SERIAL_7_DATA 0x02 +#define SERIAL_6_DATA 0x01 +#define SERIAL_5_DATA 0x00 + +#define SERIAL_ODD_PARITY 0X08 +#define SERIAL_EVEN_PARITY 0X18 +#define SERIAL_TWO_STOPB 0x04 +#define SERIAL_ONE_STOPB 0x00 + +#define MAX_BAUD_RATE 921600 +#define MAX_BAUD_REMAINDER 4608 + +#define SERIAL_LSR_OE 0x02 +#define SERIAL_LSR_PE 0x04 +#define SERIAL_LSR_FE 0x08 +#define SERIAL_LSR_BI 0x10 + + +static struct usb_device_id quausb2_id_table[] = { + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)}, + {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, quausb2_id_table); + +/* custom structures we need go here */ + + +static struct usb_driver quausb2_usb_driver = { + .name = "quatech-usb2-serial", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = quausb2_id_table, + .no_dynamic_id = 1, +}; + +/* structure in which to keep all the messy stuff that this driver needs + * alongside the usb_serial_port structure */ +struct quatech2_port { + int magic; + char active; /* someone has this device open */ + unsigned char *xfer_to_tty_buffer; + wait_queue_head_t wait; + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ + __u8 shadowLCR; /* last LCR value received */ + __u8 shadowMCR; /* last MCR value received */ + __u8 shadowMSR; /* last MSR value received */ + __u8 shadowLSR; /* last LSR value received */ + char open_ports; /* ports open on whole device */ + char RxHolding; + char Rcv_Flush; + char Xmit_Flush; + char closePending; + char fifo_empty_flag; + int xmit_pending_bytes; + int xmit_fifo_room_bytes; + struct semaphore pend_xmit_sem; /* locks this structure */ + spinlock_t lock; +}; + +/* structure which holds line and modem status flags */ +struct qt2_status_data { + __u8 line_status; + __u8 modem_status; +}; + +/* Function prototypes */ +static int qt2_boxpoweron(struct usb_serial *serial); +static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number, + __u8 QMCR_Value); +static int port_paranoia_check(struct usb_serial_port *port, + const char *function); +static int serial_paranoia_check(struct usb_serial *serial, + const char *function); +static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port + *port); +static inline void qt2_set_port_private(struct usb_serial_port *port, + struct quatech2_port *data); +static int qt2_openboxchannel(struct usb_serial *serial, __u16 + Uart_Number, struct qt2_status_data *pDeviceData); +static int qt2_closeboxchannel(struct usb_serial *serial, __u16 + Uart_Number); +static int qt2_conf_uart(struct usb_serial *serial, unsigned short Uart_Number, + unsigned short divisor, unsigned char LCR); +/* implementation functions, roughly in order of use, are here */ +static int qt2_calc_num_ports(struct usb_serial *serial) +{ + int num_ports; + int flag_as_400; + switch (serial->dev->descriptor.idProduct) { + case QUATECH_SSU2_100: + num_ports = 1; + break; + + case QUATECH_DSU2_400: + flag_as_400 = true; + case QUATECH_DSU2_100: + num_ports = 2; + break; + + case QUATECH_QSU2_400: + flag_as_400 = true; + case QUATECH_QSU2_100: + num_ports = 4; + break; + + case QUATECH_ESU2_400: + flag_as_400 = true; + case QUATECH_ESU2_100: + num_ports = 8; + break; + default: + num_ports = 1; + break; + } + return num_ports; +} + +static int qt2_attach(struct usb_serial *serial) +{ + struct usb_serial_port *port; + struct quatech2_port *qt2_port; + int i; + /* stuff for printing endpoint addresses, not needed for + * production */ + struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *iface_desc; + + /* check how many endpoints there are on the device, for + * sanity's sake */ + dbg("%s(): Endpoints: %d bulk in, %d bulk out, %d interrupt in", + __func__, serial->num_bulk_in, + serial->num_bulk_out, serial->num_interrupt_in); + if ((serial->num_bulk_in != 1) || (serial->num_bulk_out != 1)) { + dbg("Device has wrong number of bulk endpoints!"); + return -ENODEV; + } + iface_desc = serial->interface->cur_altsetting; + /* print endpoint addresses so we can check them later + * by hand */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) + { + endpoint = &iface_desc->endpoint[i].desc; + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + dbg("found bulk in at 0x%x", + endpoint->bEndpointAddress); + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) + { + /* we found a bulk out endpoint */ + dbg("found bulk out at 0x%x", + endpoint->bEndpointAddress); + } + } /* end printing endpoint addresses */ + + /* Now setup per port private data, which replaces all the things + * that quatech added to standard kernel structures in their driver */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + qt2_port = kzalloc(sizeof(*qt2_port), GFP_KERNEL); + if (!qt2_port) { + dbg("%s: kmalloc for quatech2_port (%d) failed!.", + __func__, i); + return -ENOMEM; + } + spin_lock_init(&qt2_port->lock); + if (i == 0) + qt2_port->open_ports = 0; /* no ports */ + else + qt2_port->open_ports = -1; /* unused */ + + usb_set_serial_port_data(port, qt2_port); + + } + /* switch on power to the hardware */ + if (qt2_boxpoweron(serial) < 0) { + dbg("qt2_boxpoweron() failed"); + goto startup_error; + } + /* set all ports to RS232 mode */ + for (i = 0; i < serial->num_ports; ++i) { + if (qt2_boxsetQMCR(serial, i, QU2BOX232) < 0) { + dbg("qt2_boxsetQMCR() on port %d failed", + i); + goto startup_error; + } + } + + return 0; + +startup_error: + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + qt2_port = qt2_get_port_private(port); + kfree(qt2_port); + usb_set_serial_port_data(port, NULL); + } + + dbg("Exit fail %s\n", __func__); + return -EIO; +} + +static void qt2_release(struct usb_serial *serial) +{ + struct usb_serial_port *port; + struct quatech2_port *qt_port; + int i; + + dbg("enterting %s", __func__); + + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + if (!port) + continue; + + qt_port = usb_get_serial_port_data(port); + kfree(qt_port); + usb_set_serial_port_data(port, NULL); + } +} +/* This function is called once per serial port on the device. + * The tty_struct and the usb_serial_port belong to this port, + * i.e. there are multiple ones for a multi-port device. + * However the usb_serial_port structure has a back-pointer + * to the parent usb_serial structure which belongs to the device, + * so we can access either the device-wide information or + * any other port's information (because there are also forward + * pointers) via that pointer. + * This is most helpful if the device shares resources (e.g. end + * points) between different ports + */ +int qt2_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) +{ + struct usb_serial *serial; /* device structure */ + struct usb_serial_port *port0; /* first port structure on device */ + struct quatech2_port *port_extra; /* extra data for this port */ + struct quatech2_port *port0_extra; /* extra data for first port */ + struct qt2_status_data ChannelData; + unsigned short default_divisor = QU2BOXSPD9600; + unsigned char default_LCR = SERIAL_8_DATA; + int status; + + if (port_paranoia_check(port, __func__)) + return -ENODEV; + + dbg("%s - port %d\n", __func__, port->number); + + serial = port->serial; /* get the parent device structure */ + if (serial_paranoia_check(serial, __func__)) + return -ENODEV; + port0 = serial->port[0]; /* get the first port's device structure */ + + port_extra = qt2_get_port_private(port); + port0_extra = qt2_get_port_private(port0); + + if (port_extra == NULL || port0_extra == NULL) + return -ENODEV; + + usb_clear_halt(serial->dev, port->write_urb->pipe); + usb_clear_halt(serial->dev, port->read_urb->pipe); + port0_extra->open_ports++; + + /* FIXME: are these needed? Does it even do anything useful? */ + /* get the modem and line status values from the UART */ + status = qt2_openboxchannel(serial, port->number, + &ChannelData); + if (status < 0) { + dbg("qt2_openboxchannel on channel %d failed", + port->number); + return status; + } + port_extra->shadowLSR = ChannelData.line_status & + (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | + SERIAL_LSR_BI); + + port_extra->shadowMSR = ChannelData.modem_status & + (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | + SERIAL_MSR_CD); + + port_extra->fifo_empty_flag = true; + dbg("qt2_openboxchannel on channel %d completed.", + port->number); + + /* Set Baud rate to default and turn off flow control here */ + status = qt2_conf_uart(serial, port->number, default_divisor, + default_LCR); + if (status < 0) { + dbg("qt2_conf_uart() failed on channel %d", + port->number); + return status; + } + dbg("qt2_conf_uart() completed on channel %d", + port->number); + + dbg("port number is %d", port->number); + dbg("serial number is %d", port->serial->minor); + + /* We need to set up endpoints here. We only + * have one pair of endpoints per device, so in fact + * we only need to set up endpoints on the first time + * round, not subsequent ones. + * When we do a write to a port, we will use the same endpoint + * regardless of the port, with a 5-byte header added on to + * tell the box which port it should eventually come out of, + * so the same endpoint information needs to be visible to + * write calls regardless of which port is being written. + * To this end we actually keep the relevant endpoints + * in port 0's structure, because that's always there + * and avoids providing our own duplicate members in some + * user data structure for the same purpose. + * URBs will be allocated and freed dynamically as the are + * used, so are not touched here. + */ + if (port0_extra->open_ports == 1) { + /* this is first port to be opened */ + } + + dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress); + dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress); + dbg("Interrupt endpoint is %d", port->interrupt_in_endpointAddress); + + /* initialize our wait queues */ + init_waitqueue_head(&port_extra->wait); + + /* remember to store port_extra and port0 back again at end !*/ + qt2_set_port_private(port, port_extra); + qt2_set_port_private(serial->port[0], port0_extra); + + return 0; +} + +/* internal, private helper functions for the driver */ + +/* Power up the FPGA in the box to get it working */ +static int qt2_boxpoweron(struct usb_serial *serial) +{ + int result; + __u8 Direcion; + unsigned int pipe; + Direcion = USBD_TRANSFER_DIRECTION_OUT; + pipe = usb_rcvctrlpipe(serial->dev, 0); + result = usb_control_msg(serial->dev, pipe, QT_SET_GET_DEVICE, + Direcion, QU2BOXPWRON, 0x00, NULL, 0x00, + 5000); + return result; +} + +/* + * qt2_boxsetQMCR Issue a QT_GET_SET_QMCR vendor-spcific request on the + * default control pipe. If successful return the number of bytes written, + * otherwise return a negative error number of the problem. + */ +static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number, + __u8 QMCR_Value) +{ + int result; + __u16 PortSettings; + + PortSettings = (__u16)(QMCR_Value); + + dbg("%s(): Port = %d, PortSettings = 0x%x", __func__, + Uart_Number, PortSettings); + + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + QT_GET_SET_QMCR, 0x40, PortSettings, + (__u16)Uart_Number, NULL, 0, 5000); + return result; +} + +static int port_paranoia_check(struct usb_serial_port *port, + const char *function) +{ + if (!port) { + dbg("%s - port == NULL", function); + return -1; + } + if (!port->serial) { + dbg("%s - port->serial == NULL\n", function); + return -1; + } + return 0; +} + +static int serial_paranoia_check(struct usb_serial *serial, + const char *function) +{ + if (!serial) { + dbg("%s - serial == NULL\n", function); + return -1; + } + + if (!serial->type) { + dbg("%s - serial->type == NULL!", function); + return -1; + } + + return 0; +} + +static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port + *port) +{ + return (struct quatech2_port *)usb_get_serial_port_data(port); +} + +static inline void qt2_set_port_private(struct usb_serial_port *port, + struct quatech2_port *data) +{ + usb_set_serial_port_data(port, (void *)data); +} + +static int qt2_openboxchannel(struct usb_serial *serial, __u16 + Uart_Number, struct qt2_status_data *status) +{ + int result; + __u16 length; + __u8 Direcion; + unsigned int pipe; + length = sizeof(struct qt2_status_data); + Direcion = USBD_TRANSFER_DIRECTION_IN; + pipe = usb_rcvctrlpipe(serial->dev, 0); + result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL, + Direcion, 0x00, Uart_Number, status, length, 5000); + return result; +} +static int qt2_closeboxchannel(struct usb_serial *serial, __u16 Uart_Number) +{ + int result; + __u8 direcion; + unsigned int pipe; + direcion = USBD_TRANSFER_DIRECTION_OUT; + pipe = usb_sndctrlpipe(serial->dev, 0); + result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL, + direcion, 0, Uart_Number, NULL, 0, 5000); + return result; +} + +/* qt2_conf_uart Issue a SET_UART vendor-spcific request on the default + * control pipe. If successful sets baud rate divisor and LCR value + */ +static int qt2_conf_uart(struct usb_serial *serial, unsigned short Uart_Number, + unsigned short divisor, unsigned char LCR) +{ + int result; + unsigned short UartNumandLCR; + + UartNumandLCR = (LCR << 8) + Uart_Number; + + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + QT_GET_SET_UART, 0x40, divisor, UartNumandLCR, + NULL, 0, 300); + return result; +} + +/* + * last things in file: stuff to register this driver into the generic + * USB serial framework. + */ + +static struct usb_serial_driver quatech2_device = { + .driver = { + .owner = THIS_MODULE, + .name = "quatech_usb2", + }, + .description = DRIVER_DESC, + .usb_driver = &quausb2_usb_driver, + .id_table = quausb2_id_table, + .num_ports = 8, + .open = qt2_open, + /*.close = qt_close, + .write = qt_write, + .write_room = qt_write_room, + .chars_in_buffer = qt_chars_in_buffer, + .throttle = qt_throttle, + .unthrottle = qt_unthrottle,*/ + .calc_num_ports = qt2_calc_num_ports, + /*.ioctl = qt_ioctl, + .set_termios = qt_set_termios, + .break_ctl = qt_break, + .tiocmget = qt_tiocmget, + .tiocmset = qt_tiocmset,*/ + .attach = qt2_attach, + .release = qt2_release, +}; + +static int __init quausb2_usb_init(void) +{ + int retval; + + dbg("%s\n", __func__); + + /* register with usb-serial */ + retval = usb_serial_register(&quatech2_device); + + if (retval) + goto failed_usb_serial_register; + + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); + + /* register with usb */ + + retval = usb_register(&quausb2_usb_driver); + if (retval == 0) + return 0; + + /* if we're here, usb_register() failed */ + usb_serial_deregister(&quatech2_device); +failed_usb_serial_register: + return retval; +} + + + +static void __exit quausb2_usb_exit(void) +{ + usb_deregister(&quausb2_usb_driver); + usb_serial_deregister(&quatech2_device); +} + +module_init(quausb2_usb_init); +module_exit(quausb2_usb_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); -- cgit v1.2.3 From 578f2938a43f83988f6edab86cff487889b4ef58 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 17 Jul 2009 14:55:53 +0200 Subject: Staging: HTC Dream: Makefile glue This provides Makefile/Kconfig glue for HTC Dream staging parts. Signed-off-by: Pavel Machek Cc: Brian Swetland Cc: Iliyan Malchev Cc: San Mehat Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 4 ++++ drivers/staging/Makefile | 2 ++ 2 files changed, 6 insertions(+) (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 549ae79199e..c1a0ca4c96f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -131,6 +131,10 @@ source "drivers/staging/cpc-usb/Kconfig" source "drivers/staging/pata_rdc/Kconfig" +source "drivers/staging/dream/smd/Kconfig" + +source "drivers/staging/dream/camera/Kconfig" + source "drivers/staging/udlfb/Kconfig" endif # !STAGING_EXCLUDE_BUILD diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index cb14ff2b257..aa65ed205bb 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -48,3 +48,5 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ +obj-$(CONFIG_MSM_ADSP) += dream/qdsp5/ dream/smd/ +obj-$(CONFIG_MSM_CAMERA) += dream/camera/ -- cgit v1.2.3 From c4ca0e9e6de92f46271599db90f4ab006c133441 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Jul 2009 16:04:02 -0700 Subject: Staging: hv: add the Hyper-V virtual bus to the build Add the Hyper-V virtual bus to the kernel build system. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/hv/Kconfig | 8 ++++++++ drivers/staging/hv/Makefile | 3 +++ 4 files changed, 14 insertions(+) create mode 100644 drivers/staging/hv/Kconfig create mode 100644 drivers/staging/hv/Makefile (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c1a0ca4c96f..34aa21e1fb3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -137,5 +137,7 @@ source "drivers/staging/dream/camera/Kconfig" source "drivers/staging/udlfb/Kconfig" +source "drivers/staging/hv/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index aa65ed205bb..bc84a0e0a46 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,3 +50,4 @@ obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_MSM_ADSP) += dream/qdsp5/ dream/smd/ obj-$(CONFIG_MSM_CAMERA) += dream/camera/ +obj-$(CONFIG_HYPERV) += hv/ diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig new file mode 100644 index 00000000000..40d922bfab2 --- /dev/null +++ b/drivers/staging/hv/Kconfig @@ -0,0 +1,8 @@ +config HYPERV + tristate "Microsoft Hyper-V client drivers" + depends on X86 + default n + help + Select this option to run Linux as a Hyper-V client operating + system. + diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile new file mode 100644 index 00000000000..9908360345b --- /dev/null +++ b/drivers/staging/hv/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_HYPERV) += hv_vmbus.o + +hv_vmbus-objs := vmbus_drv.o osd.o Sources.o -- cgit v1.2.3 From 347a799cef17e66bd532fca4e55a5f5a2f9ff36c Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 8 Aug 2009 14:27:02 +0200 Subject: Staging: Dream: separate Kconfig/Makefile into subdirectory Separate Kconfig/Makefile glue from dream into subdirectory. I plan to add few more drivers, and changing staging/Makefile each time sounds like inviting conflicts. Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 6 ++---- drivers/staging/Makefile | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 34aa21e1fb3..aec18bcd6e5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -99,6 +99,8 @@ source "drivers/staging/epl/Kconfig" source "drivers/staging/android/Kconfig" +source "drivers/staging/dream/Kconfig" + source "drivers/staging/dst/Kconfig" source "drivers/staging/pohmelfs/Kconfig" @@ -131,10 +133,6 @@ source "drivers/staging/cpc-usb/Kconfig" source "drivers/staging/pata_rdc/Kconfig" -source "drivers/staging/dream/smd/Kconfig" - -source "drivers/staging/dream/camera/Kconfig" - source "drivers/staging/udlfb/Kconfig" source "drivers/staging/hv/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index bc84a0e0a46..f4f7666bc4e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_EPL) += epl/ obj-$(CONFIG_ANDROID) += android/ +obj-$(CONFIG_ANDROID) += dream/ obj-$(CONFIG_DST) += dst/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_STLC45XX) += stlc45xx/ @@ -48,6 +49,4 @@ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ -obj-$(CONFIG_MSM_ADSP) += dream/qdsp5/ dream/smd/ -obj-$(CONFIG_MSM_CAMERA) += dream/camera/ obj-$(CONFIG_HYPERV) += hv/ -- cgit v1.2.3 From a17a75e2666f7175baac838bc4b6d11324dca3ef Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Fri, 31 Jul 2009 09:28:17 +0100 Subject: Staging: VME Framework for the Linux Kernel This framework aims to colelese, extend and improve the VME Linux drivers found at vmelinux.org, universe2.sourceforge.net and openfmi.net/frs/?group_id=144. The last 2 drivers appear to be forks of the original code found at vmelinux.org though have extended the codebase. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/vme/Kconfig | 17 + drivers/staging/vme/Makefile | 7 + drivers/staging/vme/vme.c | 1371 ++++++++++++++++++++++++++++++++++++++ drivers/staging/vme/vme.h | 153 +++++ drivers/staging/vme/vme_bridge.h | 249 +++++++ 7 files changed, 1800 insertions(+) create mode 100644 drivers/staging/vme/Kconfig create mode 100644 drivers/staging/vme/Makefile create mode 100644 drivers/staging/vme/vme.c create mode 100644 drivers/staging/vme/vme.h create mode 100644 drivers/staging/vme/vme_bridge.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index aec18bcd6e5..58274ca5e63 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -137,5 +137,7 @@ source "drivers/staging/udlfb/Kconfig" source "drivers/staging/hv/Kconfig" +source "drivers/staging/vme/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f4f7666bc4e..42c6776ed5f 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,3 +50,4 @@ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ +obj-$(CONFIG_VME) += vme/ diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig new file mode 100644 index 00000000000..ee4c5889562 --- /dev/null +++ b/drivers/staging/vme/Kconfig @@ -0,0 +1,17 @@ +# +# VME configuration. +# + +menuconfig VME + tristate "VME bridge support" + depends on PCI + ---help--- + If you say Y here you get support for the VME bridge Framework. + +if VME + +#source "drivers/staging/vme/bridges/Kconfig" +# +#source "drivers/staging/vme/devices/Kconfig" + +endif # VME diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile new file mode 100644 index 00000000000..18775003405 --- /dev/null +++ b/drivers/staging/vme/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the VME bridge device drivers. +# +obj-$(CONFIG_VME) += vme.o + +#obj-y += bridges/ +#obj-y += devices/ diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c new file mode 100644 index 00000000000..8ee11925b19 --- /dev/null +++ b/drivers/staging/vme/vme.c @@ -0,0 +1,1371 @@ +/* + * VME Bridge Framework + * + * Author: Martyn Welch + * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * + * Based on work by Tom Armistead and Ajit Prem + * Copyright 2004 Motorola Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vme.h" +#include "vme_bridge.h" + +/* Bitmask and semaphore to keep track of bridge numbers */ +static unsigned int vme_bus_numbers; +DECLARE_MUTEX(vme_bus_num_sem); + +static void __exit vme_exit (void); +static int __init vme_init (void); + + +/* + * Find the bridge resource associated with a specific device resource + */ +static struct vme_bridge *dev_to_bridge(struct device *dev) +{ + return dev->platform_data; +} + +/* + * Find the bridge that the resource is associated with. + */ +static struct vme_bridge *find_bridge(struct vme_resource *resource) +{ + /* Get list to search */ + switch (resource->type) { + case VME_MASTER: + return list_entry(resource->entry, struct vme_master_resource, + list)->parent; + break; + case VME_SLAVE: + return list_entry(resource->entry, struct vme_slave_resource, + list)->parent; + break; + case VME_DMA: + return list_entry(resource->entry, struct vme_dma_resource, + list)->parent; + break; + default: + printk(KERN_ERR "Unknown resource type\n"); + return NULL; + break; + } +} + +/* + * Allocate a contiguous block of memory for use by the driver. This is used to + * create the buffers for the slave windows. + * + * XXX VME bridges could be available on buses other than PCI. At the momment + * this framework only supports PCI devices. + */ +void * vme_alloc_consistent(struct vme_resource *resource, size_t size, + dma_addr_t *dma) +{ + struct vme_bridge *bridge; + struct pci_dev *pdev; + + if(resource == NULL) { + printk("No resource\n"); + return NULL; + } + + bridge = find_bridge(resource); + if(bridge == NULL) { + printk("Can't find bridge\n"); + return NULL; + } + + /* Find pci_dev container of dev */ + if (bridge->parent == NULL) { + printk("Dev entry NULL\n"); + return NULL; + } + pdev = container_of(bridge->parent, struct pci_dev, dev); + + return pci_alloc_consistent(pdev, size, dma); +} +EXPORT_SYMBOL(vme_alloc_consistent); + +/* + * Free previously allocated contiguous block of memory. + * + * XXX VME bridges could be available on buses other than PCI. At the momment + * this framework only supports PCI devices. + */ +void vme_free_consistent(struct vme_resource *resource, size_t size, + void *vaddr, dma_addr_t dma) +{ + struct vme_bridge *bridge; + struct pci_dev *pdev; + + if(resource == NULL) { + printk("No resource\n"); + return; + } + + bridge = find_bridge(resource); + if(bridge == NULL) { + printk("Can't find bridge\n"); + return; + } + + /* Find pci_dev container of dev */ + pdev = container_of(bridge->parent, struct pci_dev, dev); + + pci_free_consistent(pdev, size, vaddr, dma); +} +EXPORT_SYMBOL(vme_free_consistent); + +size_t vme_get_size(struct vme_resource *resource) +{ + int enabled, retval; + unsigned long long base, size; + dma_addr_t buf_base; + vme_address_t aspace; + vme_cycle_t cycle; + vme_width_t dwidth; + + switch (resource->type) { + case VME_MASTER: + retval = vme_master_get(resource, &enabled, &base, &size, + &aspace, &cycle, &dwidth); + + return size; + break; + case VME_SLAVE: + retval = vme_slave_get(resource, &enabled, &base, &size, + &buf_base, &aspace, &cycle); + + return size; + break; + case VME_DMA: + return 0; + break; + default: + printk(KERN_ERR "Unknown resource type\n"); + return 0; + break; + } +} +EXPORT_SYMBOL(vme_get_size); + +static int vme_check_window(vme_address_t aspace, unsigned long long vme_base, + unsigned long long size) +{ + int retval = 0; + + switch (aspace) { + case VME_A16: + if (((vme_base + size) > VME_A16_MAX) || + (vme_base > VME_A16_MAX)) + retval = -EFAULT; + break; + case VME_A24: + if (((vme_base + size) > VME_A24_MAX) || + (vme_base > VME_A24_MAX)) + retval = -EFAULT; + break; + case VME_A32: + if (((vme_base + size) > VME_A32_MAX) || + (vme_base > VME_A32_MAX)) + retval = -EFAULT; + break; + case VME_A64: + /* + * Any value held in an unsigned long long can be used as the + * base + */ + break; + case VME_CRCSR: + if (((vme_base + size) > VME_CRCSR_MAX) || + (vme_base > VME_CRCSR_MAX)) + retval = -EFAULT; + break; + case VME_USER1: + case VME_USER2: + case VME_USER3: + case VME_USER4: + /* User Defined */ + break; + default: + printk("Invalid address space\n"); + retval = -EINVAL; + break; + } + + return retval; +} + +/* + * Request a slave image with specific attributes, return some unique + * identifier. + */ +struct vme_resource * vme_slave_request(struct device *dev, + vme_address_t address, vme_cycle_t cycle) +{ + struct vme_bridge *bridge; + struct list_head *slave_pos = NULL; + struct vme_slave_resource *allocated_image = NULL; + struct vme_slave_resource *slave_image = NULL; + struct vme_resource *resource = NULL; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through slave resources */ + list_for_each(slave_pos, &(bridge->slave_resources)) { + slave_image = list_entry(slave_pos, + struct vme_slave_resource, list); + + if (slave_image == NULL) { + printk("Registered NULL Slave resource\n"); + continue; + } + + /* Find an unlocked and compatible image */ + down(&(slave_image->sem)); + if(((slave_image->address_attr & address) == address) && + ((slave_image->cycle_attr & cycle) == cycle) && + (slave_image->locked == 0)) { + + slave_image->locked = 1; + up(&(slave_image->sem)); + allocated_image = slave_image; + break; + } + up(&(slave_image->sem)); + } + + /* No free image */ + if (allocated_image == NULL) + goto err_image; + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_WARNING "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_SLAVE; + resource->entry = &(allocated_image->list); + + return resource; + +err_alloc: + /* Unlock image */ + down(&(slave_image->sem)); + slave_image->locked = 0; + up(&(slave_image->sem)); +err_image: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_slave_request); + +int vme_slave_set (struct vme_resource *resource, int enabled, + unsigned long long vme_base, unsigned long long size, + dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_slave_resource *image; + int retval; + + if (resource->type != VME_SLAVE) { + printk("Not a slave resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_slave_resource, list); + + if (bridge->slave_set == NULL) { + printk("Function not supported\n"); + return -ENOSYS; + } + + if(!(((image->address_attr & aspace) == aspace) && + ((image->cycle_attr & cycle) == cycle))) { + printk("Invalid attributes\n"); + return -EINVAL; + } + + retval = vme_check_window(aspace, vme_base, size); + if(retval) + return retval; + + return bridge->slave_set(image, enabled, vme_base, size, buf_base, + aspace, cycle); +} +EXPORT_SYMBOL(vme_slave_set); + +int vme_slave_get (struct vme_resource *resource, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_slave_resource *image; + + if (resource->type != VME_SLAVE) { + printk("Not a slave resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_slave_resource, list); + + if (bridge->slave_set == NULL) { + printk("vme_slave_get not supported\n"); + return -EINVAL; + } + + return bridge->slave_get(image, enabled, vme_base, size, buf_base, + aspace, cycle); +} +EXPORT_SYMBOL(vme_slave_get); + +void vme_slave_free(struct vme_resource *resource) +{ + struct vme_slave_resource *slave_image; + + if (resource->type != VME_SLAVE) { + printk("Not a slave resource\n"); + return; + } + + slave_image = list_entry(resource->entry, struct vme_slave_resource, + list); + if (slave_image == NULL) { + printk("Can't find slave resource\n"); + return; + } + + /* Unlock image */ + down(&(slave_image->sem)); + if (slave_image->locked == 0) + printk(KERN_ERR "Image is already free\n"); + + slave_image->locked = 0; + up(&(slave_image->sem)); + + /* Free up resource memory */ + kfree(resource); +} +EXPORT_SYMBOL(vme_slave_free); + +/* + * Request a master image with specific attributes, return some unique + * identifier. + */ +struct vme_resource * vme_master_request(struct device *dev, + vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth) +{ + struct vme_bridge *bridge; + struct list_head *master_pos = NULL; + struct vme_master_resource *allocated_image = NULL; + struct vme_master_resource *master_image = NULL; + struct vme_resource *resource = NULL; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through master resources */ + list_for_each(master_pos, &(bridge->master_resources)) { + master_image = list_entry(master_pos, + struct vme_master_resource, list); + + if (master_image == NULL) { + printk(KERN_WARNING "Registered NULL master resource\n"); + continue; + } + + /* Find an unlocked and compatible image */ + spin_lock(&(master_image->lock)); + if(((master_image->address_attr & address) == address) && + ((master_image->cycle_attr & cycle) == cycle) && + ((master_image->width_attr & dwidth) == dwidth) && + (master_image->locked == 0)) { + + master_image->locked = 1; + spin_unlock(&(master_image->lock)); + allocated_image = master_image; + break; + } + spin_unlock(&(master_image->lock)); + } + + /* Check to see if we found a resource */ + if (allocated_image == NULL) { + printk(KERN_ERR "Can't find a suitable resource\n"); + goto err_image; + } + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_ERR "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_MASTER; + resource->entry = &(allocated_image->list); + + return resource; + + kfree(resource); +err_alloc: + /* Unlock image */ + spin_lock(&(master_image->lock)); + master_image->locked = 0; + spin_unlock(&(master_image->lock)); +err_image: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_master_request); + +int vme_master_set (struct vme_resource *resource, int enabled, + unsigned long long vme_base, unsigned long long size, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + int retval; + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + if (bridge->master_set == NULL) { + printk("vme_master_set not supported\n"); + return -EINVAL; + } + + if(!(((image->address_attr & aspace) == aspace) && + ((image->cycle_attr & cycle) == cycle) && + ((image->width_attr & dwidth) == dwidth))) { + printk("Invalid attributes\n"); + return -EINVAL; + } + + retval = vme_check_window(aspace, vme_base, size); + if(retval) + return retval; + + return bridge->master_set(image, enabled, vme_base, size, aspace, + cycle, dwidth); +} +EXPORT_SYMBOL(vme_master_set); + +int vme_master_get (struct vme_resource *resource, int *enabled, + unsigned long long *vme_base, unsigned long long *size, + vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + if (bridge->master_set == NULL) { + printk("vme_master_set not supported\n"); + return -EINVAL; + } + + return bridge->master_get(image, enabled, vme_base, size, aspace, + cycle, dwidth); +} +EXPORT_SYMBOL(vme_master_get); + +/* + * Read data out of VME space into a buffer. + */ +ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count, + loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + size_t length; + + if (bridge->master_read == NULL) { + printk("Reading from resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + length = vme_get_size(resource); + + if (offset > length) { + printk("Invalid Offset\n"); + return -EFAULT; + } + + if ((offset + count) > length) + count = length - offset; + + return bridge->master_read(image, buf, count, offset); + +} +EXPORT_SYMBOL(vme_master_read); + +/* + * Write data out to VME space from a buffer. + */ +ssize_t vme_master_write (struct vme_resource *resource, void *buf, + size_t count, loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + size_t length; + + if (bridge->master_write == NULL) { + printk("Writing to resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + length = vme_get_size(resource); + + if (offset > length) { + printk("Invalid Offset\n"); + return -EFAULT; + } + + if ((offset + count) > length) + count = length - offset; + + return bridge->master_write(image, buf, count, offset); +} +EXPORT_SYMBOL(vme_master_write); + +/* + * Perform RMW cycle to provided location. + */ +unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask, + unsigned int compare, unsigned int swap, loff_t offset) +{ + struct vme_bridge *bridge = find_bridge(resource); + struct vme_master_resource *image; + + if (bridge->master_rmw == NULL) { + printk("Writing to resource not supported\n"); + return -EINVAL; + } + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return -EINVAL; + } + + image = list_entry(resource->entry, struct vme_master_resource, list); + + return bridge->master_rmw(image, mask, compare, swap, offset); +} +EXPORT_SYMBOL(vme_master_rmw); + +void vme_master_free(struct vme_resource *resource) +{ + struct vme_master_resource *master_image; + + if (resource->type != VME_MASTER) { + printk("Not a master resource\n"); + return; + } + + master_image = list_entry(resource->entry, struct vme_master_resource, + list); + if (master_image == NULL) { + printk("Can't find master resource\n"); + return; + } + + /* Unlock image */ + spin_lock(&(master_image->lock)); + if (master_image->locked == 0) + printk(KERN_ERR "Image is already free\n"); + + master_image->locked = 0; + spin_unlock(&(master_image->lock)); + + /* Free up resource memory */ + kfree(resource); +} +EXPORT_SYMBOL(vme_master_free); + +/* + * Request a DMA controller with specific attributes, return some unique + * identifier. + */ +struct vme_resource *vme_request_dma(struct device *dev) +{ + struct vme_bridge *bridge; + struct list_head *dma_pos = NULL; + struct vme_dma_resource *allocated_ctrlr = NULL; + struct vme_dma_resource *dma_ctrlr = NULL; + struct vme_resource *resource = NULL; + + /* XXX Not checking resource attributes */ + printk(KERN_ERR "No VME resource Attribute tests done\n"); + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + goto err_bus; + } + + /* Loop through DMA resources */ + list_for_each(dma_pos, &(bridge->dma_resources)) { + dma_ctrlr = list_entry(dma_pos, + struct vme_dma_resource, list); + + if (dma_ctrlr == NULL) { + printk("Registered NULL DMA resource\n"); + continue; + } + + /* Find an unlocked controller */ + down(&(dma_ctrlr->sem)); + if(dma_ctrlr->locked == 0) { + dma_ctrlr->locked = 1; + up(&(dma_ctrlr->sem)); + allocated_ctrlr = dma_ctrlr; + break; + } + up(&(dma_ctrlr->sem)); + } + + /* Check to see if we found a resource */ + if (allocated_ctrlr == NULL) + goto err_ctrlr; + + resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); + if (resource == NULL) { + printk(KERN_WARNING "Unable to allocate resource structure\n"); + goto err_alloc; + } + resource->type = VME_DMA; + resource->entry = &(allocated_ctrlr->list); + + return resource; + +err_alloc: + /* Unlock image */ + down(&(dma_ctrlr->sem)); + dma_ctrlr->locked = 0; + up(&(dma_ctrlr->sem)); +err_ctrlr: +err_bus: + return NULL; +} +EXPORT_SYMBOL(vme_request_dma); + +/* + * Start new list + */ +struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) +{ + struct vme_dma_resource *ctrlr; + struct vme_dma_list *dma_list; + + if (resource->type != VME_DMA) { + printk("Not a DMA resource\n"); + return NULL; + } + + ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); + + dma_list = (struct vme_dma_list *)kmalloc( + sizeof(struct vme_dma_list), GFP_KERNEL); + if(dma_list == NULL) { + printk("Unable to allocate memory for new dma list\n"); + return NULL; + } + INIT_LIST_HEAD(&(dma_list->entries)); + dma_list->parent = ctrlr; + init_MUTEX(&(dma_list->sem)); + + return dma_list; +} +EXPORT_SYMBOL(vme_new_dma_list); + +/* + * Create "Pattern" type attributes + */ +struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, + vme_pattern_t type) +{ + struct vme_dma_attr *attributes; + struct vme_dma_pattern *pattern_attr; + + attributes = (struct vme_dma_attr *)kmalloc( + sizeof(struct vme_dma_attr), GFP_KERNEL); + if(attributes == NULL) { + printk("Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + pattern_attr = (struct vme_dma_pattern *)kmalloc( + sizeof(struct vme_dma_pattern), GFP_KERNEL); + if(pattern_attr == NULL) { + printk("Unable to allocate memory for pattern attributes\n"); + goto err_pat; + } + + attributes->type = VME_DMA_PATTERN; + attributes->private = (void *)pattern_attr; + + pattern_attr->pattern = pattern; + pattern_attr->type = type; + + return attributes; + + kfree(pattern_attr); +err_pat: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_pattern_attribute); + +/* + * Create "PCI" type attributes + */ +struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) +{ + struct vme_dma_attr *attributes; + struct vme_dma_pci *pci_attr; + + /* XXX Run some sanity checks here */ + + attributes = (struct vme_dma_attr *)kmalloc( + sizeof(struct vme_dma_attr), GFP_KERNEL); + if(attributes == NULL) { + printk("Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci), + GFP_KERNEL); + if(pci_attr == NULL) { + printk("Unable to allocate memory for pci attributes\n"); + goto err_pci; + } + + + + attributes->type = VME_DMA_PCI; + attributes->private = (void *)pci_attr; + + pci_attr->address = address; + + return attributes; + + kfree(pci_attr); +err_pci: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_pci_attribute); + +/* + * Create "VME" type attributes + */ +struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) +{ + struct vme_dma_attr *attributes; + struct vme_dma_vme *vme_attr; + + /* XXX Run some sanity checks here */ + + attributes = (struct vme_dma_attr *)kmalloc( + sizeof(struct vme_dma_attr), GFP_KERNEL); + if(attributes == NULL) { + printk("Unable to allocate memory for attributes structure\n"); + goto err_attr; + } + + vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme), + GFP_KERNEL); + if(vme_attr == NULL) { + printk("Unable to allocate memory for vme attributes\n"); + goto err_vme; + } + + attributes->type = VME_DMA_VME; + attributes->private = (void *)vme_attr; + + vme_attr->address = address; + vme_attr->aspace = aspace; + vme_attr->cycle = cycle; + vme_attr->dwidth = dwidth; + + return attributes; + + kfree(vme_attr); +err_vme: + kfree(attributes); +err_attr: + return NULL; +} +EXPORT_SYMBOL(vme_dma_vme_attribute); + +/* + * Free attribute + */ +void vme_dma_free_attribute(struct vme_dma_attr *attributes) +{ + kfree(attributes->private); + kfree(attributes); +} +EXPORT_SYMBOL(vme_dma_free_attribute); + +int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, + struct vme_dma_attr *dest, size_t count) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_add == NULL) { + printk("Link List DMA generation not supported\n"); + return -EINVAL; + } + + if (down_trylock(&(list->sem))) { + printk("Link List already submitted\n"); + return -EINVAL; + } + + retval = bridge->dma_list_add(list, src, dest, count); + + up(&(list->sem)); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_add); + +int vme_dma_list_exec(struct vme_dma_list *list) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_exec == NULL) { + printk("Link List DMA execution not supported\n"); + return -EINVAL; + } + + down(&(list->sem)); + + retval = bridge->dma_list_exec(list); + + up(&(list->sem)); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_exec); + +int vme_dma_list_free(struct vme_dma_list *list) +{ + struct vme_bridge *bridge = list->parent->parent; + int retval; + + if (bridge->dma_list_empty == NULL) { + printk("Emptying of Link Lists not supported\n"); + return -EINVAL; + } + + if (down_trylock(&(list->sem))) { + printk("Link List in use\n"); + return -EINVAL; + } + + /* + * Empty out all of the entries from the dma list. We need to go to the + * low level driver as dma entries are driver specific. + */ + retval = bridge->dma_list_empty(list); + if (retval) { + printk("Unable to empty link-list entries\n"); + up(&(list->sem)); + return retval; + } + up(&(list->sem)); + kfree(list); + + return retval; +} +EXPORT_SYMBOL(vme_dma_list_free); + +int vme_dma_free(struct vme_resource *resource) +{ + struct vme_dma_resource *ctrlr; + + if (resource->type != VME_DMA) { + printk("Not a DMA resource\n"); + return -EINVAL; + } + + ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); + + if (down_trylock(&(ctrlr->sem))) { + printk("Resource busy, can't free\n"); + return -EBUSY; + } + + if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) { + printk("Resource still processing transfers\n"); + up(&(ctrlr->sem)); + return -EBUSY; + } + + ctrlr->locked = 0; + + up(&(ctrlr->sem)); + + return 0; +} +EXPORT_SYMBOL(vme_dma_free); + +int vme_request_irq(struct device *dev, int level, int statid, + void (*callback)(int level, int vector, void *priv_data), + void *priv_data) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if((level < 1) || (level > 7)) { + printk(KERN_WARNING "Invalid interrupt level\n"); + return -EINVAL; + } + + if (bridge->request_irq == NULL) { + printk("Registering interrupts not supported\n"); + return -EINVAL; + } + + return bridge->request_irq(level, statid, callback, priv_data); +} +EXPORT_SYMBOL(vme_request_irq); + +void vme_free_irq(struct device *dev, int level, int statid) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return; + } + + if((level < 1) || (level > 7)) { + printk(KERN_WARNING "Invalid interrupt level\n"); + return; + } + + if (bridge->free_irq == NULL) { + printk("Freeing interrupts not supported\n"); + return; + } + + bridge->free_irq(level, statid); +} +EXPORT_SYMBOL(vme_free_irq); + +int vme_generate_irq(struct device *dev, int level, int statid) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if((level < 1) || (level > 7)) { + printk(KERN_WARNING "Invalid interrupt level\n"); + return -EINVAL; + } + + if (bridge->generate_irq == NULL) { + printk("Interrupt generation not supported\n"); + return -EINVAL; + } + + return bridge->generate_irq(level, statid); +} +EXPORT_SYMBOL(vme_generate_irq); + +int vme_lm_set(struct device *dev, unsigned long long lm_base, vme_address_t aspace, + vme_cycle_t cycle) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->lm_set == NULL) { + printk("vme_lm_set not supported\n"); + return -EINVAL; + } + + return bridge->lm_set(lm_base, aspace, cycle); +} +EXPORT_SYMBOL(vme_lm_set); + +int vme_lm_get(struct device *dev, unsigned long long *lm_base, vme_address_t *aspace, + vme_cycle_t *cycle) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->lm_get == NULL) { + printk("vme_lm_get not supported\n"); + return -EINVAL; + } + + return bridge->lm_get(lm_base, aspace, cycle); +} +EXPORT_SYMBOL(vme_lm_get); + +int vme_lm_attach(struct device *dev, int monitor, void (*callback)(int)) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->lm_attach == NULL) { + printk("vme_lm_attach not supported\n"); + return -EINVAL; + } + + return bridge->lm_attach(monitor, callback); +} +EXPORT_SYMBOL(vme_lm_attach); + +int vme_lm_detach(struct device *dev, int monitor) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(dev); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->lm_detach == NULL) { + printk("vme_lm_detach not supported\n"); + return -EINVAL; + } + + return bridge->lm_detach(monitor); +} +EXPORT_SYMBOL(vme_lm_detach); + +int vme_slot_get(struct device *bus) +{ + struct vme_bridge *bridge; + + bridge = dev_to_bridge(bus); + if (bridge == NULL) { + printk(KERN_ERR "Can't find VME bus\n"); + return -EINVAL; + } + + if (bridge->slot_get == NULL) { + printk("vme_slot_get not supported\n"); + return -EINVAL; + } + + return bridge->slot_get(); +} +EXPORT_SYMBOL(vme_slot_get); + + +/* - Bridge Registration --------------------------------------------------- */ + +static int vme_alloc_bus_num(void) +{ + int i; + + down(&vme_bus_num_sem); + for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { + if (((vme_bus_numbers >> i) & 0x1) == 0) { + vme_bus_numbers |= (0x1 << i); + break; + } + } + up(&vme_bus_num_sem); + + return i; +} + +static void vme_free_bus_num(int bus) +{ + down(&vme_bus_num_sem); + vme_bus_numbers |= ~(0x1 << bus); + up(&vme_bus_num_sem); +} + +int vme_register_bridge (struct vme_bridge *bridge) +{ + struct device *dev; + int retval; + int i; + + bridge->num = vme_alloc_bus_num(); + + /* This creates 32 vme "slot" devices. This equates to a slot for each + * ID available in a system conforming to the ANSI/VITA 1-1994 + * specification. + */ + for (i = 0; i < VME_SLOTS_MAX; i++) { + dev = &(bridge->dev[i]); + memset(dev, 0, sizeof(struct device)); + + dev->parent = bridge->parent; + dev->bus = &(vme_bus_type); + /* + * We save a pointer to the bridge in platform_data so that we + * can get to it later. We keep driver_data for use by the + * driver that binds against the slot + */ + dev->platform_data = bridge; + dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1); + + retval = device_register(dev); + if(retval) + goto err_reg; + } + + return retval; + + i = VME_SLOTS_MAX; +err_reg: + while (i > -1) { + dev = &(bridge->dev[i]); + device_unregister(dev); + } + vme_free_bus_num(bridge->num); + return retval; +} +EXPORT_SYMBOL(vme_register_bridge); + +void vme_unregister_bridge (struct vme_bridge *bridge) +{ + int i; + struct device *dev; + + + for (i = 0; i < VME_SLOTS_MAX; i++) { + dev = &(bridge->dev[i]); + device_unregister(dev); + } + vme_free_bus_num(bridge->num); +} +EXPORT_SYMBOL(vme_unregister_bridge); + + +/* - Driver Registration --------------------------------------------------- */ + +int vme_register_driver (struct vme_driver *drv) +{ + drv->driver.name = drv->name; + drv->driver.bus = &vme_bus_type; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL(vme_register_driver); + +void vme_unregister_driver (struct vme_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(vme_unregister_driver); + +/* - Bus Registration ------------------------------------------------------ */ + +int vme_calc_slot(struct device *dev) +{ + struct vme_bridge *bridge; + int num; + + bridge = dev_to_bridge(dev); + + /* Determine slot number */ + num = 0; + while(num < VME_SLOTS_MAX) { + if(&(bridge->dev[num]) == dev) { + break; + } + num++; + } + if (num == VME_SLOTS_MAX) { + dev_err(dev, "Failed to identify slot\n"); + num = 0; + goto err_dev; + } + num++; + +err_dev: + return num; +} + +static struct vme_driver *dev_to_vme_driver(struct device *dev) +{ + if(dev->driver == NULL) + printk("Bugger dev->driver is NULL\n"); + + return container_of(dev->driver, struct vme_driver, driver); +} + +static int vme_bus_match(struct device *dev, struct device_driver *drv) +{ + struct vme_bridge *bridge; + struct vme_driver *driver; + int i, num; + + bridge = dev_to_bridge(dev); + driver = container_of(drv, struct vme_driver, driver); + + num = vme_calc_slot(dev); + if (!num) + goto err_dev; + + if (driver->bind_table == NULL) { + dev_err(dev, "Bind table NULL\n"); + goto err_table; + } + + i = 0; + while((driver->bind_table[i].bus != 0) || + (driver->bind_table[i].slot != 0)) { + + if ((bridge->num == driver->bind_table[i].bus) && + (num == driver->bind_table[i].slot)) + return 1; + i++; + } + +err_dev: +err_table: + return 0; +} + +static int vme_bus_probe(struct device *dev) +{ + struct vme_bridge *bridge; + struct vme_driver *driver; + int retval = -ENODEV; + + driver = dev_to_vme_driver(dev); + bridge = dev_to_bridge(dev); + + if(driver->probe != NULL) { + retval = driver->probe(dev, bridge->num, vme_calc_slot(dev)); + } + + return retval; +} + +static int vme_bus_remove(struct device *dev) +{ + struct vme_bridge *bridge; + struct vme_driver *driver; + int retval = -ENODEV; + + driver = dev_to_vme_driver(dev); + bridge = dev_to_bridge(dev); + + if(driver->remove != NULL) { + retval = driver->remove(dev, bridge->num, vme_calc_slot(dev)); + } + + return retval; +} + +struct bus_type vme_bus_type = { + .name = "vme", + .match = vme_bus_match, + .probe = vme_bus_probe, + .remove = vme_bus_remove, +}; +EXPORT_SYMBOL(vme_bus_type); + +static int __init vme_init (void) +{ + return bus_register(&vme_bus_type); +} + +static void __exit vme_exit (void) +{ + bus_unregister(&vme_bus_type); +} + +MODULE_DESCRIPTION("VME bridge driver framework"); +MODULE_AUTHOR("Martyn Welch dev for PCI) */ + void * base; /* Base Address of device registers */ + + struct device dev[VME_SLOTS_MAX]; /* Device registered with + * device model on VME bus + */ + + /* Interrupt callbacks */ + struct vme_irq irq[7]; + + /* Slave Functions */ + int (*slave_get) (struct vme_slave_resource *, int *, + unsigned long long *, unsigned long long *, dma_addr_t *, + vme_address_t *, vme_cycle_t *); + int (*slave_set) (struct vme_slave_resource *, int, unsigned long long, + unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t); + + /* Master Functions */ + int (*master_get) (struct vme_master_resource *, int *, + unsigned long long *, unsigned long long *, vme_address_t *, + vme_cycle_t *, vme_width_t *); + int (*master_set) (struct vme_master_resource *, int, + unsigned long long, unsigned long long, vme_address_t, + vme_cycle_t, vme_width_t); + ssize_t (*master_read) (struct vme_master_resource *, void *, size_t, + loff_t); + ssize_t (*master_write) (struct vme_master_resource *, void *, size_t, + loff_t); + unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int, + unsigned int, unsigned int, loff_t); + + /* DMA Functions */ + int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *, + struct vme_dma_attr *, size_t); + int (*dma_list_exec) (struct vme_dma_list *); + int (*dma_list_empty) (struct vme_dma_list *); + + /* Interrupt Functions */ + int (*request_irq) (int, int, void (*cback)(int, int, void*), void *); + void (*free_irq) (int, int); + int (*generate_irq) (int, int); + + /* Location monitor functions */ + int (*lm_set) (unsigned long long, vme_address_t, vme_cycle_t); + int (*lm_get) (unsigned long long *, vme_address_t *, vme_cycle_t *); + int (*lm_attach) (int, void (*callback)(int)); + int (*lm_detach) (int); + + /* CR/CSR space functions */ + int (*slot_get) (void); + /* Use standard master read and write functions to access CR/CSR */ + +#if 0 + int (*set_prefetch) (void); + int (*get_prefetch) (void); + int (*set_arbiter) (void); + int (*get_arbiter) (void); + int (*set_requestor) (void); + int (*get_requestor) (void); +#endif +}; + +int vme_register_bridge (struct vme_bridge *); +void vme_unregister_bridge (struct vme_bridge *); + +#endif /* _VME_BRIDGE_H_ */ + +#if 0 +/* + * VMEbus GET INFO Arg Structure + */ +struct vmeInfoCfg { + int vmeSlotNum; /* VME slot number of interest */ + int boardResponded; /* Board responded */ + char sysConFlag; /* System controller flag */ + int vmeControllerID; /* Vendor/device ID of VME bridge */ + int vmeControllerRev; /* Revision of VME bridge */ + char osName[8]; /* Name of OS e.g. "Linux" */ + int vmeSharedDataValid; /* Validity of data struct */ + int vmeDriverRev; /* Revision of VME driver */ + unsigned int vmeAddrHi[8]; /* Address on VME bus */ + unsigned int vmeAddrLo[8]; /* Address on VME bus */ + unsigned int vmeSize[8]; /* Size on VME bus */ + unsigned int vmeAm[8]; /* Address modifier on VME bus */ + int reserved; /* For future use */ +}; +typedef struct vmeInfoCfg vmeInfoCfg_t; + +/* + * VMEbus Requester Arg Structure + */ +struct vmeRequesterCfg { + int requestLevel; /* Requester Bus Request Level */ + char fairMode; /* Requester Fairness Mode Indicator */ + int releaseMode; /* Requester Bus Release Mode */ + int timeonTimeoutTimer; /* Master Time-on Time-out Timer */ + int timeoffTimeoutTimer; /* Master Time-off Time-out Timer */ + int reserved; /* For future use */ +}; +typedef struct vmeRequesterCfg vmeRequesterCfg_t; + +/* + * VMEbus Arbiter Arg Structure + */ +struct vmeArbiterCfg { + vme_arbitration_t arbiterMode; /* Arbitration Scheduling Algorithm */ + char arbiterTimeoutFlag; /* Arbiter Time-out Timer Indicator */ + int globalTimeoutTimer; /* VMEbus Global Time-out Timer */ + char noEarlyReleaseFlag; /* No Early Release on BBUSY */ + int reserved; /* For future use */ +}; +typedef struct vmeArbiterCfg vmeArbiterCfg_t; + + +/* + * VMEbus RMW Configuration Data + */ +struct vmeRmwCfg { + unsigned int targetAddrU; /* VME Address (Upper) to trigger RMW cycle */ + unsigned int targetAddr; /* VME Address (Lower) to trigger RMW cycle */ + vme_address_t addrSpace; /* VME Address Space */ + int enableMask; /* Bit mask defining the bits of interest */ + int compareData; /* Data to be compared with the data read */ + int swapData; /* Data written to the VMEbus on success */ + int maxAttempts; /* Maximum times to try */ + int numAttempts; /* Number of attempts before success */ + int reserved; /* For future use */ + +}; +typedef struct vmeRmwCfg vmeRmwCfg_t; + +/* + * VMEbus Location Monitor Arg Structure + */ +struct vmeLmCfg { + unsigned int addrU; /* Location Monitor Address upper */ + unsigned int addr; /* Location Monitor Address lower */ + vme_address_t addrSpace; /* Address Space */ + int userAccessType; /* User/Supervisor Access Type */ + int dataAccessType; /* Data/Program Access Type */ + int lmWait; /* Time to wait for access */ + int lmEvents; /* Lm event mask */ + int reserved; /* For future use */ +}; +typedef struct vmeLmCfg vmeLmCfg_t; +#endif -- cgit v1.2.3 From 0841a555af4e15c1048f69b800a475f2fbf315a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 28 Jul 2009 17:05:51 -0700 Subject: Staging: remove epl driver This is no longer maintained upstream, and no one cares about it at all, so delete it. The fact that it is duplicating an existing network driver also is a good reason to remove it, it's causing nothing but trouble right now. Cc: Daniel Krueger Cc: Ronald Sieber Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/epl/Benchmark.h | 425 --- drivers/staging/epl/Debug.h | 694 ----- drivers/staging/epl/Edrv8139.c | 1246 -------- drivers/staging/epl/EdrvFec.h | 114 - drivers/staging/epl/EdrvSim.h | 89 - drivers/staging/epl/Epl.h | 272 -- drivers/staging/epl/EplAmi.h | 323 -- drivers/staging/epl/EplApiGeneric.c | 2054 ------------- drivers/staging/epl/EplApiLinux.h | 141 - drivers/staging/epl/EplApiLinuxKernel.c | 1173 ------- drivers/staging/epl/EplApiProcessImage.c | 328 -- drivers/staging/epl/EplCfg.h | 196 -- drivers/staging/epl/EplDef.h | 355 --- drivers/staging/epl/EplDll.h | 205 -- drivers/staging/epl/EplDllCal.h | 123 - drivers/staging/epl/EplDllk.c | 4052 ------------------------- drivers/staging/epl/EplDllkCal.c | 1260 -------- drivers/staging/epl/EplDlluCal.c | 529 ---- drivers/staging/epl/EplErrDef.h | 294 -- drivers/staging/epl/EplErrorHandlerk.c | 810 ----- drivers/staging/epl/EplEvent.h | 279 -- drivers/staging/epl/EplEventk.c | 853 ------ drivers/staging/epl/EplEventu.c | 813 ----- drivers/staging/epl/EplFrame.h | 344 --- drivers/staging/epl/EplIdentu.c | 486 --- drivers/staging/epl/EplInc.h | 370 --- drivers/staging/epl/EplInstDef.h | 363 --- drivers/staging/epl/EplLed.h | 92 - drivers/staging/epl/EplNmt.h | 230 -- drivers/staging/epl/EplNmtCnu.c | 701 ----- drivers/staging/epl/EplNmtMnu.c | 2828 ----------------- drivers/staging/epl/EplNmtk.c | 1840 ----------- drivers/staging/epl/EplNmtkCal.c | 147 - drivers/staging/epl/EplNmtu.c | 706 ----- drivers/staging/epl/EplNmtuCal.c | 158 - drivers/staging/epl/EplObd.c | 3192 ------------------- drivers/staging/epl/EplObd.h | 456 --- drivers/staging/epl/EplObdMacro.h | 354 --- drivers/staging/epl/EplObdkCal.c | 146 - drivers/staging/epl/EplObdu.c | 506 --- drivers/staging/epl/EplObduCal.c | 543 ---- drivers/staging/epl/EplPdo.h | 117 - drivers/staging/epl/EplPdok.c | 669 ---- drivers/staging/epl/EplPdokCal.c | 266 -- drivers/staging/epl/EplPdou.c | 565 ---- drivers/staging/epl/EplSdo.h | 241 -- drivers/staging/epl/EplSdoAc.h | 111 - drivers/staging/epl/EplSdoAsndu.c | 483 --- drivers/staging/epl/EplSdoAsySequ.c | 2522 --------------- drivers/staging/epl/EplSdoComu.c | 3345 -------------------- drivers/staging/epl/EplSdoUdpu.c | 650 ---- drivers/staging/epl/EplStatusu.c | 377 --- drivers/staging/epl/EplTarget.h | 140 - drivers/staging/epl/EplTimer.h | 116 - drivers/staging/epl/EplTimeruLinuxKernel.c | 446 --- drivers/staging/epl/EplVersion.h | 98 - drivers/staging/epl/Kconfig | 6 - drivers/staging/epl/Makefile | 41 - drivers/staging/epl/SharedBuff.c | 1762 ----------- drivers/staging/epl/SharedBuff.h | 187 -- drivers/staging/epl/ShbIpc-LinuxKernel.c | 944 ------ drivers/staging/epl/ShbIpc.h | 99 - drivers/staging/epl/ShbLinuxKernel.h | 68 - drivers/staging/epl/SocketLinuxKernel.c | 197 -- drivers/staging/epl/SocketLinuxKernel.h | 105 - drivers/staging/epl/TimerHighReskX86.c | 510 ---- drivers/staging/epl/VirtualEthernetLinux.c | 348 --- drivers/staging/epl/amix86.c | 861 ------ drivers/staging/epl/demo_main.c | 947 ------ drivers/staging/epl/edrv.h | 167 - drivers/staging/epl/global.h | 144 - drivers/staging/epl/kernel/EplDllk.h | 153 - drivers/staging/epl/kernel/EplDllkCal.h | 129 - drivers/staging/epl/kernel/EplErrorHandlerk.h | 88 - drivers/staging/epl/kernel/EplEventk.h | 96 - drivers/staging/epl/kernel/EplNmtk.h | 90 - drivers/staging/epl/kernel/EplObdk.h | 156 - drivers/staging/epl/kernel/EplPdok.h | 98 - drivers/staging/epl/kernel/EplPdokCal.h | 86 - drivers/staging/epl/kernel/EplTimerHighResk.h | 96 - drivers/staging/epl/kernel/EplTimerk.h | 108 - drivers/staging/epl/kernel/VirtualEthernet.h | 84 - drivers/staging/epl/proc_fs.c | 410 --- drivers/staging/epl/proc_fs.h | 89 - drivers/staging/epl/user/EplCfgMau.h | 276 -- drivers/staging/epl/user/EplDllu.h | 96 - drivers/staging/epl/user/EplDlluCal.h | 106 - drivers/staging/epl/user/EplEventu.h | 96 - drivers/staging/epl/user/EplIdentu.h | 94 - drivers/staging/epl/user/EplLedu.h | 95 - drivers/staging/epl/user/EplNmtCnu.h | 92 - drivers/staging/epl/user/EplNmtMnu.h | 117 - drivers/staging/epl/user/EplNmtu.h | 139 - drivers/staging/epl/user/EplNmtuCal.h | 80 - drivers/staging/epl/user/EplObdu.h | 169 -- drivers/staging/epl/user/EplObduCal.h | 126 - drivers/staging/epl/user/EplPdou.h | 96 - drivers/staging/epl/user/EplSdoAsndu.h | 96 - drivers/staging/epl/user/EplSdoAsySequ.h | 100 - drivers/staging/epl/user/EplSdoComu.h | 114 - drivers/staging/epl/user/EplSdoUdpu.h | 97 - drivers/staging/epl/user/EplStatusu.h | 90 - drivers/staging/epl/user/EplTimeru.h | 95 - 105 files changed, 50482 deletions(-) delete mode 100644 drivers/staging/epl/Benchmark.h delete mode 100644 drivers/staging/epl/Debug.h delete mode 100644 drivers/staging/epl/Edrv8139.c delete mode 100644 drivers/staging/epl/EdrvFec.h delete mode 100644 drivers/staging/epl/EdrvSim.h delete mode 100644 drivers/staging/epl/Epl.h delete mode 100644 drivers/staging/epl/EplAmi.h delete mode 100644 drivers/staging/epl/EplApiGeneric.c delete mode 100644 drivers/staging/epl/EplApiLinux.h delete mode 100644 drivers/staging/epl/EplApiLinuxKernel.c delete mode 100644 drivers/staging/epl/EplApiProcessImage.c delete mode 100644 drivers/staging/epl/EplCfg.h delete mode 100644 drivers/staging/epl/EplDef.h delete mode 100644 drivers/staging/epl/EplDll.h delete mode 100644 drivers/staging/epl/EplDllCal.h delete mode 100644 drivers/staging/epl/EplDllk.c delete mode 100644 drivers/staging/epl/EplDllkCal.c delete mode 100644 drivers/staging/epl/EplDlluCal.c delete mode 100644 drivers/staging/epl/EplErrDef.h delete mode 100644 drivers/staging/epl/EplErrorHandlerk.c delete mode 100644 drivers/staging/epl/EplEvent.h delete mode 100644 drivers/staging/epl/EplEventk.c delete mode 100644 drivers/staging/epl/EplEventu.c delete mode 100644 drivers/staging/epl/EplFrame.h delete mode 100644 drivers/staging/epl/EplIdentu.c delete mode 100644 drivers/staging/epl/EplInc.h delete mode 100644 drivers/staging/epl/EplInstDef.h delete mode 100644 drivers/staging/epl/EplLed.h delete mode 100644 drivers/staging/epl/EplNmt.h delete mode 100644 drivers/staging/epl/EplNmtCnu.c delete mode 100644 drivers/staging/epl/EplNmtMnu.c delete mode 100644 drivers/staging/epl/EplNmtk.c delete mode 100644 drivers/staging/epl/EplNmtkCal.c delete mode 100644 drivers/staging/epl/EplNmtu.c delete mode 100644 drivers/staging/epl/EplNmtuCal.c delete mode 100644 drivers/staging/epl/EplObd.c delete mode 100644 drivers/staging/epl/EplObd.h delete mode 100644 drivers/staging/epl/EplObdMacro.h delete mode 100644 drivers/staging/epl/EplObdkCal.c delete mode 100644 drivers/staging/epl/EplObdu.c delete mode 100644 drivers/staging/epl/EplObduCal.c delete mode 100644 drivers/staging/epl/EplPdo.h delete mode 100644 drivers/staging/epl/EplPdok.c delete mode 100644 drivers/staging/epl/EplPdokCal.c delete mode 100644 drivers/staging/epl/EplPdou.c delete mode 100644 drivers/staging/epl/EplSdo.h delete mode 100644 drivers/staging/epl/EplSdoAc.h delete mode 100644 drivers/staging/epl/EplSdoAsndu.c delete mode 100644 drivers/staging/epl/EplSdoAsySequ.c delete mode 100644 drivers/staging/epl/EplSdoComu.c delete mode 100644 drivers/staging/epl/EplSdoUdpu.c delete mode 100644 drivers/staging/epl/EplStatusu.c delete mode 100644 drivers/staging/epl/EplTarget.h delete mode 100644 drivers/staging/epl/EplTimer.h delete mode 100644 drivers/staging/epl/EplTimeruLinuxKernel.c delete mode 100644 drivers/staging/epl/EplVersion.h delete mode 100644 drivers/staging/epl/Kconfig delete mode 100644 drivers/staging/epl/Makefile delete mode 100644 drivers/staging/epl/SharedBuff.c delete mode 100644 drivers/staging/epl/SharedBuff.h delete mode 100644 drivers/staging/epl/ShbIpc-LinuxKernel.c delete mode 100644 drivers/staging/epl/ShbIpc.h delete mode 100644 drivers/staging/epl/ShbLinuxKernel.h delete mode 100644 drivers/staging/epl/SocketLinuxKernel.c delete mode 100644 drivers/staging/epl/SocketLinuxKernel.h delete mode 100644 drivers/staging/epl/TimerHighReskX86.c delete mode 100644 drivers/staging/epl/VirtualEthernetLinux.c delete mode 100644 drivers/staging/epl/amix86.c delete mode 100644 drivers/staging/epl/demo_main.c delete mode 100644 drivers/staging/epl/edrv.h delete mode 100644 drivers/staging/epl/global.h delete mode 100644 drivers/staging/epl/kernel/EplDllk.h delete mode 100644 drivers/staging/epl/kernel/EplDllkCal.h delete mode 100644 drivers/staging/epl/kernel/EplErrorHandlerk.h delete mode 100644 drivers/staging/epl/kernel/EplEventk.h delete mode 100644 drivers/staging/epl/kernel/EplNmtk.h delete mode 100644 drivers/staging/epl/kernel/EplObdk.h delete mode 100644 drivers/staging/epl/kernel/EplPdok.h delete mode 100644 drivers/staging/epl/kernel/EplPdokCal.h delete mode 100644 drivers/staging/epl/kernel/EplTimerHighResk.h delete mode 100644 drivers/staging/epl/kernel/EplTimerk.h delete mode 100644 drivers/staging/epl/kernel/VirtualEthernet.h delete mode 100644 drivers/staging/epl/proc_fs.c delete mode 100644 drivers/staging/epl/proc_fs.h delete mode 100644 drivers/staging/epl/user/EplCfgMau.h delete mode 100644 drivers/staging/epl/user/EplDllu.h delete mode 100644 drivers/staging/epl/user/EplDlluCal.h delete mode 100644 drivers/staging/epl/user/EplEventu.h delete mode 100644 drivers/staging/epl/user/EplIdentu.h delete mode 100644 drivers/staging/epl/user/EplLedu.h delete mode 100644 drivers/staging/epl/user/EplNmtCnu.h delete mode 100644 drivers/staging/epl/user/EplNmtMnu.h delete mode 100644 drivers/staging/epl/user/EplNmtu.h delete mode 100644 drivers/staging/epl/user/EplNmtuCal.h delete mode 100644 drivers/staging/epl/user/EplObdu.h delete mode 100644 drivers/staging/epl/user/EplObduCal.h delete mode 100644 drivers/staging/epl/user/EplPdou.h delete mode 100644 drivers/staging/epl/user/EplSdoAsndu.h delete mode 100644 drivers/staging/epl/user/EplSdoAsySequ.h delete mode 100644 drivers/staging/epl/user/EplSdoComu.h delete mode 100644 drivers/staging/epl/user/EplSdoUdpu.h delete mode 100644 drivers/staging/epl/user/EplStatusu.h delete mode 100644 drivers/staging/epl/user/EplTimeru.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 58274ca5e63..7b500a88060 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -95,8 +95,6 @@ source "drivers/staging/mimio/Kconfig" source "drivers/staging/frontier/Kconfig" -source "drivers/staging/epl/Kconfig" - source "drivers/staging/android/Kconfig" source "drivers/staging/dream/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0bf10ac04d0..1ac7c8f23d0 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_RTL8192SU) += rtl8192su/ obj-$(CONFIG_USB_RSPI) += rspiusb/ obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ -obj-$(CONFIG_EPL) += epl/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_ANDROID) += dream/ obj-$(CONFIG_DST) += dst/ diff --git a/drivers/staging/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h deleted file mode 100644 index 4cc01bd12a1..00000000000 --- a/drivers/staging/epl/Benchmark.h +++ /dev/null @@ -1,425 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: header file for benchmarking - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: Benchmark.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - - 2006/08/16 d.k.: start of implementation - -****************************************************************************/ - -#ifndef _BENCHMARK_H_ -#define _BENCHMARK_H_ - -#include "global.h" - -#include - -#ifdef CONFIG_COLDFIRE -#include -#include - -#define BENCHMARK_SET(x) MCF_GPIO_PODR_PCIBG |= (1 << (x)) // (x+1) -#define BENCHMARK_RESET(x) MCF_GPIO_PODR_PCIBG &= ~(1 << (x)) // (x+1) -#define BENCHMARK_TOGGLE(x) MCF_GPIO_PODR_PCIBR ^= (1 << (x - 5)) -#else -#undef BENCHMARK_MODULES -#define BENCHMARK_MODULES 0x00000000 -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef BENCHMARK_MODULES -#define BENCHMARK_MODULES 0x00000000 -#endif - -#define BENCHMARK_MOD_01 0x00000001 -#define BENCHMARK_MOD_02 0x00000002 -#define BENCHMARK_MOD_03 0x00000004 -#define BENCHMARK_MOD_04 0x00000008 -#define BENCHMARK_MOD_05 0x00000010 -#define BENCHMARK_MOD_06 0x00000020 -#define BENCHMARK_MOD_07 0x00000040 -#define BENCHMARK_MOD_08 0x00000080 -#define BENCHMARK_MOD_09 0x00000100 -#define BENCHMARK_MOD_10 0x00000200 -#define BENCHMARK_MOD_11 0x00000400 -#define BENCHMARK_MOD_12 0x00000800 -#define BENCHMARK_MOD_13 0x00001000 -#define BENCHMARK_MOD_14 0x00002000 -#define BENCHMARK_MOD_15 0x00004000 -#define BENCHMARK_MOD_16 0x00008000 -#define BENCHMARK_MOD_17 0x00010000 -#define BENCHMARK_MOD_18 0x00020000 -#define BENCHMARK_MOD_19 0x00040000 -#define BENCHMARK_MOD_20 0x00080000 -#define BENCHMARK_MOD_21 0x00100000 -#define BENCHMARK_MOD_22 0x00200000 -#define BENCHMARK_MOD_23 0x00400000 -#define BENCHMARK_MOD_24 0x00800000 -#define BENCHMARK_MOD_25 0x01000000 -#define BENCHMARK_MOD_26 0x02000000 -#define BENCHMARK_MOD_27 0x04000000 -#define BENCHMARK_MOD_28 0x08000000 -#define BENCHMARK_MOD_29 0x10000000 -#define BENCHMARK_MOD_30 0x20000000 -#define BENCHMARK_MOD_31 0x40000000 -#define BENCHMARK_MOD_32 0x80000000 - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_01) -#define BENCHMARK_MOD_01_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_01_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_01_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_01_SET(x) -#define BENCHMARK_MOD_01_RESET(x) -#define BENCHMARK_MOD_01_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_02) -#define BENCHMARK_MOD_02_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_02_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_02_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_02_SET(x) -#define BENCHMARK_MOD_02_RESET(x) -#define BENCHMARK_MOD_02_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_03) -#define BENCHMARK_MOD_03_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_03_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_03_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_03_SET(x) -#define BENCHMARK_MOD_03_RESET(x) -#define BENCHMARK_MOD_03_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_04) -#define BENCHMARK_MOD_04_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_04_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_04_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_04_SET(x) -#define BENCHMARK_MOD_04_RESET(x) -#define BENCHMARK_MOD_04_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_05) -#define BENCHMARK_MOD_05_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_05_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_05_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_05_SET(x) -#define BENCHMARK_MOD_05_RESET(x) -#define BENCHMARK_MOD_05_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_06) -#define BENCHMARK_MOD_06_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_06_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_06_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_06_SET(x) -#define BENCHMARK_MOD_06_RESET(x) -#define BENCHMARK_MOD_06_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_07) -#define BENCHMARK_MOD_07_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_07_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_07_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_07_SET(x) -#define BENCHMARK_MOD_07_RESET(x) -#define BENCHMARK_MOD_07_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_08) -#define BENCHMARK_MOD_08_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_08_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_08_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_08_SET(x) -#define BENCHMARK_MOD_08_RESET(x) -#define BENCHMARK_MOD_08_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_09) -#define BENCHMARK_MOD_09_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_09_RESET(x) BENCHMARK_RESET(x) -#define BENCHMARK_MOD_09_TOGGLE(x) BENCHMARK_TOGGLE(x) -#else -#define BENCHMARK_MOD_09_SET(x) -#define BENCHMARK_MOD_09_RESET(x) -#define BENCHMARK_MOD_09_TOGGLE(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_10) -#define BENCHMARK_MOD_10_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_10_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_10_SET(x) -#define BENCHMARK_MOD_10_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_11) -#define BENCHMARK_MOD_11_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_11_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_11_SET(x) -#define BENCHMARK_MOD_11_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_12) -#define BENCHMARK_MOD_12_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_12_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_12_SET(x) -#define BENCHMARK_MOD_12_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_13) -#define BENCHMARK_MOD_13_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_13_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_13_SET(x) -#define BENCHMARK_MOD_13_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_14) -#define BENCHMARK_MOD_14_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_14_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_14_SET(x) -#define BENCHMARK_MOD_14_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_15) -#define BENCHMARK_MOD_15_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_15_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_15_SET(x) -#define BENCHMARK_MOD_15_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_16) -#define BENCHMARK_MOD_16_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_16_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_16_SET(x) -#define BENCHMARK_MOD_16_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_17) -#define BENCHMARK_MOD_17_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_17_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_17_SET(x) -#define BENCHMARK_MOD_17_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_18) -#define BENCHMARK_MOD_18_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_18_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_18_SET(x) -#define BENCHMARK_MOD_18_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_19) -#define BENCHMARK_MOD_19_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_19_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_19_SET(x) -#define BENCHMARK_MOD_19_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_20) -#define BENCHMARK_MOD_20_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_20_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_20_SET(x) -#define BENCHMARK_MOD_20_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_21) -#define BENCHMARK_MOD_21_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_21_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_21_SET(x) -#define BENCHMARK_MOD_21_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_22) -#define BENCHMARK_MOD_22_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_22_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_22_SET(x) -#define BENCHMARK_MOD_22_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_23) -#define BENCHMARK_MOD_23_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_23_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_23_SET(x) -#define BENCHMARK_MOD_23_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_24) -#define BENCHMARK_MOD_24_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_24_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_24_SET(x) -#define BENCHMARK_MOD_24_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_25) -#define BENCHMARK_MOD_25_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_25_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_25_SET(x) -#define BENCHMARK_MOD_25_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_26) -#define BENCHMARK_MOD_26_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_26_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_26_SET(x) -#define BENCHMARK_MOD_26_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_27) -#define BENCHMARK_MOD_27_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_27_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_27_SET(x) -#define BENCHMARK_MOD_27_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_28) -#define BENCHMARK_MOD_28_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_28_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_28_SET(x) -#define BENCHMARK_MOD_28_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_29) -#define BENCHMARK_MOD_29_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_29_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_29_SET(x) -#define BENCHMARK_MOD_29_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_30) -#define BENCHMARK_MOD_30_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_30_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_30_SET(x) -#define BENCHMARK_MOD_30_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_31) -#define BENCHMARK_MOD_31_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_31_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_31_SET(x) -#define BENCHMARK_MOD_31_RESET(x) -#endif - -#if (BENCHMARK_MODULES & BENCHMARK_MOD_32) -#define BENCHMARK_MOD_32_SET(x) BENCHMARK_SET(x) -#define BENCHMARK_MOD_32_RESET(x) BENCHMARK_RESET(x) -#else -#define BENCHMARK_MOD_32_SET(x) -#define BENCHMARK_MOD_32_RESET(x) -#endif - -//--------------------------------------------------------------------------- -// modul global types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -#endif // _BENCHMARK_H_ diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h deleted file mode 100644 index 851a22213ad..00000000000 --- a/drivers/staging/epl/Debug.h +++ /dev/null @@ -1,694 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Debug interface - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: Debug.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - -****************************************************************************/ - -#ifndef _DEBUG_H_ -#define _DEBUG_H_ - -#include "global.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// global const defines -//--------------------------------------------------------------------------- - -// These definitions are important for level-debug traces. -// A macro DEBUG_GLB_LVL() defines the current debug-level using following bis. -// If the corresponding bit is set then trace message will be printed out -// (only if NDEBUG is not defined). The upper debug-levels are reserved for -// the debug-levels ALWAYS, ERROR and ASSERT. -#define DEBUG_LVL_01 0x00000001 -#define DEBUG_LVL_02 0x00000002 -#define DEBUG_LVL_03 0x00000004 -#define DEBUG_LVL_04 0x00000008 -#define DEBUG_LVL_05 0x00000010 -#define DEBUG_LVL_06 0x00000020 -#define DEBUG_LVL_07 0x00000040 -#define DEBUG_LVL_08 0x00000080 -#define DEBUG_LVL_09 0x00000100 -#define DEBUG_LVL_10 0x00000200 -#define DEBUG_LVL_11 0x00000400 -#define DEBUG_LVL_12 0x00000800 -#define DEBUG_LVL_13 0x00001000 -#define DEBUG_LVL_14 0x00002000 -#define DEBUG_LVL_15 0x00004000 -#define DEBUG_LVL_16 0x00008000 -#define DEBUG_LVL_17 0x00010000 -#define DEBUG_LVL_18 0x00020000 -#define DEBUG_LVL_19 0x00040000 -#define DEBUG_LVL_20 0x00080000 -#define DEBUG_LVL_21 0x00100000 -#define DEBUG_LVL_22 0x00200000 -#define DEBUG_LVL_23 0x00400000 -#define DEBUG_LVL_24 0x00800000 -#define DEBUG_LVL_25 0x01000000 -#define DEBUG_LVL_26 0x02000000 -#define DEBUG_LVL_27 0x04000000 -#define DEBUG_LVL_28 0x08000000 -#define DEBUG_LVL_29 0x10000000 -#define DEBUG_LVL_ASSERT 0x20000000 -#define DEBUG_LVL_ERROR 0x40000000 -#define DEBUG_LVL_ALWAYS 0x80000000 - -//--------------------------------------------------------------------------- -// global types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// global vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// global function prototypes -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// global macros -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// this macro defines a version string - - -//--------------------------------------------------------------------------- -// this macro defines a build info string (e.g. for using in printf()) -#define DEBUG_MAKE_BUILD_INFO(prefix,product,prodid,descr,verstr,author) "\n" \ - prefix "***************************************************\n" \ - prefix "Project: " product ", " prodid "\n" \ - prefix "Descript.: " descr "\n" \ - prefix "Author: " author "\n" \ - prefix "Date: " __DATE__ "\n" \ - prefix "Version: " verstr "\n" \ - prefix "***************************************************\n\n" - -//--------------------------------------------------------------------------- -// The default debug-level is: ERROR and ALWAYS. -// You can define an other debug-level in project settings. -#ifndef DEF_DEBUG_LVL -#define DEF_DEBUG_LVL (DEBUG_LVL_ALWAYS | DEBUG_LVL_ERROR) -#endif -#ifndef DEBUG_GLB_LVL -#define DEBUG_GLB_LVL() (DEF_DEBUG_LVL) -#endif - -//--------------------------------------------------------------------------- - // At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines - // (compiler does delete the lines). - // - // Here the parameter 'lvl' can only be used with one debug-level. - // - // Example: DEBUG_TRACE1(DEBUG_LVL_ERROR, "error code %d", dwRet); - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_ALWAYS) -#define DEBUG_LVL_ALWAYS_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_ALWAYS_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_ALWAYS_TRACE0(str) -#define DEBUG_LVL_ALWAYS_TRACE1(str,p1) -#define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2) -#define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_ERROR) -#define DEBUG_LVL_ERROR_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_ERROR_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_ERROR_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_ERROR_TRACE0(str) -#define DEBUG_LVL_ERROR_TRACE1(str,p1) -#define DEBUG_LVL_ERROR_TRACE2(str,p1,p2) -#define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT) -#define DEBUG_LVL_ASSERT_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_ASSERT_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_ASSERT_TRACE0(str) -#define DEBUG_LVL_ASSERT_TRACE1(str,p1) -#define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2) -#define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_29) -#define DEBUG_LVL_29_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_29_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_29_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_29_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_29_TRACE0(str) -#define DEBUG_LVL_29_TRACE1(str,p1) -#define DEBUG_LVL_29_TRACE2(str,p1,p2) -#define DEBUG_LVL_29_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_28) -#define DEBUG_LVL_28_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_28_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_28_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_28_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_28_TRACE0(str) -#define DEBUG_LVL_28_TRACE1(str,p1) -#define DEBUG_LVL_28_TRACE2(str,p1,p2) -#define DEBUG_LVL_28_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_27) -#define DEBUG_LVL_27_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_27_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_27_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_27_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_27_TRACE0(str) -#define DEBUG_LVL_27_TRACE1(str,p1) -#define DEBUG_LVL_27_TRACE2(str,p1,p2) -#define DEBUG_LVL_27_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_26) -#define DEBUG_LVL_26_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_26_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_26_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_26_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_26_TRACE0(str) -#define DEBUG_LVL_26_TRACE1(str,p1) -#define DEBUG_LVL_26_TRACE2(str,p1,p2) -#define DEBUG_LVL_26_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_25) -#define DEBUG_LVL_25_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_25_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_25_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_25_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_25_TRACE0(str) -#define DEBUG_LVL_25_TRACE1(str,p1) -#define DEBUG_LVL_25_TRACE2(str,p1,p2) -#define DEBUG_LVL_25_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_24) -#define DEBUG_LVL_24_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_24_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_24_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_24_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_24_TRACE0(str) -#define DEBUG_LVL_24_TRACE1(str,p1) -#define DEBUG_LVL_24_TRACE2(str,p1,p2) -#define DEBUG_LVL_24_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_23) -#define DEBUG_LVL_23_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_23_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_23_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_23_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_23_TRACE0(str) -#define DEBUG_LVL_23_TRACE1(str,p1) -#define DEBUG_LVL_23_TRACE2(str,p1,p2) -#define DEBUG_LVL_23_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_22) -#define DEBUG_LVL_22_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_22_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_22_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_22_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_22_TRACE0(str) -#define DEBUG_LVL_22_TRACE1(str,p1) -#define DEBUG_LVL_22_TRACE2(str,p1,p2) -#define DEBUG_LVL_22_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_21) -#define DEBUG_LVL_21_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_21_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_21_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_21_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_21_TRACE0(str) -#define DEBUG_LVL_21_TRACE1(str,p1) -#define DEBUG_LVL_21_TRACE2(str,p1,p2) -#define DEBUG_LVL_21_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_20) -#define DEBUG_LVL_20_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_20_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_20_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_20_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_20_TRACE0(str) -#define DEBUG_LVL_20_TRACE1(str,p1) -#define DEBUG_LVL_20_TRACE2(str,p1,p2) -#define DEBUG_LVL_20_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_19) -#define DEBUG_LVL_19_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_19_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_19_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_19_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_19_TRACE0(str) -#define DEBUG_LVL_19_TRACE1(str,p1) -#define DEBUG_LVL_19_TRACE2(str,p1,p2) -#define DEBUG_LVL_19_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_18) -#define DEBUG_LVL_18_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_18_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_18_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_18_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_18_TRACE0(str) -#define DEBUG_LVL_18_TRACE1(str,p1) -#define DEBUG_LVL_18_TRACE2(str,p1,p2) -#define DEBUG_LVL_18_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_17) -#define DEBUG_LVL_17_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_17_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_17_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_17_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_17_TRACE0(str) -#define DEBUG_LVL_17_TRACE1(str,p1) -#define DEBUG_LVL_17_TRACE2(str,p1,p2) -#define DEBUG_LVL_17_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_16) -#define DEBUG_LVL_16_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_16_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_16_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_16_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_16_TRACE0(str) -#define DEBUG_LVL_16_TRACE1(str,p1) -#define DEBUG_LVL_16_TRACE2(str,p1,p2) -#define DEBUG_LVL_16_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_15) -#define DEBUG_LVL_15_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_15_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_15_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_15_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_15_TRACE0(str) -#define DEBUG_LVL_15_TRACE1(str,p1) -#define DEBUG_LVL_15_TRACE2(str,p1,p2) -#define DEBUG_LVL_15_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_14) -#define DEBUG_LVL_14_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_14_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_14_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_14_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_14_TRACE0(str) -#define DEBUG_LVL_14_TRACE1(str,p1) -#define DEBUG_LVL_14_TRACE2(str,p1,p2) -#define DEBUG_LVL_14_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_13) -#define DEBUG_LVL_13_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_13_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_13_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_13_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_13_TRACE0(str) -#define DEBUG_LVL_13_TRACE1(str,p1) -#define DEBUG_LVL_13_TRACE2(str,p1,p2) -#define DEBUG_LVL_13_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_12) -#define DEBUG_LVL_12_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_12_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_12_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_12_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_12_TRACE0(str) -#define DEBUG_LVL_12_TRACE1(str,p1) -#define DEBUG_LVL_12_TRACE2(str,p1,p2) -#define DEBUG_LVL_12_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_11) -#define DEBUG_LVL_11_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_11_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_11_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_11_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_11_TRACE0(str) -#define DEBUG_LVL_11_TRACE1(str,p1) -#define DEBUG_LVL_11_TRACE2(str,p1,p2) -#define DEBUG_LVL_11_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_10) -#define DEBUG_LVL_10_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_10_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_10_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_10_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_10_TRACE0(str) -#define DEBUG_LVL_10_TRACE1(str,p1) -#define DEBUG_LVL_10_TRACE2(str,p1,p2) -#define DEBUG_LVL_10_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_09) -#define DEBUG_LVL_09_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_09_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_09_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_09_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_09_TRACE0(str) -#define DEBUG_LVL_09_TRACE1(str,p1) -#define DEBUG_LVL_09_TRACE2(str,p1,p2) -#define DEBUG_LVL_09_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_08) -#define DEBUG_LVL_08_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_08_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_08_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_08_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_08_TRACE0(str) -#define DEBUG_LVL_08_TRACE1(str,p1) -#define DEBUG_LVL_08_TRACE2(str,p1,p2) -#define DEBUG_LVL_08_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_07) -#define DEBUG_LVL_07_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_07_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_07_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_07_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_07_TRACE0(str) -#define DEBUG_LVL_07_TRACE1(str,p1) -#define DEBUG_LVL_07_TRACE2(str,p1,p2) -#define DEBUG_LVL_07_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_06) -#define DEBUG_LVL_06_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_06_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_06_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_06_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_06_TRACE0(str) -#define DEBUG_LVL_06_TRACE1(str,p1) -#define DEBUG_LVL_06_TRACE2(str,p1,p2) -#define DEBUG_LVL_06_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_05) -#define DEBUG_LVL_05_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_05_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_05_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_05_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_05_TRACE0(str) -#define DEBUG_LVL_05_TRACE1(str,p1) -#define DEBUG_LVL_05_TRACE2(str,p1,p2) -#define DEBUG_LVL_05_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_04) -#define DEBUG_LVL_04_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_04_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_04_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_04_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_04_TRACE0(str) -#define DEBUG_LVL_04_TRACE1(str,p1) -#define DEBUG_LVL_04_TRACE2(str,p1,p2) -#define DEBUG_LVL_04_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_03) -#define DEBUG_LVL_03_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_03_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_03_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_03_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_03_TRACE0(str) -#define DEBUG_LVL_03_TRACE1(str,p1) -#define DEBUG_LVL_03_TRACE2(str,p1,p2) -#define DEBUG_LVL_03_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_02) -#define DEBUG_LVL_02_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_02_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_02_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_02_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_02_TRACE0(str) -#define DEBUG_LVL_02_TRACE1(str,p1) -#define DEBUG_LVL_02_TRACE2(str,p1,p2) -#define DEBUG_LVL_02_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4) -#endif - -#if (DEBUG_GLB_LVL() & DEBUG_LVL_01) -#define DEBUG_LVL_01_TRACE0(str) TRACE0(str) -#define DEBUG_LVL_01_TRACE1(str,p1) TRACE1(str,p1) -#define DEBUG_LVL_01_TRACE2(str,p1,p2) TRACE2(str,p1,p2) -#define DEBUG_LVL_01_TRACE3(str,p1,p2,p3) TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4) TRACE4(str,p1,p2,p3,p4) -#else -#define DEBUG_LVL_01_TRACE0(str) -#define DEBUG_LVL_01_TRACE1(str,p1) -#define DEBUG_LVL_01_TRACE2(str,p1,p2) -#define DEBUG_LVL_01_TRACE3(str,p1,p2,p3) -#define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4) -#endif - -#define DEBUG_TRACE0(lvl,str) lvl##_TRACE0(str) -#define DEBUG_TRACE1(lvl,str,p1) lvl##_TRACE1(str,p1) -#define DEBUG_TRACE2(lvl,str,p1,p2) lvl##_TRACE2(str,p1,p2) -#define DEBUG_TRACE3(lvl,str,p1,p2,p3) lvl##_TRACE3(str,p1,p2,p3) -#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4) lvl##_TRACE4(str,p1,p2,p3,p4) - -//--------------------------------------------------------------------------- -// The macro DEBUG_DUMP_DATA() can be used with the same debug-levels to dump -// out data bytes. Function DumpData() has to be included. -// NOTE: DUMP_DATA has to be defined in project settings. -#if (!defined (NDEBUG) && defined (DUMP_DATA)) - -#ifdef __cplusplus -extern "C" { -#endif - - void DumpData(char *szStr_p, u8 *pbData_p, u16 wSize_p); - -#ifdef __cplusplus -} // von extern "C" -#endif -#define DEBUG_DUMP_DATA(lvl,str,ptr,siz) if ((DEBUG_GLB_LVL() & (lvl))==(lvl)) \ - DumpData (str, (u8 *)(ptr), (u16)(siz)); -#else - -#define DEBUG_DUMP_DATA(lvl,str,ptr,siz) - -#endif - -//--------------------------------------------------------------------------- -// The macro DEBUG_ASSERT() can be used to print out an error string if the -// parametered expresion does not result TRUE. -// NOTE: If DEBUG_KEEP_ASSERT is defined, then DEBUG_ASSERT-line will not be -// deleted from compiler (in release version too). -#if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT) - - // For microcontrollers process will be stopped using endless loop. - -#define DEBUG_ASSERT0(expr,str) if (!(expr )) { \ - DEBUG_LVL_ASSERT_TRACE3 ( \ - "Assertion failed: line %d file '%s'\n" \ - " -> '%s'\n", __LINE__, __FILE__, str); \ - while (1); } - -#define DEBUG_ASSERT1(expr,str,p1) if (!(expr )) { \ - DEBUG_LVL_ASSERT_TRACE4 ( \ - "Assertion failed: line %d file '%s'\n" \ - " -> '%s'\n" \ - " -> 0x%08lX\n", __LINE__, __FILE__, str, (u32) p1); \ - while (1); } - - -#else - -#define DEBUG_ASSERT0(expr,str) -#define DEBUG_ASSERT1(expr,str,p1) - -#endif - -//--------------------------------------------------------------------------- -// The macro DEBUG_ONLY() implements code, if NDEBUG is not defined. -#if !defined (DEBUG_ONLY) -#if !defined (NDEBUG) - -#define DEBUG_ONLY(expr) expr - -#else - -#define DEBUG_ONLY(expr) - -#endif -#endif - -#endif // _DEBUG_H_ diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c deleted file mode 100644 index 44e3f7b144b..00000000000 --- a/drivers/staging/epl/Edrv8139.c +++ /dev/null @@ -1,1246 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Ethernet driver for Realtek RTL8139 chips - except the RTL8139C+, because it has a different - Tx descriptor handling. - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: Edrv8139.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.10 $ $Date: 2008/11/21 09:00:38 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2008/02/05 d.k.: start of implementation - -****************************************************************************/ - -#include "global.h" -#include "EplInc.h" -#include "edrv.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -// Buffer handling: -// All buffers are created statically (i.e. at compile time resp. at -// initialisation via kmalloc() ) and not dynamically on request (i.e. via -// EdrvAllocTxMsgBuffer(). -// EdrvAllocTxMsgBuffer() searches for an unused buffer which is large enough. -// EdrvInit() may allocate some buffers with sizes less than maximum frame -// size (i.e. 1514 bytes), e.g. for SoC, SoA, StatusResponse, IdentResponse, -// NMT requests / commands. The less the size of the buffer the less the -// number of the buffer. - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EDRV_MAX_TX_BUFFERS -#define EDRV_MAX_TX_BUFFERS 20 -#endif - -#define EDRV_MAX_FRAME_SIZE 0x600 - -#define EDRV_RX_BUFFER_SIZE 0x8610 // 32 kB + 16 Byte + 1,5 kB (WRAP is enabled) -#define EDRV_RX_BUFFER_LENGTH (EDRV_RX_BUFFER_SIZE & 0xF800) // buffer size cut down to 2 kB alignment - -#define EDRV_TX_BUFFER_SIZE (EDRV_MAX_TX_BUFFERS * EDRV_MAX_FRAME_SIZE) // n * (MTU + 14 + 4) - -#define DRV_NAME "epl" - -#define EDRV_REGW_INT_MASK 0x3C // interrupt mask register -#define EDRV_REGW_INT_STATUS 0x3E // interrupt status register -#define EDRV_REGW_INT_ROK 0x0001 // Receive OK interrupt -#define EDRV_REGW_INT_RER 0x0002 // Receive error interrupt -#define EDRV_REGW_INT_TOK 0x0004 // Transmit OK interrupt -#define EDRV_REGW_INT_TER 0x0008 // Transmit error interrupt -#define EDRV_REGW_INT_RXOVW 0x0010 // Rx buffer overflow interrupt -#define EDRV_REGW_INT_PUN 0x0020 // Packet underrun/ link change interrupt -#define EDRV_REGW_INT_FOVW 0x0040 // Rx FIFO overflow interrupt -#define EDRV_REGW_INT_LENCHG 0x2000 // Cable length change interrupt -#define EDRV_REGW_INT_TIMEOUT 0x4000 // Time out interrupt -#define EDRV_REGW_INT_SERR 0x8000 // System error interrupt -#define EDRV_REGW_INT_MASK_DEF (EDRV_REGW_INT_ROK \ - | EDRV_REGW_INT_RER \ - | EDRV_REGW_INT_TOK \ - | EDRV_REGW_INT_TER \ - | EDRV_REGW_INT_RXOVW \ - | EDRV_REGW_INT_FOVW \ - | EDRV_REGW_INT_PUN \ - | EDRV_REGW_INT_TIMEOUT \ - | EDRV_REGW_INT_SERR) // default interrupt mask - -#define EDRV_REGB_COMMAND 0x37 // command register -#define EDRV_REGB_COMMAND_RST 0x10 -#define EDRV_REGB_COMMAND_RE 0x08 -#define EDRV_REGB_COMMAND_TE 0x04 -#define EDRV_REGB_COMMAND_BUFE 0x01 - -#define EDRV_REGB_CMD9346 0x50 // 93C46 command register -#define EDRV_REGB_CMD9346_LOCK 0x00 // lock configuration registers -#define EDRV_REGB_CMD9346_UNLOCK 0xC0 // unlock configuration registers - -#define EDRV_REGDW_RCR 0x44 // Rx configuration register -#define EDRV_REGDW_RCR_NO_FTH 0x0000E000 // no receive FIFO threshold -#define EDRV_REGDW_RCR_RBLEN32K 0x00001000 // 32 kB receive buffer -#define EDRV_REGDW_RCR_MXDMAUNL 0x00000700 // unlimited maximum DMA burst size -#define EDRV_REGDW_RCR_NOWRAP 0x00000080 // do not wrap frame at end of buffer -#define EDRV_REGDW_RCR_AER 0x00000020 // accept error frames (CRC, alignment, collided) -#define EDRV_REGDW_RCR_AR 0x00000010 // accept runt -#define EDRV_REGDW_RCR_AB 0x00000008 // accept broadcast frames -#define EDRV_REGDW_RCR_AM 0x00000004 // accept multicast frames -#define EDRV_REGDW_RCR_APM 0x00000002 // accept physical match frames -#define EDRV_REGDW_RCR_AAP 0x00000001 // accept all frames -#define EDRV_REGDW_RCR_DEF (EDRV_REGDW_RCR_NO_FTH \ - | EDRV_REGDW_RCR_RBLEN32K \ - | EDRV_REGDW_RCR_MXDMAUNL \ - | EDRV_REGDW_RCR_NOWRAP \ - | EDRV_REGDW_RCR_AB \ - | EDRV_REGDW_RCR_AM \ - | EDRV_REGDW_RCR_APM) // default value - -#define EDRV_REGDW_TCR 0x40 // Tx configuration register -#define EDRV_REGDW_TCR_VER_MASK 0x7CC00000 // mask for hardware version -#define EDRV_REGDW_TCR_VER_C 0x74000000 // RTL8139C -#define EDRV_REGDW_TCR_VER_D 0x74400000 // RTL8139D -#define EDRV_REGDW_TCR_IFG96 0x03000000 // default interframe gap (960 ns) -#define EDRV_REGDW_TCR_CRC 0x00010000 // disable appending of CRC by the controller -#define EDRV_REGDW_TCR_MXDMAUNL 0x00000700 // maximum DMA burst size of 2048 b -#define EDRV_REGDW_TCR_TXRETRY 0x00000000 // 16 retries -#define EDRV_REGDW_TCR_DEF (EDRV_REGDW_TCR_IFG96 \ - | EDRV_REGDW_TCR_MXDMAUNL \ - | EDRV_REGDW_TCR_TXRETRY) - -#define EDRV_REGW_MULINT 0x5C // multiple interrupt select register - -#define EDRV_REGDW_MPC 0x4C // missed packet counter register - -#define EDRV_REGDW_TSAD0 0x20 // Transmit start address of descriptor 0 -#define EDRV_REGDW_TSAD1 0x24 // Transmit start address of descriptor 1 -#define EDRV_REGDW_TSAD2 0x28 // Transmit start address of descriptor 2 -#define EDRV_REGDW_TSAD3 0x2C // Transmit start address of descriptor 3 -#define EDRV_REGDW_TSD0 0x10 // Transmit status of descriptor 0 -#define EDRV_REGDW_TSD_CRS 0x80000000 // Carrier sense lost -#define EDRV_REGDW_TSD_TABT 0x40000000 // Transmit Abort -#define EDRV_REGDW_TSD_OWC 0x20000000 // Out of window collision -#define EDRV_REGDW_TSD_TXTH_DEF 0x00020000 // Transmit FIFO threshold of 64 bytes -#define EDRV_REGDW_TSD_TOK 0x00008000 // Transmit OK -#define EDRV_REGDW_TSD_TUN 0x00004000 // Transmit FIFO underrun -#define EDRV_REGDW_TSD_OWN 0x00002000 // Owner - -#define EDRV_REGDW_RBSTART 0x30 // Receive buffer start address - -#define EDRV_REGW_CAPR 0x38 // Current address of packet read - -#define EDRV_REGDW_IDR0 0x00 // ID register 0 -#define EDRV_REGDW_IDR4 0x04 // ID register 4 - -#define EDRV_REGDW_MAR0 0x08 // Multicast address register 0 -#define EDRV_REGDW_MAR4 0x0C // Multicast address register 4 - -// defines for the status word in the receive buffer -#define EDRV_RXSTAT_MAR 0x8000 // Multicast address received -#define EDRV_RXSTAT_PAM 0x4000 // Physical address matched -#define EDRV_RXSTAT_BAR 0x2000 // Broadcast address received -#define EDRV_RXSTAT_ISE 0x0020 // Invalid symbol error -#define EDRV_RXSTAT_RUNT 0x0010 // Runt packet received -#define EDRV_RXSTAT_LONG 0x0008 // Long packet -#define EDRV_RXSTAT_CRC 0x0004 // CRC error -#define EDRV_RXSTAT_FAE 0x0002 // Frame alignment error -#define EDRV_RXSTAT_ROK 0x0001 // Receive OK - -#define EDRV_REGDW_WRITE(dwReg, dwVal) writel(dwVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGW_WRITE(dwReg, wVal) writew(wVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGB_WRITE(dwReg, bVal) writeb(bVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGDW_READ(dwReg) readl(EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGW_READ(dwReg) readw(EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGB_READ(dwReg) readb(EdrvInstance_l.m_pIoAddr + dwReg) - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif - -#define EDRV_COUNT_SEND TGT_DBG_SIGNAL_TRACE_POINT(2) -#define EDRV_COUNT_TIMEOUT TGT_DBG_SIGNAL_TRACE_POINT(3) -#define EDRV_COUNT_PCI_ERR TGT_DBG_SIGNAL_TRACE_POINT(4) -#define EDRV_COUNT_TX TGT_DBG_SIGNAL_TRACE_POINT(5) -#define EDRV_COUNT_RX TGT_DBG_SIGNAL_TRACE_POINT(6) -#define EDRV_COUNT_LATECOLLISION TGT_DBG_SIGNAL_TRACE_POINT(10) -#define EDRV_COUNT_TX_COL_RL TGT_DBG_SIGNAL_TRACE_POINT(11) -#define EDRV_COUNT_TX_FUN TGT_DBG_SIGNAL_TRACE_POINT(12) -#define EDRV_COUNT_TX_ERR TGT_DBG_SIGNAL_TRACE_POINT(13) -#define EDRV_COUNT_RX_CRC TGT_DBG_SIGNAL_TRACE_POINT(14) -#define EDRV_COUNT_RX_ERR TGT_DBG_SIGNAL_TRACE_POINT(15) -#define EDRV_COUNT_RX_FOVW TGT_DBG_SIGNAL_TRACE_POINT(16) -#define EDRV_COUNT_RX_PUN TGT_DBG_SIGNAL_TRACE_POINT(17) -#define EDRV_COUNT_RX_FAE TGT_DBG_SIGNAL_TRACE_POINT(18) -#define EDRV_COUNT_RX_OVW TGT_DBG_SIGNAL_TRACE_POINT(19) - -#define EDRV_TRACE_CAPR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x06000000) -#define EDRV_TRACE_RX_CRC(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0E000000) -#define EDRV_TRACE_RX_ERR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0F000000) -#define EDRV_TRACE_RX_PUN(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x11000000) -#define EDRV_TRACE(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF0000) | 0x0000FEC0) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- -/* -typedef struct -{ - BOOL m_fUsed; - unsigned int m_uiSize; - MCD_bufDescFec *m_pBufDescr; - -} tEdrvTxBufferIntern; -*/ - -// Private structure -typedef struct { - struct pci_dev *m_pPciDev; // pointer to PCI device structure - void *m_pIoAddr; // pointer to register space of Ethernet controller - u8 *m_pbRxBuf; // pointer to Rx buffer - dma_addr_t m_pRxBufDma; - u8 *m_pbTxBuf; // pointer to Tx buffer - dma_addr_t m_pTxBufDma; - BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS]; - unsigned int m_uiCurTxDesc; - - tEdrvInitParam m_InitParam; - tEdrvTxBuffer *m_pLastTransmittedTxBuffer; - -} tEdrvInstance; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static int EdrvInitOne(struct pci_dev *pPciDev, - const struct pci_device_id *pId); - -static void EdrvRemoveOne(struct pci_dev *pPciDev); - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -// buffers and buffer descriptors and pointers - -static struct pci_device_id aEdrvPciTbl[] = { - {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, aEdrvPciTbl); - -static tEdrvInstance EdrvInstance_l; - -static struct pci_driver EdrvDriver = { - .name = DRV_NAME, - .id_table = aEdrvPciTbl, - .probe = EdrvInitOne, - .remove = EdrvRemoveOne, -}; - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static u8 EdrvCalcHash(u8 * pbMAC_p); - -//--------------------------------------------------------------------------- -// -// Function: EdrvInit -// -// Description: function for init of the Ethernet controller -// -// Parameters: pEdrvInitParam_p = pointer to struct including the init-parameters -// -// Returns: Errorcode = kEplSuccessful -// = kEplNoResource -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p) -{ - tEplKernel Ret; - int iResult; - - Ret = kEplSuccessful; - - // clear instance structure - EPL_MEMSET(&EdrvInstance_l, 0, sizeof(EdrvInstance_l)); - - // save the init data - EdrvInstance_l.m_InitParam = *pEdrvInitParam_p; - - // register PCI driver - iResult = pci_register_driver(&EdrvDriver); - if (iResult != 0) { - printk("%s pci_register_driver failed with %d\n", __func__, - iResult); - Ret = kEplNoResource; - goto Exit; - } - - if (EdrvInstance_l.m_pPciDev == NULL) { - printk("%s m_pPciDev=NULL\n", __func__); - Ret = kEplNoResource; - goto Exit; - } - // read MAC address from controller - printk("%s local MAC = ", __func__); - for (iResult = 0; iResult < 6; iResult++) { - pEdrvInitParam_p->m_abMyMacAddr[iResult] = - EDRV_REGB_READ((EDRV_REGDW_IDR0 + iResult)); - printk("%02X ", - (unsigned int)pEdrvInitParam_p->m_abMyMacAddr[iResult]); - } - printk("\n"); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvShutdown -// -// Description: Shutdown the Ethernet controller -// -// Parameters: void -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvShutdown(void) -{ - - // unregister PCI driver - printk("%s calling pci_unregister_driver()\n", __func__); - pci_unregister_driver(&EdrvDriver); - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvDefineRxMacAddrEntry -// -// Description: Set a multicast entry into the Ethernet controller -// -// Parameters: pbMacAddr_p = pointer to multicast entry to set -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 dwData; - u8 bHash; - - bHash = EdrvCalcHash(pbMacAddr_p); -/* - dwData = ether_crc(6, pbMacAddr_p); - - printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u ether_crc = 0x%08lX\n", - (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2], - (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5], - (u16) bHash, (u16) (dwData >> 26), dwData); -*/ - if (bHash > 31) { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - dwData |= 1 << (bHash - 32); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData); - } else { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - dwData |= 1 << bHash; - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvUndefineRxMacAddrEntry -// -// Description: Reset a multicast entry in the Ethernet controller -// -// Parameters: pbMacAddr_p = pointer to multicast entry to reset -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 dwData; - u8 bHash; - - bHash = EdrvCalcHash(pbMacAddr_p); - - if (bHash > 31) { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - dwData &= ~(1 << (bHash - 32)); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData); - } else { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - dwData &= ~(1 << bHash); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvAllocTxMsgBuffer -// -// Description: Register a Tx-Buffer -// -// Parameters: pBuffer_p = pointer to Buffer structure -// -// Returns: Errorcode = kEplSuccessful -// = kEplEdrvNoFreeBufEntry -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 i; - - if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - // search a free Tx buffer with appropriate size - for (i = 0; i < EDRV_MAX_TX_BUFFERS; i++) { - if (EdrvInstance_l.m_afTxBufUsed[i] == FALSE) { - // free channel found - EdrvInstance_l.m_afTxBufUsed[i] = TRUE; - pBuffer_p->m_uiBufferNumber = i; - pBuffer_p->m_pbBuffer = - EdrvInstance_l.m_pbTxBuf + - (i * EDRV_MAX_FRAME_SIZE); - pBuffer_p->m_uiMaxBufferLen = EDRV_MAX_FRAME_SIZE; - break; - } - } - if (i >= EDRV_MAX_TX_BUFFERS) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvReleaseTxMsgBuffer -// -// Description: Register a Tx-Buffer -// -// Parameters: pBuffer_p = pointer to Buffer structure -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p) -{ - unsigned int uiBufferNumber; - - uiBufferNumber = pBuffer_p->m_uiBufferNumber; - - if (uiBufferNumber < EDRV_MAX_TX_BUFFERS) { - EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] = FALSE; - } - - return kEplSuccessful; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvSendTxMsg -// -// Description: immediately starts the transmission of the buffer -// -// Parameters: pBuffer_p = buffer descriptor to transmit -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiBufferNumber; - u32 dwTemp; - - uiBufferNumber = pBuffer_p->m_uiBufferNumber; - - if ((uiBufferNumber >= EDRV_MAX_TX_BUFFERS) - || (EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] == FALSE)) { - Ret = kEplEdrvBufNotExisting; - goto Exit; - } - - if (EdrvInstance_l.m_pLastTransmittedTxBuffer != NULL) { // transmission is already active - Ret = kEplInvalidOperation; - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * - sizeof(u32)))); - printk("%s InvOp TSD%u = 0x%08X", __func__, - EdrvInstance_l.m_uiCurTxDesc, dwTemp); - printk(" Cmd = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - goto Exit; - } - // save pointer to buffer structure for TxHandler - EdrvInstance_l.m_pLastTransmittedTxBuffer = pBuffer_p; - - EDRV_COUNT_SEND; - - // pad with zeros if necessary, because controller does not do it - if (pBuffer_p->m_uiTxMsgLen < MIN_ETH_SIZE) { - EPL_MEMSET(pBuffer_p->m_pbBuffer + pBuffer_p->m_uiTxMsgLen, 0, - MIN_ETH_SIZE - pBuffer_p->m_uiTxMsgLen); - pBuffer_p->m_uiTxMsgLen = MIN_ETH_SIZE; - } - // set DMA address of buffer - EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))), - (EdrvInstance_l.m_pTxBufDma + - (uiBufferNumber * EDRV_MAX_FRAME_SIZE))); - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSAD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32)))); -// printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp); - - // start transmission - EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))), - (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen)); - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32)))); -// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen)); - - Exit: - return Ret; -} - -#if 0 -//--------------------------------------------------------------------------- -// -// Function: EdrvTxMsgReady -// -// Description: starts copying the buffer to the ethernet controller's FIFO -// -// Parameters: pbBuffer_p - bufferdescriptor to transmit -// -// Returns: Errorcode - kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiBufferNumber; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvTxMsgStart -// -// Description: starts transmission of the ethernet controller's FIFO -// -// Parameters: pbBuffer_p - bufferdescriptor to transmit -// -// Returns: Errorcode - kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EdrvReinitRx -// -// Description: reinitialize the Rx process, because of error -// -// Parameters: void -// -// Returns: void -// -// State: -// -//--------------------------------------------------------------------------- -static void EdrvReinitRx(void) -{ - u8 bCmd; - - // simply switch off and on the receiver - // this will reset the CAPR register - bCmd = EDRV_REGB_READ(EDRV_REGB_COMMAND); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (bCmd & ~EDRV_REGB_COMMAND_RE)); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, bCmd); - - // set receive configuration register - EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF); -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvInterruptHandler -// -// Description: interrupt handler -// -// Parameters: void -// -// Returns: void -// -// State: -// -//--------------------------------------------------------------------------- -#if 0 -void EdrvInterruptHandler(void) -{ -} -#endif - -static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p) -{ -// EdrvInterruptHandler(); - tEdrvRxBuffer RxBuffer; - tEdrvTxBuffer *pTxBuffer; - u16 wStatus; - u32 dwTxStatus; - u32 dwRxStatus; - u16 wCurRx; - u8 *pbRxBuf; - unsigned int uiLength; - int iHandled = IRQ_HANDLED; - -// printk("¤"); - - // read the interrupt status - wStatus = EDRV_REGW_READ(EDRV_REGW_INT_STATUS); - - // acknowledge the interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, wStatus); - - if (wStatus == 0) { - iHandled = IRQ_NONE; - goto Exit; - } - // process tasks - if ((wStatus & (EDRV_REGW_INT_TER | EDRV_REGW_INT_TOK)) != 0) { // transmit interrupt - - if (EdrvInstance_l.m_pbTxBuf == NULL) { - printk("%s Tx buffers currently not allocated\n", - __func__); - goto Exit; - } - // read transmit status - dwTxStatus = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * - sizeof(u32)))); - if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) { // transmit finished - EdrvInstance_l.m_uiCurTxDesc = - (EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03; - pTxBuffer = EdrvInstance_l.m_pLastTransmittedTxBuffer; - EdrvInstance_l.m_pLastTransmittedTxBuffer = NULL; - - if ((dwTxStatus & EDRV_REGDW_TSD_TOK) != 0) { - EDRV_COUNT_TX; - } else if ((dwTxStatus & EDRV_REGDW_TSD_TUN) != 0) { - EDRV_COUNT_TX_FUN; - } else { // assume EDRV_REGDW_TSD_TABT - EDRV_COUNT_TX_COL_RL; - } - -// printk("T"); - if (pTxBuffer != NULL) { - // call Tx handler of Data link layer - EdrvInstance_l.m_InitParam. - m_pfnTxHandler(pTxBuffer); - } - } else { - EDRV_COUNT_TX_ERR; - } - } - - if ((wStatus & (EDRV_REGW_INT_RER | EDRV_REGW_INT_FOVW | EDRV_REGW_INT_RXOVW | EDRV_REGW_INT_PUN)) != 0) { // receive error interrupt - - if ((wStatus & EDRV_REGW_INT_FOVW) != 0) { - EDRV_COUNT_RX_FOVW; - } else if ((wStatus & EDRV_REGW_INT_RXOVW) != 0) { - EDRV_COUNT_RX_OVW; - } else if ((wStatus & EDRV_REGW_INT_PUN) != 0) { // Packet underrun - EDRV_TRACE_RX_PUN(wStatus); - EDRV_COUNT_RX_PUN; - } else { /*if ((wStatus & EDRV_REGW_INT_RER) != 0) */ - - EDRV_TRACE_RX_ERR(wStatus); - EDRV_COUNT_RX_ERR; - } - - // reinitialize Rx process - EdrvReinitRx(); - } - - if ((wStatus & EDRV_REGW_INT_ROK) != 0) { // receive interrupt - - if (EdrvInstance_l.m_pbRxBuf == NULL) { - printk("%s Rx buffers currently not allocated\n", - __func__); - goto Exit; - } - // read current offset in receive buffer - wCurRx = - (EDRV_REGW_READ(EDRV_REGW_CAPR) + - 0x10) % EDRV_RX_BUFFER_LENGTH; - - while ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_BUFE) == 0) { // frame available - - // calculate pointer to current frame in receive buffer - pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx; - - // read receive status u32 - dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf)); - - // calculate length of received frame - uiLength = dwRxStatus >> 16; - - if (uiLength == 0xFFF0) { // frame is unfinished (maybe early Rx interrupt is active) - break; - } - - if ((dwRxStatus & EDRV_RXSTAT_ROK) == 0) { // error occured while receiving this frame - // ignore it - if ((dwRxStatus & EDRV_RXSTAT_FAE) != 0) { - EDRV_COUNT_RX_FAE; - } else if ((dwRxStatus & EDRV_RXSTAT_CRC) != 0) { - EDRV_TRACE_RX_CRC(dwRxStatus); - EDRV_COUNT_RX_CRC; - } else { - EDRV_TRACE_RX_ERR(dwRxStatus); - EDRV_COUNT_RX_ERR; - } - - // reinitialize Rx process - EdrvReinitRx(); - - break; - } else { // frame is OK - RxBuffer.m_BufferInFrame = - kEdrvBufferLastInFrame; - RxBuffer.m_uiRxMsgLen = uiLength - ETH_CRC_SIZE; - RxBuffer.m_pbBuffer = - pbRxBuf + sizeof(dwRxStatus); - -// printk("R"); - EDRV_COUNT_RX; - - // call Rx handler of Data link layer - EdrvInstance_l.m_InitParam. - m_pfnRxHandler(&RxBuffer); - } - - // calulate new offset (u32 aligned) - wCurRx = - (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) + - 3) & ~0x3); - EDRV_TRACE_CAPR(wCurRx - 0x10); - EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10); - - // reread current offset in receive buffer - wCurRx = - (EDRV_REGW_READ(EDRV_REGW_CAPR) + - 0x10) % EDRV_RX_BUFFER_LENGTH; - - } - } - - if ((wStatus & EDRV_REGW_INT_SERR) != 0) { // PCI error - EDRV_COUNT_PCI_ERR; - } - - if ((wStatus & EDRV_REGW_INT_TIMEOUT) != 0) { // Timeout - EDRV_COUNT_TIMEOUT; - } - - Exit: - return iHandled; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvInitOne -// -// Description: initializes one PCI device -// -// Parameters: pPciDev = pointer to corresponding PCI device structure -// pId = PCI device ID -// -// Returns: (int) = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId) -{ - int iResult = 0; - u32 dwTemp; - - if (EdrvInstance_l.m_pPciDev != NULL) { // Edrv is already connected to a PCI device - printk("%s device %s discarded\n", __func__, - pci_name(pPciDev)); - iResult = -ENODEV; - goto Exit; - } - - if (pPciDev->revision >= 0x20) { - printk - ("%s device %s is an enhanced 8139C+ version, which is not supported\n", - __func__, pci_name(pPciDev)); - iResult = -ENODEV; - goto Exit; - } - - EdrvInstance_l.m_pPciDev = pPciDev; - - // enable device - printk("%s enable device\n", __func__); - iResult = pci_enable_device(pPciDev); - if (iResult != 0) { - goto Exit; - } - - if ((pci_resource_flags(pPciDev, 1) & IORESOURCE_MEM) == 0) { - iResult = -ENODEV; - goto Exit; - } - - printk("%s request regions\n", __func__); - iResult = pci_request_regions(pPciDev, DRV_NAME); - if (iResult != 0) { - goto Exit; - } - - printk("%s ioremap\n", __func__); - EdrvInstance_l.m_pIoAddr = - ioremap(pci_resource_start(pPciDev, 1), - pci_resource_len(pPciDev, 1)); - if (EdrvInstance_l.m_pIoAddr == NULL) { // remap of controller's register space failed - iResult = -EIO; - goto Exit; - } - // enable PCI busmaster - printk("%s enable busmaster\n", __func__); - pci_set_master(pPciDev); - - // reset controller - printk("%s reset controller\n", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, EDRV_REGB_COMMAND_RST); - - // wait until reset has finished - for (iResult = 500; iResult > 0; iResult--) { - if ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_RST) - == 0) { - break; - } - - schedule_timeout(10); - } - - // check hardware version, i.e. chip ID - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR); - if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C) - && ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) { // unsupported chip - printk("%s Unsupported chip! TCR = 0x%08X\n", __func__, - dwTemp); - iResult = -ENODEV; - goto Exit; - } - // disable interrupts - printk("%s disable interrupts\n", __func__); - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0); - // acknowledge all pending interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, - EDRV_REGW_READ(EDRV_REGW_INT_STATUS)); - - // install interrupt handler - printk("%s install interrupt handler\n", __func__); - iResult = - request_irq(pPciDev->irq, TgtEthIsr, IRQF_SHARED, - DRV_NAME /*pPciDev->dev.name */ , pPciDev); - if (iResult != 0) { - goto Exit; - } - -/* - // unlock configuration registers - printk("%s unlock configuration registers\n", __func__); - EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_UNLOCK); - - // check if user specified a MAC address - printk("%s check specified MAC address\n", __func__); - for (iResult = 0; iResult < 6; iResult++) - { - if (EdrvInstance_l.m_InitParam.m_abMyMacAddr[iResult] != 0) - { - printk("%s set local MAC address\n", __func__); - // write this MAC address to controller - EDRV_REGDW_WRITE(EDRV_REGDW_IDR0, - le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0]))); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0); - - EDRV_REGDW_WRITE(EDRV_REGDW_IDR4, - le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4]))); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4); - break; - } - } - iResult = 0; - - // lock configuration registers - EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_LOCK); -*/ - - // allocate buffers - printk("%s allocate buffers\n", __func__); - EdrvInstance_l.m_pbTxBuf = - pci_alloc_consistent(pPciDev, EDRV_TX_BUFFER_SIZE, - &EdrvInstance_l.m_pTxBufDma); - if (EdrvInstance_l.m_pbTxBuf == NULL) { - iResult = -ENOMEM; - goto Exit; - } - - EdrvInstance_l.m_pbRxBuf = - pci_alloc_consistent(pPciDev, EDRV_RX_BUFFER_SIZE, - &EdrvInstance_l.m_pRxBufDma); - if (EdrvInstance_l.m_pbRxBuf == NULL) { - iResult = -ENOMEM; - goto Exit; - } - // reset pointers for Tx buffers - printk("%s reset pointers fo Tx buffers\n", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD0, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD0); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD1, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD1); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD2, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD2); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD3, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3); - - printk(" Command = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - - // set pointer for receive buffer in controller - printk("%s set pointer to Rx buffer\n", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_RBSTART, EdrvInstance_l.m_pRxBufDma); - - // enable transmitter and receiver - printk("%s enable Tx and Rx", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, - (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE)); - printk(" Command = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - - // clear missed packet counter to enable Rx/Tx process - EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0); - - // set transmit configuration register - printk("%s set Tx conf register", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_TCR, EDRV_REGDW_TCR_DEF); - printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_TCR)); - - // set receive configuration register - printk("%s set Rx conf register", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF); - printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_RCR)); - - // reset multicast MAC address filter - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - -/* - // enable transmitter and receiver - printk("%s enable Tx and Rx", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE)); - printk(" Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); -*/ - // disable early interrupts - EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0); - - // enable interrupts - printk("%s enable interrupts\n", __func__); - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, EDRV_REGW_INT_MASK_DEF); - - Exit: - printk("%s finished with %d\n", __func__, iResult); - return iResult; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvRemoveOne -// -// Description: shuts down one PCI device -// -// Parameters: pPciDev = pointer to corresponding PCI device structure -// -// Returns: (void) -// -// State: -// -//--------------------------------------------------------------------------- - -static void EdrvRemoveOne(struct pci_dev *pPciDev) -{ - - if (EdrvInstance_l.m_pPciDev != pPciDev) { // trying to remove unknown device - BUG_ON(EdrvInstance_l.m_pPciDev != pPciDev); - goto Exit; - } - // disable transmitter and receiver - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, 0); - - // disable interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0); - - // remove interrupt handler - free_irq(pPciDev->irq, pPciDev); - - // free buffers - if (EdrvInstance_l.m_pbTxBuf != NULL) { - pci_free_consistent(pPciDev, EDRV_TX_BUFFER_SIZE, - EdrvInstance_l.m_pbTxBuf, - EdrvInstance_l.m_pTxBufDma); - EdrvInstance_l.m_pbTxBuf = NULL; - } - - if (EdrvInstance_l.m_pbRxBuf != NULL) { - pci_free_consistent(pPciDev, EDRV_RX_BUFFER_SIZE, - EdrvInstance_l.m_pbRxBuf, - EdrvInstance_l.m_pRxBufDma); - EdrvInstance_l.m_pbRxBuf = NULL; - } - // unmap controller's register space - if (EdrvInstance_l.m_pIoAddr != NULL) { - iounmap(EdrvInstance_l.m_pIoAddr); - } - // disable the PCI device - pci_disable_device(pPciDev); - - // release memory regions - pci_release_regions(pPciDev); - - EdrvInstance_l.m_pPciDev = NULL; - - Exit:; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvCalcHash -// -// Description: function calculates the entry for the hash-table from MAC -// address -// -// Parameters: pbMAC_p - pointer to MAC address -// -// Returns: hash value -// -// State: -// -//--------------------------------------------------------------------------- -#define HASH_BITS 6 // used bits in hash -#define CRC32_POLY 0x04C11DB6 // -//#define CRC32_POLY 0xEDB88320 // -// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 - -static u8 EdrvCalcHash(u8 * pbMAC_p) -{ - u32 dwByteCounter; - u32 dwBitCounter; - u32 dwData; - u32 dwCrc; - u32 dwCarry; - u8 *pbData; - u8 bHash; - - pbData = pbMAC_p; - - // calculate crc32 value of mac address - dwCrc = 0xFFFFFFFF; - - for (dwByteCounter = 0; dwByteCounter < 6; dwByteCounter++) { - dwData = *pbData; - pbData++; - for (dwBitCounter = 0; dwBitCounter < 8; - dwBitCounter++, dwData >>= 1) { - dwCarry = (((dwCrc >> 31) ^ dwData) & 1); - dwCrc = dwCrc << 1; - if (dwCarry != 0) { - dwCrc = (dwCrc ^ CRC32_POLY) | dwCarry; - } - } - } - -// printk("MyCRC = 0x%08lX\n", dwCrc); - // only upper 6 bits (HASH_BITS) are used - // which point to specific bit in the hash registers - bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f); - - return bHash; -} diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h deleted file mode 100644 index 56728d1e95e..00000000000 --- a/drivers/staging/epl/EdrvFec.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: interface for ethernetdriver - "fast ethernet controller" (FEC) - freescale coldfire MCF528x and compatible FEC - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EdrvFec.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2005/08/01 m.b.: start of implementation - -****************************************************************************/ - -#ifndef _EDRVFEC_H_ -#define _EDRVFEC_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- -// do this in config header -#define TARGET_HARDWARE TGTHW_SPLC_CF54 - -// base addresses -#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282) - -#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485) - -#else - -#error 'ERROR: Target was never implemented!' - -#endif - -//--------------------------------------------------------------------------- -// types -//--------------------------------------------------------------------------- - -// Rx and Tx buffer descriptor format -typedef struct { - u16 m_wStatus; // control / status --- used by edrv, do not change in application - u16 m_wLength; // transfer length - u8 *m_pbData; // buffer address -} tBufferDescr; - -#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282) - -#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485) - -#endif - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EDRV_FEC_H_ diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h deleted file mode 100644 index 191ec1457d2..00000000000 --- a/drivers/staging/epl/EdrvSim.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: interface for ethernet driver simulation - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EdrvSim.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/15 d.k.: start of implementation - -****************************************************************************/ - -#ifndef _EDRVSIM_H_ -#define _EDRVSIM_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -void EdrvRxInterruptHandler(u8 bBufferInFrame_p, u8 * pbEthernetData_p, - u16 wDataLen_p); - -#endif // #ifndef _EDRVSIM_H_ diff --git a/drivers/staging/epl/Epl.h b/drivers/staging/epl/Epl.h deleted file mode 100644 index 7f22b04022b..00000000000 --- a/drivers/staging/epl/Epl.h +++ /dev/null @@ -1,272 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL API layer - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: Epl.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_API_H_ -#define _EPL_API_H_ - -#include "EplInc.h" -#include "EplSdo.h" -#include "EplObd.h" -#include "EplLed.h" -#include "EplEvent.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct { - unsigned int m_uiNodeId; - tEplNmtState m_NmtState; - tEplNmtNodeEvent m_NodeEvent; - u16 m_wErrorCode; // EPL error code if m_NodeEvent == kEplNmtNodeEventError - BOOL m_fMandatory; - -} tEplApiEventNode; - -typedef struct { - tEplNmtState m_NmtState; // local NMT state - tEplNmtBootEvent m_BootEvent; - u16 m_wErrorCode; // EPL error code if m_BootEvent == kEplNmtBootEventError - -} tEplApiEventBoot; - -typedef struct { - tEplLedType m_LedType; // type of the LED (e.g. Status or Error) - BOOL m_fOn; // state of the LED (e.g. on or off) - -} tEplApiEventLed; - -typedef enum { - kEplApiEventNmtStateChange = 0x10, // m_NmtStateChange -// kEplApiEventRequestNmt = 0x11, // m_bNmtCmd - kEplApiEventCriticalError = 0x12, // m_InternalError, Stack halted - kEplApiEventWarning = 0x13, // m_InternalError, Stack running - kEplApiEventNode = 0x20, // m_Node - kEplApiEventBoot = 0x21, // m_Boot - kEplApiEventSdo = 0x62, // m_Sdo - kEplApiEventObdAccess = 0x69, // m_ObdCbParam - kEplApiEventLed = 0x70, // m_Led - -} tEplApiEventType; - -typedef union { - tEplEventNmtStateChange m_NmtStateChange; - tEplEventError m_InternalError; - tEplSdoComFinished m_Sdo; - tEplObdCbParam m_ObdCbParam; - tEplApiEventNode m_Node; - tEplApiEventBoot m_Boot; - tEplApiEventLed m_Led; - -} tEplApiEventArg; - -typedef tEplKernel(*tEplApiCbEvent) (tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p); - -typedef struct { - unsigned int m_uiSizeOfStruct; - BOOL m_fAsyncOnly; // do not need to register PRes - unsigned int m_uiNodeId; // local node ID - u8 m_abMacAddress[6]; // local MAC address - - // 0x1F82: NMT_FeatureFlags_U32 - u32 m_dwFeatureFlags; - // Cycle Length (0x1006: NMT_CycleLen_U32) in [us] - u32 m_dwCycleLen; // required for error detection - // 0x1F98: NMT_CycleTiming_REC - // 0x1F98.1: IsochrTxMaxPayload_U16 - unsigned int m_uiIsochrTxMaxPayload; // const - // 0x1F98.2: IsochrRxMaxPayload_U16 - unsigned int m_uiIsochrRxMaxPayload; // const - // 0x1F98.3: PResMaxLatency_U32 - u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes - // 0x1F98.4: PReqActPayloadLimit_U16 - unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+28 bytes) - // 0x1F98.5: PResActPayloadLimit_U16 - unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+28 bytes) - // 0x1F98.6: ASndMaxLatency_U32 - u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes - // 0x1F98.7: MultiplCycleCnt_U8 - unsigned int m_uiMultiplCycleCnt; // required for error detection - // 0x1F98.8: AsyncMTU_U16 - unsigned int m_uiAsyncMtu; // required to set up max frame size - // 0x1F98.9: Prescaler_U16 - unsigned int m_uiPrescaler; // required for sync - // $$$ Multiplexed Slot - - // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns] - u32 m_dwLossOfFrameTolerance; - - // 0x1F8A: NMT_MNCycleTiming_REC - // 0x1F8A.1: WaitSoCPReq_U32 in [ns] - u32 m_dwWaitSocPreq; - - // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] - u32 m_dwAsyncSlotTimeout; - - u32 m_dwDeviceType; // NMT_DeviceType_U32 - u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32 - u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32 - u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32 - u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32 - u64 m_qwVendorSpecificExt1; - u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32 - u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32 - u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_dwIpAddress; - u32 m_dwSubnetMask; - u32 m_dwDefaultGateway; - u8 m_sHostname[32]; - u8 m_abVendorSpecificExt2[48]; - - char *m_pszDevName; // NMT_ManufactDevName_VS (0x1008/0 local OD) - char *m_pszHwVersion; // NMT_ManufactHwVers_VS (0x1009/0 local OD) - char *m_pszSwVersion; // NMT_ManufactSwVers_VS (0x100A/0 local OD) - - tEplApiCbEvent m_pfnCbEvent; - void *m_pEventUserArg; - tEplSyncCb m_pfnCbSync; - -} tEplApiInitParam; - -typedef struct { - void *m_pImage; - unsigned int m_uiSize; - -} tEplApiProcessImage; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p); - -tEplKernel EplApiShutdown(void); - -tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiNodeId_p, - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pDstData_le_p, - unsigned int *puiSize_p, - tEplSdoType SdoType_p, void *pUserArg_p); - -tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiNodeId_p, - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pSrcData_le_p, - unsigned int uiSize_p, - tEplSdoType SdoType_p, void *pUserArg_p); - -tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p); - -tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pDstData_p, - unsigned int *puiSize_p); - -tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pSrcData_p, - unsigned int uiSize_p); - -tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p); - -tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p, - void *pVar_p, - unsigned int *puiVarEntries_p, - tEplObdSize *pEntrySize_p, - unsigned int uiFirstSubindex_p); - -tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p); - -tEplKernel EplApiProcess(void); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p, - tEplNmtNodeCommand NodeCommand_p); -#endif - -tEplKernel EplApiGetIdentResponse(unsigned int uiNodeId_p, - tEplIdentResponse **ppIdentResponse_p); - -// functions for process image will be implemented in separate file -tEplKernel EplApiProcessImageSetup(void); -tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p); -tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p); - -#endif // #ifndef _EPL_API_H_ diff --git a/drivers/staging/epl/EplAmi.h b/drivers/staging/epl/EplAmi.h deleted file mode 100644 index 3b46ea11442..00000000000 --- a/drivers/staging/epl/EplAmi.h +++ /dev/null @@ -1,323 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Definitions for Abstract Memory Interface - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplAmi.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.2 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC - - ------------------------------------------------------------------------- - - Revision History: - - 06.03.2000 -rs - Implementation - - 16.09.2002 -as - To save code space the functions AmiSetByte and AmiGetByte - are replaced by macros. For targets which assign u8 by - an 16Bit type, the definition of macros must changed to - functions. - - 23.02.2005 r.d.: - Functions included for extended data types such as UNSIGNED24, - UNSIGNED40, ... - - 13.06.2006 d.k.: - Extended the interface for EPL with the different functions - for little endian and big endian - -****************************************************************************/ - -#ifndef _EPLAMI_H_ -#define _EPLAMI_H_ - - -//--------------------------------------------------------------------------- -// types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Prototypen -//--------------------------------------------------------------------------- - -#ifdef __cplusplus -extern "C" { -#endif - -//--------------------------------------------------------------------------- -// -// write functions -// -// To save code space the function AmiSetByte is replaced by -// an macro. -// void AmiSetByte (void * pAddr_p, u8 bByteVal_p); - -#define AmiSetByteToBe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);} -#define AmiSetByteToLe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);} - -void AmiSetWordToBe(void *pAddr_p, u16 wWordVal_p); -void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p); -void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p); -void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p); - -//--------------------------------------------------------------------------- -// -// read functions -// -// To save code space the function AmiGetByte is replaced by -// an macro. -// u8 AmiGetByte (void * pAddr_p); - -#define AmiGetByteFromBe(pAddr_p) (*(u8 *)(pAddr_p)) -#define AmiGetByteFromLe(pAddr_p) (*(u8 *)(pAddr_p)) - -u16 AmiGetWordFromBe(void *pAddr_p); -u32 AmiGetDwordFromBe(void *pAddr_p); -u16 AmiGetWordFromLe(void *pAddr_p); -u32 AmiGetDwordFromLe(void *pAddr_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiSetDword24() -// -// Description: sets a 24 bit value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// dwDwordVal_p = value to set -// -// Return: void -// -//--------------------------------------------------------------------------- - -void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p); -void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetDword24() -// -// Description: reads a 24 bit value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u32 = read value -// -//--------------------------------------------------------------------------- - -u32 AmiGetDword24FromBe(void *pAddr_p); -u32 AmiGetDword24FromLe(void *pAddr_p); - -//#ifdef USE_VAR64 - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword40() -// -// Description: sets a 40 bit value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -//--------------------------------------------------------------------------- - -void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p); -void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword40() -// -// Description: reads a 40 bit value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword40FromBe(void *pAddr_p); -u64 AmiGetQword40FromLe(void *pAddr_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword48() -// -// Description: sets a 48 bit value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -//--------------------------------------------------------------------------- - -void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p); -void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword48() -// -// Description: reads a 48 bit value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword48FromBe(void *pAddr_p); -u64 AmiGetQword48FromLe(void *pAddr_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword56() -// -// Description: sets a 56 bit value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -//--------------------------------------------------------------------------- - -void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p); -void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword56() -// -// Description: reads a 56 bit value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword56FromBe(void *pAddr_p); -u64 AmiGetQword56FromLe(void *pAddr_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword64() -// -// Description: sets a 64 bit value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -//--------------------------------------------------------------------------- - -void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p); -void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword64() -// -// Description: reads a 64 bit value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: void -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword64FromBe(void *pAddr_p); -u64 AmiGetQword64FromLe(void *pAddr_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiSetTimeOfDay() -// -// Description: sets a TIME_OF_DAY (CANopen) value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// pTimeOfDay_p = pointer to struct TIME_OF_DAY -// -// Return: void -// -//--------------------------------------------------------------------------- -void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p); - -//--------------------------------------------------------------------------- -// -// Function: AmiGetTimeOfDay() -// -// Description: reads a TIME_OF_DAY (CANopen) value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// pTimeOfDay_p = pointer to struct TIME_OF_DAY -// -// Return: void -// -//--------------------------------------------------------------------------- -void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p); - -#ifdef __cplusplus -} -#endif -#endif // ifndef _EPLAMI_H_ -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c deleted file mode 100644 index c4419569183..00000000000 --- a/drivers/staging/epl/EplApiGeneric.c +++ /dev/null @@ -1,2054 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for generic EPL API module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplApiGeneric.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.21 $ $Date: 2008/11/21 09:00:38 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/09/05 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "Epl.h" -#include "kernel/EplDllk.h" -#include "kernel/EplErrorHandlerk.h" -#include "kernel/EplEventk.h" -#include "kernel/EplNmtk.h" -#include "kernel/EplObdk.h" -#include "kernel/EplTimerk.h" -#include "kernel/EplDllkCal.h" -#include "kernel/EplPdokCal.h" -#include "user/EplDlluCal.h" -#include "user/EplLedu.h" -#include "user/EplNmtCnu.h" -#include "user/EplNmtMnu.h" -#include "user/EplSdoComu.h" -#include "user/EplIdentu.h" -#include "user/EplStatusu.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -#include "kernel/EplPdok.h" -#endif - -#include "SharedBuff.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0) -#error "EPL API layer needs EPL module OBDK!" -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplApi */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - tEplApiInitParam m_InitParam; - -} tEplApiInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplApiInstance EplApiInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -// NMT state change event callback function -static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p); - -// update DLL configuration from OD -static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p); - -// update OD from init param -static tEplKernel EplApiUpdateObd(void); - -// process events from user event queue -static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -// callback function of SDO module -static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -// callback functions of NmtMnu module -static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p, - tEplNmtNodeEvent NodeEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p, BOOL fMandatory_p); - -static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) -// callback function of Ledu module -static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p); -#endif - -// OD initialization function (implemented in Objdict.c) -tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplApiInitialize() -// -// Description: add and initialize new instance of EPL stack. -// After return from this function the application must start -// the NMT state machine via -// EplApiExecNmtCommand(kEplNmtEventSwReset) -// and thereby the whole EPL stack :-) -// -// Parameters: pInitParam_p = initialisation parameters -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplObdInitParam ObdInitParam; - tEplDllkInitParam DllkInitParam; -#ifndef EPL_NO_FIFO - tShbError ShbError; -#endif - - // reset instance structure - EPL_MEMSET(&EplApiInstance_g, 0, sizeof(EplApiInstance_g)); - - EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p, - min(sizeof(tEplApiInitParam), - pInitParam_p->m_uiSizeOfStruct)); - - // check event callback function pointer - if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) { // application must always have an event callback function - Ret = kEplApiInvalidParam; - goto Exit; - } -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - // init OD -// FIXME -// Ret = EplObdInitRam(&ObdInitParam); -// if (Ret != kEplSuccessful) -// { -// goto Exit; -// } - - // initialize EplObd module - Ret = EplObdInit(&ObdInitParam); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - -#ifndef EPL_NO_FIFO - ShbError = ShbInit(); - if (ShbError != kShbOk) { - Ret = kEplNoResource; - goto Exit; - } -#endif - - // initialize EplEventk module - Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplEventu module - Ret = EplEventuInit(EplApiProcessEvent); - if (Ret != kEplSuccessful) { - goto Exit; - } - // init EplTimerk module - Ret = EplTimerkInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplNmtk module before DLL -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - Ret = EplNmtkInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplDllk module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - EPL_MEMCPY(DllkInitParam.m_be_abSrcMac, - EplApiInstance_g.m_InitParam.m_abMacAddress, 6); - Ret = EplDllkAddInstance(&DllkInitParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplErrorHandlerk module - Ret = EplErrorHandlerkInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplDllkCal module - Ret = EplDllkCalAddInstance(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplDlluCal module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalAddInstance(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplPdok module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - Ret = EplPdokAddInstance(); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = EplPdokCalAddInstance(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplNmtCnu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplNmtu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = EplNmtuInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } - // register NMT event callback function - Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // initialize EplNmtMnu module - Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplIdentu module - Ret = EplIdentuInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } - // initialize EplStatusu module - Ret = EplStatusuInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // initialize EplLedu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - Ret = EplLeduInit(EplApiCbLedStateChange); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // init SDO module -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \ - (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)) - // init sdo command layer - Ret = EplSdoComInit(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // the application must start NMT state machine - // via EplApiExecNmtCommand(kEplNmtEventSwReset) - // and thereby the whole EPL stack - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiShutdown() -// -// Description: deletes an instance of EPL stack -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplApiShutdown(void) -{ - tEplKernel Ret = kEplSuccessful; - - // $$$ d.k.: check if NMT state is NMT_GS_OFF - - // $$$ d.k.: maybe delete event queues at first, but this implies that - // no other module must not use the event queues for communication - // during shutdown. - - // delete instance for all modules - - // deinitialize EplSdoCom module -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \ - (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)) - Ret = EplSdoComDelInstance(); -// PRINTF1("EplSdoComDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplLedu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - Ret = EplLeduDelInstance(); -// PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // deinitialize EplNmtMnu module - Ret = EplNmtMnuDelInstance(); -// PRINTF1("EplNmtMnuDelInstance(): 0x%X\n", Ret); - - // deinitialize EplIdentu module - Ret = EplIdentuDelInstance(); -// PRINTF1("EplIdentuDelInstance(): 0x%X\n", Ret); - - // deinitialize EplStatusu module - Ret = EplStatusuDelInstance(); -// PRINTF1("EplStatusuDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplNmtCnu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - Ret = EplNmtCnuDelInstance(); -// PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplNmtu module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = EplNmtuDelInstance(); -// PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplDlluCal module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalDelInstance(); -// PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret); - -#endif - - // deinitialize EplEventu module - Ret = EplEventuDelInstance(); -// PRINTF1("EplEventuDelInstance(): 0x%X\n", Ret); - - // deinitialize EplNmtk module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - Ret = EplNmtkDelInstance(); -// PRINTF1("EplNmtkDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplDllk module -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkDelInstance(); -// PRINTF1("EplDllkDelInstance(): 0x%X\n", Ret); - - // deinitialize EplDllkCal module - Ret = EplDllkCalDelInstance(); -// PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret); -#endif - - // deinitialize EplEventk module - Ret = EplEventkDelInstance(); -// PRINTF1("EplEventkDelInstance(): 0x%X\n", Ret); - - // deinitialize EplTimerk module - Ret = EplTimerkDelInstance(); -// PRINTF1("EplTimerkDelInstance(): 0x%X\n", Ret); - -#ifndef EPL_NO_FIFO - ShbExit(); -#endif - - return Ret; -} - -//---------------------------------------------------------------------------- -// Function: EplApiExecNmtCommand() -// -// Description: executes a NMT command, i.e. post the NMT command/event to the -// NMTk module. NMT commands which are not appropriate in the current -// NMT state are silently ignored. Please keep in mind that the -// NMT state may change until the NMT command is actually executed. -// -// Parameters: NmtEvent_p = NMT command/event -// -// Returns: tEplKernel = error code -// -// State: -//---------------------------------------------------------------------------- - -tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = EplNmtuNmtEvent(NmtEvent_p); -#endif - - return Ret; -} - -//---------------------------------------------------------------------------- -// Function: EplApiLinkObject() -// -// Description: Function maps array of application variables onto specified object in OD -// -// Parameters: uiObjIndex_p = Function maps variables for this object index -// pVar_p = Pointer to data memory area for the specified object -// puiVarEntries_p = IN: pointer to number of entries to map -// OUT: pointer to number of actually used entries -// pEntrySize_p = IN: pointer to size of one entry; -// if size is zero, the actual size will be read from OD -// OUT: pointer to entire size of all entries mapped -// uiFirstSubindex_p = This is the first subindex to be mapped. -// -// Returns: tEplKernel = error code -// -// State: -//---------------------------------------------------------------------------- - -tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p, - void *pVar_p, - unsigned int *puiVarEntries_p, - tEplObdSize *pEntrySize_p, - unsigned int uiFirstSubindex_p) -{ - u8 bVarEntries; - u8 bIndexEntries; - u8 *pbData; - unsigned int uiSubindex; - tEplVarParam VarParam; - tEplObdSize EntrySize; - tEplObdSize UsedSize; - - tEplKernel RetCode = kEplSuccessful; - - if ((pVar_p == NULL) - || (puiVarEntries_p == NULL) - || (*puiVarEntries_p == 0) - || (pEntrySize_p == NULL)) { - RetCode = kEplApiInvalidParam; - goto Exit; - } - - pbData = (u8 *)pVar_p; - bVarEntries = (u8) * puiVarEntries_p; - UsedSize = 0; - - // init VarParam structure with default values - VarParam.m_uiIndex = uiObjIndex_p; - VarParam.m_ValidFlag = kVarValidAll; - - if (uiFirstSubindex_p != 0) { // check if object exists by reading subindex 0x00, - // because user wants to link a variable to a subindex unequal 0x00 - // read number of entries - EntrySize = (tEplObdSize) sizeof(bIndexEntries); - RetCode = EplObdReadEntry(uiObjIndex_p, - 0x00, - (void *)&bIndexEntries, - &EntrySize); - - if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) { - // Object doesn't exist or invalid entry number - RetCode = kEplObdIndexNotExist; - goto Exit; - } - } else { // user wants to link a variable to subindex 0x00 - // that's OK - bIndexEntries = 0; - } - - // Correct number of entries if number read from OD is greater - // than the specified number. - // This is done, so that we do not set more entries than subindexes the - // object actually has. - if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) && - (bVarEntries != 0x00)) { - bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1); - } - // map entries - for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries; - uiSubindex++) { - // if passed entry size is 0, then get size from OD - if (*pEntrySize_p == 0x00) { - // read entry size - EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex); - - if (EntrySize == 0x00) { - // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty) - RetCode = kEplObdSubindexNotExist; - break; - } - } else { // use passed entry size - EntrySize = *pEntrySize_p; - } - - VarParam.m_uiSubindex = uiSubindex; - - // set pointer to user var - VarParam.m_Size = EntrySize; - VarParam.m_pData = pbData; - - UsedSize += EntrySize; - pbData += EntrySize; - - RetCode = EplObdDefineVar(&VarParam); - if (RetCode != kEplSuccessful) { - break; - } - } - - // set number of mapped entries and entry size - *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1); - *pEntrySize_p = UsedSize; - - Exit: - - return (RetCode); - -} - -// ---------------------------------------------------------------------------- -// -// Function: EplApiReadObject() -// -// Description: reads the specified entry from the OD of the specified node. -// If this node is a remote node, it performs a SDO transfer, which -// means this function returns kEplApiTaskDeferred and the application -// is informed via the event callback function when the task is completed. -// -// Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access) -// uiNodeId_p = IN: node ID (0 = itself) -// uiIndex_p = IN: index of object in OD -// uiSubindex_p = IN: sub-index of object in OD -// pDstData_le_p = OUT: pointer to data in little endian -// puiSize_p = INOUT: pointer to size of data -// SdoType_p = IN: type of SDO transfer -// pUserArg_p = IN: user-definable argument pointer, -// which will be passed to the event callback function -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiNodeId_p, - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pDstData_le_p, - unsigned int *puiSize_p, - tEplSdoType SdoType_p, void *pUserArg_p) -{ - tEplKernel Ret = kEplSuccessful; - - if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL) - || (*puiSize_p == 0)) { - Ret = kEplApiInvalidParam; - goto Exit; - } - - if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed - tEplObdSize ObdSize; - - ObdSize = (tEplObdSize) * puiSize_p; - Ret = - EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p, - &ObdSize); - *puiSize_p = (unsigned int)ObdSize; - } else { // perform SDO transfer -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - tEplSdoComTransParamByIndex TransParamByIndex; -// tEplSdoComConHdl SdoComConHdl; - - // check if application provides space for handle - if (pSdoComConHdl_p == NULL) { - Ret = kEplApiInvalidParam; - goto Exit; -// pSdoComConHdl_p = &SdoComConHdl; - } - // init command layer connection - Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id - SdoType_p); // SDO type - if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) { - goto Exit; - } - TransParamByIndex.m_pData = pDstData_le_p; - TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead; - TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p; - TransParamByIndex.m_uiDataSize = *puiSize_p; - TransParamByIndex.m_uiIndex = uiIndex_p; - TransParamByIndex.m_uiSubindex = uiSubindex_p; - TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon; - TransParamByIndex.m_pUserArg = pUserArg_p; - - Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); - if (Ret != kEplSuccessful) { - goto Exit; - } - Ret = kEplApiTaskDeferred; - -#else - Ret = kEplApiInvalidParam; -#endif - } - - Exit: - return Ret; -} - -// ---------------------------------------------------------------------------- -// -// Function: EplApiWriteObject() -// -// Description: writes the specified entry to the OD of the specified node. -// If this node is a remote node, it performs a SDO transfer, which -// means this function returns kEplApiTaskDeferred and the application -// is informed via the event callback function when the task is completed. -// -// Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access) -// uiNodeId_p = IN: node ID (0 = itself) -// uiIndex_p = IN: index of object in OD -// uiSubindex_p = IN: sub-index of object in OD -// pSrcData_le_p = IN: pointer to data in little endian -// uiSize_p = IN: size of data in bytes -// SdoType_p = IN: type of SDO transfer -// pUserArg_p = IN: user-definable argument pointer, -// which will be passed to the event callback function -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiNodeId_p, - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pSrcData_le_p, - unsigned int uiSize_p, - tEplSdoType SdoType_p, void *pUserArg_p) -{ - tEplKernel Ret = kEplSuccessful; - - if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) { - Ret = kEplApiInvalidParam; - goto Exit; - } - - if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed - - Ret = - EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p, - pSrcData_le_p, uiSize_p); - } else { // perform SDO transfer -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - tEplSdoComTransParamByIndex TransParamByIndex; -// tEplSdoComConHdl SdoComConHdl; - - // check if application provides space for handle - if (pSdoComConHdl_p == NULL) { - Ret = kEplApiInvalidParam; - goto Exit; -// pSdoComConHdl_p = &SdoComConHdl; - } - // d.k.: How to recycle command layer connection? - // Try to redefine it, which will return kEplSdoComHandleExists - // and the existing command layer handle. - // If the returned handle is busy, EplSdoComInitTransferByIndex() - // will return with error. - // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and - // Configuration Manager, are trying to communicate with the very same node. - // possible solution: disallow communication by application if Configuration Manager is busy - - // init command layer connection - Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id - SdoType_p); // SDO type - if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) { - goto Exit; - } - TransParamByIndex.m_pData = pSrcData_le_p; - TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite; - TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p; - TransParamByIndex.m_uiDataSize = uiSize_p; - TransParamByIndex.m_uiIndex = uiIndex_p; - TransParamByIndex.m_uiSubindex = uiSubindex_p; - TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon; - TransParamByIndex.m_pUserArg = pUserArg_p; - - Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); - if (Ret != kEplSuccessful) { - goto Exit; - } - Ret = kEplApiTaskDeferred; - -#else - Ret = kEplApiInvalidParam; -#endif - } - - Exit: - return Ret; -} - -// ---------------------------------------------------------------------------- -// -// Function: EplApiFreeSdoChannel() -// -// Description: frees the specified SDO channel. -// This function must be called after each call to EplApiReadObject()/EplApiWriteObject() -// which returns kEplApiTaskDeferred and the application -// is informed via the event callback function when the task is completed. -// -// Parameters: SdoComConHdl_p = IN: SDO connection handle -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - - // init command layer connection - Ret = EplSdoComUndefineCon(SdoComConHdl_p); - -#else - Ret = kEplApiInvalidParam; -#endif - - return Ret; -} - -// ---------------------------------------------------------------------------- -// -// Function: EplApiReadLocalObject() -// -// Description: reads the specified entry from the local OD. -// -// Parameters: uiIndex_p = IN: index of object in OD -// uiSubindex_p = IN: sub-index of object in OD -// pDstData_p = OUT: pointer to data in platform byte order -// puiSize_p = INOUT: pointer to size of data -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pDstData_p, unsigned int *puiSize_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplObdSize ObdSize; - - ObdSize = (tEplObdSize) * puiSize_p; - Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize); - *puiSize_p = (unsigned int)ObdSize; - - return Ret; -} - -// ---------------------------------------------------------------------------- -// -// Function: EplApiWriteLocalObject() -// -// Description: writes the specified entry to the local OD. -// -// Parameters: uiIndex_p = IN: index of object in OD -// uiSubindex_p = IN: sub-index of object in OD -// pSrcData_p = IN: pointer to data in platform byte order -// uiSize_p = IN: size of data in bytes -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p, - unsigned int uiSubindex_p, - void *pSrcData_p, - unsigned int uiSize_p) -{ - tEplKernel Ret = kEplSuccessful; - - Ret = - EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p, - (tEplObdSize) uiSize_p); - - return Ret; -} - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -// ---------------------------------------------------------------------------- -// -// Function: EplApiMnTriggerStateChange() -// -// Description: triggers the specified node command for the specified node. -// -// Parameters: uiNodeId_p = node ID for which the node command will be executed -// NodeCommand_p = node command -// -// Return: tEplKernel = error code -// -// ---------------------------------------------------------------------------- - -tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p, - tEplNmtNodeCommand NodeCommand_p) -{ - tEplKernel Ret = kEplSuccessful; - - Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p); - - return Ret; -} - -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbObdAccess -// -// Description: callback function for OD accesses -// -// Parameters: pParam_p = OBD parameter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if (EPL_API_OBD_FORWARD_EVENT != FALSE) - tEplApiEventArg EventArg; - - // call user callback - // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem - // for local OD access. This is not so bad as user callback function in - // application does not use OD callbacks at the moment. - EventArg.m_ObdCbParam = *pParam_p; - Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess, - &EventArg, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); -#endif - - switch (pParam_p->m_uiIndex) { - //case 0x1006: // NMT_CycleLen_U32 (valid on reset) - case 0x1C14: // DLL_LossOfFrameTolerance_U32 - //case 0x1F98: // NMT_CycleTiming_REC (valid on reset) - { - if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) { - // update DLL configuration - Ret = EplApiUpdateDllConfig(FALSE); - } - break; - } - - case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0 - { - if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite) - && (pParam_p->m_uiSubIndex == 3) - && (*((u32 *) pParam_p->m_pArg) != 0)) { - u32 dwVerifyConfInvalid = 0; - // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0 - Ret = - EplObdWriteEntry(0x1020, 4, - &dwVerifyConfInvalid, 4); - // ignore any error because this objekt is optional - Ret = kEplSuccessful; - } - break; - } - - case 0x1F9E: // NMT_ResetCmd_U8 - { - if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) { - u8 bNmtCommand; - - bNmtCommand = *((u8 *) pParam_p->m_pArg); - // check value range - switch ((tEplNmtCommand) bNmtCommand) { - case kEplNmtCmdResetNode: - case kEplNmtCmdResetCommunication: - case kEplNmtCmdResetConfiguration: - case kEplNmtCmdSwReset: - case kEplNmtCmdInvalidService: - // valid command identifier specified - break; - - default: - pParam_p->m_dwAbortCode = - EPL_SDOAC_VALUE_RANGE_EXCEEDED; - Ret = kEplObdAccessViolation; - break; - } - } else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) { - u8 bNmtCommand; - - bNmtCommand = *((u8 *) pParam_p->m_pArg); - // check value range - switch ((tEplNmtCommand) bNmtCommand) { - case kEplNmtCmdResetNode: -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = - EplNmtuNmtEvent - (kEplNmtEventResetNode); -#endif - break; - - case kEplNmtCmdResetCommunication: -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = - EplNmtuNmtEvent - (kEplNmtEventResetCom); -#endif - break; - - case kEplNmtCmdResetConfiguration: -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = - EplNmtuNmtEvent - (kEplNmtEventResetConfig); -#endif - break; - - case kEplNmtCmdSwReset: -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = - EplNmtuNmtEvent - (kEplNmtEventSwReset); -#endif - break; - - case kEplNmtCmdInvalidService: - break; - - default: - pParam_p->m_dwAbortCode = - EPL_SDOAC_VALUE_RANGE_EXCEEDED; - Ret = kEplObdAccessViolation; - break; - } - } - break; - } - - default: - break; - } - -//Exit: - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplApiProcessEvent -// -// Description: processes events from event queue and forwards these to -// the application's event callback function -// -// Parameters: pEplEvent_p = pointer to event -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p) -{ - tEplKernel Ret; - tEplEventError *pEventError; - tEplApiEventType EventType; - - Ret = kEplSuccessful; - - // process event - switch (pEplEvent_p->m_EventType) { - // error event - case kEplEventTypeError: - { - pEventError = (tEplEventError *) pEplEvent_p->m_pArg; - switch (pEventError->m_EventSource) { - // treat the errors from the following sources as critical - case kEplEventSourceEventk: - case kEplEventSourceEventu: - case kEplEventSourceDllk: - { - EventType = kEplApiEventCriticalError; - // halt the stack by entering NMT state Off - Ret = - EplNmtuNmtEvent - (kEplNmtEventCriticalError); - break; - } - - // the other errors are just warnings - default: - { - EventType = kEplApiEventWarning; - break; - } - } - - // call user callback - Ret = - EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType, - (tEplApiEventArg - *) - pEventError, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); - // discard error from callback function, because this could generate an endless loop - Ret = kEplSuccessful; - break; - } - - // at present, there are no other events for this module - default: - break; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbNmtStateChange -// -// Description: callback function for NMT state changes -// -// Parameters: NmtStateChange_p = NMT state change event -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p) -{ - tEplKernel Ret = kEplSuccessful; - u8 bNmtState; - tEplApiEventArg EventArg; - - // save NMT state in OD - bNmtState = (u8) NmtStateChange_p.m_NewNmtState; - Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1); - if (Ret != kEplSuccessful) { - goto Exit; - } - // do work which must be done in that state - switch (NmtStateChange_p.m_NewNmtState) { - // EPL stack is not running - case kEplNmtGsOff: - break; - - // first init of the hardware - case kEplNmtGsInitialising: -#if 0 -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // configure SDO via UDP (i.e. bind it to the EPL ethernet interface) - Ret = - EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress, - EPL_C_SDO_EPL_PORT); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif -#endif - - break; - - // init of the manufacturer-specific profile area and the - // standardised device profile area - case kEplNmtGsResetApplication: - { - // reset application part of OD - Ret = EplObdAccessOdPart(kEplObdPartApp, - kEplObdDirLoad); - if (Ret != kEplSuccessful) { - goto Exit; - } - - break; - } - - // init of the communication profile area - case kEplNmtGsResetCommunication: - { - // reset communication part of OD - Ret = EplObdAccessOdPart(kEplObdPartGen, - kEplObdDirLoad); - - if (Ret != kEplSuccessful) { - goto Exit; - } - // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory - Ret = EplApiUpdateObd(); - if (Ret != kEplSuccessful) { - goto Exit; - } - - break; - } - - // build the configuration with infos from OD - case kEplNmtGsResetConfiguration: - { - - Ret = EplApiUpdateDllConfig(TRUE); - if (Ret != kEplSuccessful) { - goto Exit; - } - - break; - } - - //----------------------------------------------------------- - // CN part of the state machine - - // node liste for EPL-Frames and check timeout - case kEplNmtCsNotActive: - { - // indicate completion of reset in NMT_ResetCmd_U8 - bNmtState = (u8) kEplNmtCmdInvalidService; - Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1); - if (Ret != kEplSuccessful) { - goto Exit; - } - - break; - } - - // node process only async frames - case kEplNmtCsPreOperational1: - { - break; - } - - // node process isochronus and asynchronus frames - case kEplNmtCsPreOperational2: - { - break; - } - - // node should be configured und application is ready - case kEplNmtCsReadyToOperate: - { - break; - } - - // normal work state - case kEplNmtCsOperational: - { - break; - } - - // node stopped by MN - // -> only process asynchronus frames - case kEplNmtCsStopped: - { - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtCsBasicEthernet: - { - break; - } - - //----------------------------------------------------------- - // MN part of the state machine - - // node listens for EPL-Frames and check timeout - case kEplNmtMsNotActive: - { - break; - } - - // node processes only async frames - case kEplNmtMsPreOperational1: - { - break; - } - - // node processes isochronous and asynchronous frames - case kEplNmtMsPreOperational2: - { - break; - } - - // node should be configured und application is ready - case kEplNmtMsReadyToOperate: - { - break; - } - - // normal work state - case kEplNmtMsOperational: - { - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtMsBasicEthernet: - { - break; - } - - default: - { - TRACE0 - ("EplApiCbNmtStateChange(): unhandled NMT state\n"); - } - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - // forward event to Led module - Ret = EplLeduCbNmtStateChange(NmtStateChange_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // forward event to NmtMn module - Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - // call user callback - EventArg.m_NmtStateChange = NmtStateChange_p; - Ret = - EplApiInstance_g.m_InitParam. - m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg, - EplApiInstance_g.m_InitParam.m_pEventUserArg); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiUpdateDllConfig -// -// Description: update configuration of DLL -// -// Parameters: fUpdateIdentity_p = TRUE, if identity must be updated -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllConfigParam DllConfigParam; - tEplDllIdentParam DllIdentParam; - tEplObdSize ObdSize; - u16 wTemp; - u8 bTemp; - - // configure Dll - EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam)); - DllConfigParam.m_uiNodeId = EplObdGetNodeId(); - - // Cycle Length (0x1006: NMT_CycleLen_U32) in [us] - ObdSize = 4; - Ret = - EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 0x1F82: NMT_FeatureFlags_U32 - ObdSize = 4; - Ret = - EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // d.k. There is no dependance between FeatureFlags and async-only CN - DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly; - - // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns] - ObdSize = 4; - Ret = - EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 0x1F98: NMT_CycleTiming_REC - // 0x1F98.1: IsochrTxMaxPayload_U16 - ObdSize = 2; - Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiIsochrTxMaxPayload = wTemp; - - // 0x1F98.2: IsochrRxMaxPayload_U16 - ObdSize = 2; - Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiIsochrRxMaxPayload = wTemp; - - // 0x1F98.3: PResMaxLatency_U32 - ObdSize = 4; - Ret = - EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 0x1F98.4: PReqActPayloadLimit_U16 - ObdSize = 2; - Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiPreqActPayloadLimit = wTemp; - - // 0x1F98.5: PResActPayloadLimit_U16 - ObdSize = 2; - Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiPresActPayloadLimit = wTemp; - - // 0x1F98.6: ASndMaxLatency_U32 - ObdSize = 4; - Ret = - EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 0x1F98.7: MultiplCycleCnt_U8 - ObdSize = 1; - Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiMultiplCycleCnt = bTemp; - - // 0x1F98.8: AsyncMTU_U16 - ObdSize = 2; - Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - DllConfigParam.m_uiAsyncMtu = wTemp; - - // $$$ Prescaler - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // 0x1F8A.1: WaitSoCPReq_U32 in [ns] - ObdSize = 4; - Ret = - EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional) - ObdSize = 4; - Ret = - EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout, - &ObdSize); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ -#endif - - DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam); - Ret = EplDllkConfig(&DllConfigParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if (fUpdateIdentity_p != FALSE) { - // configure Identity - EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam)); - ObdSize = 4; - Ret = - EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - ObdSize = 4; - Ret = - EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - ObdSize = 4; - Ret = - EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - ObdSize = 4; - Ret = - EplObdReadEntry(0x1018, 3, - &DllIdentParam.m_dwRevisionNumber, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - ObdSize = 4; - Ret = - EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - DllIdentParam.m_dwIpAddress = - EplApiInstance_g.m_InitParam.m_dwIpAddress; - DllIdentParam.m_dwSubnetMask = - EplApiInstance_g.m_InitParam.m_dwSubnetMask; - EPL_MEMCPY(DllIdentParam.m_sHostname, - EplApiInstance_g.m_InitParam.m_sHostname, - sizeof(DllIdentParam.m_sHostname)); - - ObdSize = 4; - Ret = - EplObdReadEntry(0x1020, 1, - &DllIdentParam.m_dwVerifyConfigurationDate, - &ObdSize); - // ignore any error, because this object is optional - - ObdSize = 4; - Ret = - EplObdReadEntry(0x1020, 2, - &DllIdentParam.m_dwVerifyConfigurationTime, - &ObdSize); - // ignore any error, because this object is optional - - // $$$ d.k.: fill rest of ident structure - - DllIdentParam.m_uiSizeOfStruct = sizeof(DllIdentParam); - Ret = EplDllkSetIdentity(&DllIdentParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiUpdateObd -// -// Description: update OD from init param -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiUpdateObd(void) -{ - tEplKernel Ret = kEplSuccessful; - u16 wTemp; - u8 bTemp; - - // set node id in OD - Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id - kEplObdNodeIdHardware); // set by hardware - if (Ret != kEplSuccessful) { - goto Exit; - } - - if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) { - Ret = - EplObdWriteEntry(0x1006, 0, - &EplApiInstance_g.m_InitParam.m_dwCycleLen, - 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) { - Ret = - EplObdWriteEntry(0x1C14, 0, - &EplApiInstance_g.m_InitParam. - m_dwLossOfFrameTolerance, 4); - /* if(Ret != kEplSuccessful) - { - goto Exit; - } */ - } - // d.k. There is no dependance between FeatureFlags and async-only CN. - if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) { - Ret = - EplObdWriteEntry(0x1F82, 0, - &EplApiInstance_g.m_InitParam. - m_dwFeatureFlags, 4); - /* if(Ret != kEplSuccessful) - { - goto Exit; - } */ - } - - wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload; - Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - - wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload; - Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - - Ret = - EplObdWriteEntry(0x1F98, 3, - &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency, - 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - - if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <= - EPL_C_DLL_ISOCHR_MAX_PAYL) { - wTemp = - (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit; - Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <= - EPL_C_DLL_ISOCHR_MAX_PAYL) { - wTemp = - (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit; - Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - Ret = - EplObdWriteEntry(0x1F98, 6, - &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency, - 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - - if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) { - bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt; - Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <= - EPL_C_DLL_MAX_ASYNC_MTU) { - wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu; - Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) { - wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler; - Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2); - // ignore return code - Ret = kEplSuccessful; - } -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) { - Ret = - EplObdWriteEntry(0x1F8A, 1, - &EplApiInstance_g.m_InitParam. - m_dwWaitSocPreq, 4); - /* if(Ret != kEplSuccessful) - { - goto Exit; - } */ - } - - if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0) - && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) { - Ret = - EplObdWriteEntry(0x1F8A, 2, - &EplApiInstance_g.m_InitParam. - m_dwAsyncSlotTimeout, 4); - /* if(Ret != kEplSuccessful) - { - goto Exit; - } */ - } -#endif - - // configure Identity - if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) { - Ret = - EplObdWriteEntry(0x1000, 0, - &EplApiInstance_g.m_InitParam. - m_dwDeviceType, 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) { - Ret = - EplObdWriteEntry(0x1018, 1, - &EplApiInstance_g.m_InitParam.m_dwVendorId, - 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) { - Ret = - EplObdWriteEntry(0x1018, 2, - &EplApiInstance_g.m_InitParam. - m_dwProductCode, 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) { - Ret = - EplObdWriteEntry(0x1018, 3, - &EplApiInstance_g.m_InitParam. - m_dwRevisionNumber, 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) { - Ret = - EplObdWriteEntry(0x1018, 4, - &EplApiInstance_g.m_InitParam. - m_dwSerialNumber, 4); -/* if(Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) { - // write Device Name (0x1008) - Ret = - EplObdWriteEntry(0x1008, 0, - (void *)EplApiInstance_g. - m_InitParam.m_pszDevName, - (tEplObdSize) strlen(EplApiInstance_g. - m_InitParam. - m_pszDevName)); -/* if (Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) { - // write Hardware version (0x1009) - Ret = - EplObdWriteEntry(0x1009, 0, - (void *)EplApiInstance_g. - m_InitParam.m_pszHwVersion, - (tEplObdSize) strlen(EplApiInstance_g. - m_InitParam. - m_pszHwVersion)); -/* if (Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) { - // write Software version (0x100A) - Ret = - EplObdWriteEntry(0x100A, 0, - (void *)EplApiInstance_g. - m_InitParam.m_pszSwVersion, - (tEplObdSize) strlen(EplApiInstance_g. - m_InitParam. - m_pszSwVersion)); -/* if (Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbSdoCon -// -// Description: callback function for SDO transfers -// -// Parameters: pSdoComFinished_p = SDO parameter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p) -{ - tEplKernel Ret; - tEplApiEventArg EventArg; - - Ret = kEplSuccessful; - - // call user callback - EventArg.m_Sdo = *pSdoComFinished_p; - Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo, - &EventArg, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); - - return Ret; - -} -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbNodeEvent -// -// Description: callback function for node events -// -// Parameters: uiNodeId_p = node ID of the CN -// NodeEvent_p = event from the specified CN -// NmtState_p = current NMT state of the CN -// wErrorCode_p = EPL error code if NodeEvent_p==kEplNmtNodeEventError -// fMandatory_p = flag if CN is mandatory -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p, - tEplNmtNodeEvent NodeEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p, BOOL fMandatory_p) -{ - tEplKernel Ret; - tEplApiEventArg EventArg; - - Ret = kEplSuccessful; - - // call user callback - EventArg.m_Node.m_uiNodeId = uiNodeId_p; - EventArg.m_Node.m_NodeEvent = NodeEvent_p; - EventArg.m_Node.m_NmtState = NmtState_p; - EventArg.m_Node.m_wErrorCode = wErrorCode_p; - EventArg.m_Node.m_fMandatory = fMandatory_p; - - Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode, - &EventArg, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbBootEvent -// -// Description: callback function for boot events -// -// Parameters: BootEvent_p = event from the boot-up process -// NmtState_p = current local NMT state -// wErrorCode_p = EPL error code if BootEvent_p==kEplNmtBootEventError -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p) -{ - tEplKernel Ret; - tEplApiEventArg EventArg; - - Ret = kEplSuccessful; - - // call user callback - EventArg.m_Boot.m_BootEvent = BootEvent_p; - EventArg.m_Boot.m_NmtState = NmtState_p; - EventArg.m_Boot.m_wErrorCode = wErrorCode_p; - - Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot, - &EventArg, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); - - return Ret; - -} - -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplApiCbLedStateChange -// -// Description: callback function for LED change events. -// -// Parameters: LedType_p = type of LED -// fOn_p = state of LED -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p) -{ - tEplKernel Ret; - tEplApiEventArg EventArg; - - Ret = kEplSuccessful; - - // call user callback - EventArg.m_Led.m_LedType = LedType_p; - EventArg.m_Led.m_fOn = fOn_p; - - Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed, - &EventArg, - EplApiInstance_g. - m_InitParam. - m_pEventUserArg); - - return Ret; - -} - -#endif - -// EOF diff --git a/drivers/staging/epl/EplApiLinux.h b/drivers/staging/epl/EplApiLinux.h deleted file mode 100644 index 92cd12532a6..00000000000 --- a/drivers/staging/epl/EplApiLinux.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL API layer for Linux (kernel and user space) - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplApiLinux.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/08/25 12:17:41 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/10/11 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_API_LINUX_H_ -#define _EPL_API_LINUX_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPLLIN_DEV_NAME "epl" // used for "/dev" and "/proc" entry - -//--------------------------------------------------------------------------- -// Commands for -//--------------------------------------------------------------------------- - -#define EPLLIN_CMD_INITIALIZE 0 // ulArg_p ~ tEplApiInitParam* -#define EPLLIN_CMD_PI_IN 1 // ulArg_p ~ tEplApiProcessImage* -#define EPLLIN_CMD_PI_OUT 2 // ulArg_p ~ tEplApiProcessImage* -#define EPLLIN_CMD_WRITE_OBJECT 3 // ulArg_p ~ tEplLinSdoObject* -#define EPLLIN_CMD_READ_OBJECT 4 // ulArg_p ~ tEplLinSdoObject* -#define EPLLIN_CMD_WRITE_LOCAL_OBJECT 5 // ulArg_p ~ tEplLinLocalObject* -#define EPLLIN_CMD_READ_LOCAL_OBJECT 6 // ulArg_p ~ tEplLinLocalObject* -#define EPLLIN_CMD_FREE_SDO_CHANNEL 7 // ulArg_p ~ tEplSdoComConHdl -#define EPLLIN_CMD_NMT_COMMAND 8 // ulArg_p ~ tEplNmtEvent -#define EPLLIN_CMD_GET_EVENT 9 // ulArg_p ~ tEplLinEvent* -#define EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE 10 // ulArg_p ~ tEplLinNodeCmdObject* -#define EPLLIN_CMD_PI_SETUP 11 // ulArg_p ~ 0 -#define EPLLIN_CMD_SHUTDOWN 12 // ulArg_p ~ 0 - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct { - unsigned int m_uiEventArgSize; - tEplApiEventArg *m_pEventArg; - tEplApiEventType *m_pEventType; - tEplKernel m_RetCbEvent; - -} tEplLinEvent; - -typedef struct { - tEplSdoComConHdl m_SdoComConHdl; - BOOL m_fValidSdoComConHdl; - unsigned int m_uiNodeId; - unsigned int m_uiIndex; - unsigned int m_uiSubindex; - void *m_le_pData; - unsigned int m_uiSize; - tEplSdoType m_SdoType; - void *m_pUserArg; - -} tEplLinSdoObject; - -typedef struct { - unsigned int m_uiIndex; - unsigned int m_uiSubindex; - void *m_pData; - unsigned int m_uiSize; - -} tEplLinLocalObject; - -typedef struct { - unsigned int m_uiNodeId; - tEplNmtNodeCommand m_NodeCommand; - -} tEplLinNodeCmdObject; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_API_LINUX_H_ diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c deleted file mode 100644 index cb3e275e3aa..00000000000 --- a/drivers/staging/epl/EplApiLinuxKernel.c +++ /dev/null @@ -1,1173 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Linux kernel module as wrapper of EPL API layer, - i.e. counterpart to a Linux application - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplApiLinuxKernel.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.9 $ $Date: 2008/11/21 09:00:38 $ - - $State: Exp $ - - Build Environment: - GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2006/10/11 d.k.: Initial Version - 2008/04/10 m.u.: Changed to new char driver init - -****************************************************************************/ - -// kernel modul and driver - -#include -#include -#include -#include - -//#include -//#include -//#include -//#include - -// scheduling -#include - -// memory access -#include -#include - -#include "Epl.h" -#include "EplApiLinux.h" -//#include "kernel/EplPdokCal.h" -#include "proc_fs.h" - - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -// Metainformation -MODULE_LICENSE("Dual BSD/GPL"); -#ifdef MODULE_AUTHOR -MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com"); -MODULE_DESCRIPTION("EPL API driver"); -#endif - -//--------------------------------------------------------------------------- -// Configuration -//--------------------------------------------------------------------------- - -#define EPLLIN_DRV_NAME "systec_epl" // used for - -//--------------------------------------------------------------------------- -// Constant definitions -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#endif - -#define EVENT_STATE_INIT 0 -#define EVENT_STATE_IOCTL 1 // ioctl entered and ready to receive EPL event -#define EVENT_STATE_READY 2 // EPL event can be forwarded to user application -#define EVENT_STATE_TERM 3 // terminate processing - -#define EPL_STATE_NOTOPEN 0 -#define EPL_STATE_NOTINIT 1 -#define EPL_STATE_RUNNING 2 -#define EPL_STATE_SHUTDOWN 3 - -//--------------------------------------------------------------------------- -// Global variables -//--------------------------------------------------------------------------- - - // device number (major and minor) -static dev_t nDevNum_g; -static struct cdev *pEpl_cdev_g; - -static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN; - -static struct semaphore SemaphoreCbEvent_g; // semaphore for EplLinCbEvent -static wait_queue_head_t WaitQueueCbEvent_g; // wait queue EplLinCbEvent -static wait_queue_head_t WaitQueueProcess_g; // wait queue for EplApiProcess (user process) -static wait_queue_head_t WaitQueueRelease_g; // wait queue for EplLinRelease -static atomic_t AtomicEventState_g = ATOMIC_INIT(EVENT_STATE_INIT); -static tEplApiEventType EventType_g; // event type (enum) -static tEplApiEventArg *pEventArg_g; // event argument (union) -static tEplKernel RetCbEvent_g; // return code from event callback function -static wait_queue_head_t WaitQueueCbSync_g; // wait queue EplLinCbSync -static wait_queue_head_t WaitQueuePI_In_g; // wait queue for EplApiProcessImageExchangeIn (user process) -static atomic_t AtomicSyncState_g = ATOMIC_INIT(EVENT_STATE_INIT); - -//--------------------------------------------------------------------------- -// Local types -//--------------------------------------------------------------------------- - -typedef struct { - void *m_pUserArg; - void *m_pData; - -} tEplLinSdoBufHeader; - -//--------------------------------------------------------------------------- -// Local variables -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Prototypes of internal functions -//--------------------------------------------------------------------------- - -tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p); - -tEplKernel EplLinCbSync(void); - -static int __init EplLinInit(void); -static void __exit EplLinExit(void); - -static int EplLinOpen(struct inode *pDeviceFile_p, struct file *pInstance_p); -static int EplLinRelease(struct inode *pDeviceFile_p, struct file *pInstance_p); -static ssize_t EplLinRead(struct file *pInstance_p, char *pDstBuff_p, - size_t BuffSize_p, loff_t * pFileOffs_p); -static ssize_t EplLinWrite(struct file *pInstance_p, const char *pSrcBuff_p, - size_t BuffSize_p, loff_t * pFileOffs_p); -static int EplLinIoctl(struct inode *pDeviceFile_p, struct file *pInstance_p, - unsigned int uiIoctlCmd_p, unsigned long ulArg_p); - -//--------------------------------------------------------------------------- -// Kernel Module specific Data Structures -//--------------------------------------------------------------------------- - -module_init(EplLinInit); -module_exit(EplLinExit); - -static struct file_operations EplLinFileOps_g = { - .owner = THIS_MODULE, - .open = EplLinOpen, - .release = EplLinRelease, - .read = EplLinRead, - .write = EplLinWrite, - .ioctl = EplLinIoctl, - -}; - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// Initailize Driver -//--------------------------------------------------------------------------- -// -> insmod driver -//--------------------------------------------------------------------------- - -static int __init EplLinInit(void) -{ - - tEplKernel EplRet; - int iErr; - int iRet; - - TRACE0("EPL: + EplLinInit...\n"); - TRACE2("EPL: Driver build: %s / %s\n", __DATE__, __TIME__); - - iRet = 0; - - // initialize global variables - atomic_set(&AtomicEventState_g, EVENT_STATE_INIT); - sema_init(&SemaphoreCbEvent_g, 1); - init_waitqueue_head(&WaitQueueCbEvent_g); - init_waitqueue_head(&WaitQueueProcess_g); - init_waitqueue_head(&WaitQueueRelease_g); - - // register character device handler - // only one Minor required - TRACE2("EPL: Installing Driver '%s', Version %s...\n", - EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION); - iRet = alloc_chrdev_region(&nDevNum_g, 0, 1, EPLLIN_DRV_NAME); - if (iRet == 0) { - TRACE2 - ("EPL: Driver '%s' installed successful, assigned MajorNumber=%d\n", - EPLLIN_DRV_NAME, MAJOR(nDevNum_g)); - } else { - TRACE1 - ("EPL: ERROR: Driver '%s' is unable to get a free MajorNumber!\n", - EPLLIN_DRV_NAME); - iRet = -EIO; - goto Exit; - } - - // register cdev structure - pEpl_cdev_g = cdev_alloc(); - pEpl_cdev_g->ops = &EplLinFileOps_g; - pEpl_cdev_g->owner = THIS_MODULE; - iErr = cdev_add(pEpl_cdev_g, nDevNum_g, 1); - if (iErr) { - TRACE2("EPL: ERROR %d: Driver '%s' could not be added!\n", - iErr, EPLLIN_DRV_NAME); - iRet = -EIO; - goto Exit; - } - - // create device node in PROCFS - EplRet = EplLinProcInit(); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - Exit: - - TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet); - return (iRet); - -} - -//--------------------------------------------------------------------------- -// Remove Driver -//--------------------------------------------------------------------------- -// -> rmmod driver -//--------------------------------------------------------------------------- - -static void __exit EplLinExit(void) -{ - - tEplKernel EplRet; - - // delete instance for all modules -// EplRet = EplApiShutdown(); -// printk("EplApiShutdown(): 0x%X\n", EplRet); - - // deinitialize proc fs - EplRet = EplLinProcFree(); - printk("EplLinProcFree(): 0x%X\n", EplRet); - - TRACE0("EPL: + EplLinExit...\n"); - - // remove cdev structure - cdev_del(pEpl_cdev_g); - - // unregister character device handler - unregister_chrdev_region(nDevNum_g, 1); - - TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME); - - TRACE0("EPL: - EplLinExit\n"); - -} - -//--------------------------------------------------------------------------- -// Open Driver -//--------------------------------------------------------------------------- -// -> open("/dev/driver", O_RDWR)... -//--------------------------------------------------------------------------- - -static int EplLinOpen(struct inode *pDeviceFile_p, // information about the device to open - struct file *pInstance_p) // information about driver instance -{ - - int iRet; - - TRACE0("EPL: + EplLinOpen...\n"); - - if (uiEplState_g != EPL_STATE_NOTOPEN) { // stack already initialized - iRet = -EALREADY; - } else { - atomic_set(&AtomicEventState_g, EVENT_STATE_INIT); - sema_init(&SemaphoreCbEvent_g, 1); - init_waitqueue_head(&WaitQueueCbEvent_g); - init_waitqueue_head(&WaitQueueProcess_g); - init_waitqueue_head(&WaitQueueRelease_g); - atomic_set(&AtomicSyncState_g, EVENT_STATE_INIT); - init_waitqueue_head(&WaitQueueCbSync_g); - init_waitqueue_head(&WaitQueuePI_In_g); - - uiEplState_g = EPL_STATE_NOTINIT; - iRet = 0; - } - - TRACE1("EPL: - EplLinOpen (iRet=%d)\n", iRet); - return (iRet); - -} - -//--------------------------------------------------------------------------- -// Close Driver -//--------------------------------------------------------------------------- -// -> close(device)... -//--------------------------------------------------------------------------- - -static int EplLinRelease(struct inode *pDeviceFile_p, // information about the device to open - struct file *pInstance_p) // information about driver instance -{ - - tEplKernel EplRet = kEplSuccessful; - int iRet; - - TRACE0("EPL: + EplLinRelease...\n"); - - if (uiEplState_g != EPL_STATE_NOTINIT) { - // pass control to sync kernel thread, but signal termination - atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbSync_g); - wake_up_interruptible(&WaitQueuePI_In_g); - - // pass control to event queue kernel thread - atomic_set(&AtomicEventState_g, EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbEvent_g); - - if (uiEplState_g == EPL_STATE_RUNNING) { // post NmtEventSwitchOff - EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); - - } - - if (EplRet == kEplSuccessful) { - TRACE0("EPL: waiting for NMT_GS_OFF\n"); - wait_event_interruptible(WaitQueueRelease_g, - (uiEplState_g == - EPL_STATE_SHUTDOWN)); - } else { // post NmtEventSwitchOff failed - TRACE0("EPL: event post failed\n"); - } - - // $$$ d.k.: What if waiting was interrupted by signal? - - TRACE0("EPL: call EplApiShutdown()\n"); - // EPL stack can be safely shut down - // delete instance for all EPL modules - EplRet = EplApiShutdown(); - printk("EplApiShutdown(): 0x%X\n", EplRet); - } - - uiEplState_g = EPL_STATE_NOTOPEN; - iRet = 0; - - TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet); - return (iRet); - -} - -//--------------------------------------------------------------------------- -// Read Data from Driver -//--------------------------------------------------------------------------- -// -> read(...) -//--------------------------------------------------------------------------- - -static ssize_t EplLinRead(struct file *pInstance_p, // information about driver instance - char *pDstBuff_p, // address of buffer to fill with data - size_t BuffSize_p, // length of the buffer - loff_t * pFileOffs_p) // offset in the file -{ - - int iRet; - - TRACE0("EPL: + EplLinRead...\n"); - - TRACE0("EPL: Sorry, this operation isn't supported.\n"); - iRet = -EINVAL; - - TRACE1("EPL: - EplLinRead (iRet=%d)\n", iRet); - return (iRet); - -} - -//--------------------------------------------------------------------------- -// Write Data to Driver -//--------------------------------------------------------------------------- -// -> write(...) -//--------------------------------------------------------------------------- - -static ssize_t EplLinWrite(struct file *pInstance_p, // information about driver instance - const char *pSrcBuff_p, // address of buffer to get data from - size_t BuffSize_p, // length of the buffer - loff_t * pFileOffs_p) // offset in the file -{ - - int iRet; - - TRACE0("EPL: + EplLinWrite...\n"); - - TRACE0("EPL: Sorry, this operation isn't supported.\n"); - iRet = -EINVAL; - - TRACE1("EPL: - EplLinWrite (iRet=%d)\n", iRet); - return (iRet); - -} - -//--------------------------------------------------------------------------- -// Generic Access to Driver -//--------------------------------------------------------------------------- -// -> ioctl(...) -//--------------------------------------------------------------------------- - -static int EplLinIoctl(struct inode *pDeviceFile_p, // information about the device to open - struct file *pInstance_p, // information about driver instance - unsigned int uiIoctlCmd_p, // Ioctl command to execute - unsigned long ulArg_p) // Ioctl command specific argument/parameter -{ - - tEplKernel EplRet; - int iErr; - int iRet; - -// TRACE1("EPL: + EplLinIoctl (uiIoctlCmd_p=%d)...\n", uiIoctlCmd_p); - - iRet = -EINVAL; - - switch (uiIoctlCmd_p) { - // ---------------------------------------------------------- - case EPLLIN_CMD_INITIALIZE: - { - tEplApiInitParam EplApiInitParam; - - iErr = - copy_from_user(&EplApiInitParam, - (const void *)ulArg_p, - sizeof(EplApiInitParam)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - EplApiInitParam.m_pfnCbEvent = EplLinCbEvent; - EplApiInitParam.m_pfnCbSync = EplLinCbSync; - - EplRet = EplApiInitialize(&EplApiInitParam); - - uiEplState_g = EPL_STATE_RUNNING; - - iRet = (int)EplRet; - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_SHUTDOWN: - { // shutdown the threads - - // pass control to sync kernel thread, but signal termination - atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbSync_g); - wake_up_interruptible(&WaitQueuePI_In_g); - - // pass control to event queue kernel thread - atomic_set(&AtomicEventState_g, EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbEvent_g); - - if (uiEplState_g == EPL_STATE_RUNNING) { // post NmtEventSwitchOff - EplRet = - EplApiExecNmtCommand(kEplNmtEventSwitchOff); - - } - - iRet = 0; - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_READ_LOCAL_OBJECT: - { - tEplLinLocalObject LocalObject; - void *pData; - - iErr = - copy_from_user(&LocalObject, (const void *)ulArg_p, - sizeof(LocalObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if ((LocalObject.m_pData == NULL) - || (LocalObject.m_uiSize == 0)) { - iRet = (int)kEplApiInvalidParam; - goto Exit; - } - - pData = vmalloc(LocalObject.m_uiSize); - if (pData == NULL) { // no memory available - iRet = -ENOMEM; - goto Exit; - } - - EplRet = - EplApiReadLocalObject(LocalObject.m_uiIndex, - LocalObject.m_uiSubindex, - pData, &LocalObject.m_uiSize); - - if (EplRet == kEplSuccessful) { - iErr = - copy_to_user(LocalObject.m_pData, pData, - LocalObject.m_uiSize); - - vfree(pData); - - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - // return actual size (LocalObject.m_uiSize) - iErr = put_user(LocalObject.m_uiSize, - (unsigned int *)(ulArg_p + - (unsigned long) - &LocalObject. - m_uiSize - - (unsigned long) - &LocalObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - } else { - vfree(pData); - } - - iRet = (int)EplRet; - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_WRITE_LOCAL_OBJECT: - { - tEplLinLocalObject LocalObject; - void *pData; - - iErr = - copy_from_user(&LocalObject, (const void *)ulArg_p, - sizeof(LocalObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if ((LocalObject.m_pData == NULL) - || (LocalObject.m_uiSize == 0)) { - iRet = (int)kEplApiInvalidParam; - goto Exit; - } - - pData = vmalloc(LocalObject.m_uiSize); - if (pData == NULL) { // no memory available - iRet = -ENOMEM; - goto Exit; - } - iErr = - copy_from_user(pData, LocalObject.m_pData, - LocalObject.m_uiSize); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - EplRet = - EplApiWriteLocalObject(LocalObject.m_uiIndex, - LocalObject.m_uiSubindex, - pData, LocalObject.m_uiSize); - - vfree(pData); - - iRet = (int)EplRet; - break; - } - - case EPLLIN_CMD_READ_OBJECT: - { - tEplLinSdoObject SdoObject; - void *pData; - tEplLinSdoBufHeader *pBufHeader; - tEplSdoComConHdl *pSdoComConHdl; - - iErr = - copy_from_user(&SdoObject, (const void *)ulArg_p, - sizeof(SdoObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if ((SdoObject.m_le_pData == NULL) - || (SdoObject.m_uiSize == 0)) { - iRet = (int)kEplApiInvalidParam; - goto Exit; - } - - pBufHeader = - (tEplLinSdoBufHeader *) - vmalloc(sizeof(tEplLinSdoBufHeader) + - SdoObject.m_uiSize); - if (pBufHeader == NULL) { // no memory available - iRet = -ENOMEM; - goto Exit; - } - // initiate temporary buffer - pBufHeader->m_pUserArg = SdoObject.m_pUserArg; // original user argument pointer - pBufHeader->m_pData = SdoObject.m_le_pData; // original data pointer from app - pData = pBufHeader + sizeof(tEplLinSdoBufHeader); - - if (SdoObject.m_fValidSdoComConHdl != FALSE) { - pSdoComConHdl = &SdoObject.m_SdoComConHdl; - } else { - pSdoComConHdl = NULL; - } - - EplRet = - EplApiReadObject(pSdoComConHdl, - SdoObject.m_uiNodeId, - SdoObject.m_uiIndex, - SdoObject.m_uiSubindex, pData, - &SdoObject.m_uiSize, - SdoObject.m_SdoType, pBufHeader); - - // return actual SDO handle (SdoObject.m_SdoComConHdl) - iErr = put_user(SdoObject.m_SdoComConHdl, - (unsigned int *)(ulArg_p + - (unsigned long) - &SdoObject. - m_SdoComConHdl - - (unsigned long) - &SdoObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if (EplRet == kEplSuccessful) { - iErr = - copy_to_user(SdoObject.m_le_pData, pData, - SdoObject.m_uiSize); - - vfree(pBufHeader); - - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - // return actual size (SdoObject.m_uiSize) - iErr = put_user(SdoObject.m_uiSize, - (unsigned int *)(ulArg_p + - (unsigned long) - &SdoObject. - m_uiSize - - (unsigned long) - &SdoObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - } else if (EplRet != kEplApiTaskDeferred) { // error ocurred - vfree(pBufHeader); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - } - - iRet = (int)EplRet; - break; - } - - case EPLLIN_CMD_WRITE_OBJECT: - { - tEplLinSdoObject SdoObject; - void *pData; - tEplLinSdoBufHeader *pBufHeader; - tEplSdoComConHdl *pSdoComConHdl; - - iErr = - copy_from_user(&SdoObject, (const void *)ulArg_p, - sizeof(SdoObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if ((SdoObject.m_le_pData == NULL) - || (SdoObject.m_uiSize == 0)) { - iRet = (int)kEplApiInvalidParam; - goto Exit; - } - - pBufHeader = - (tEplLinSdoBufHeader *) - vmalloc(sizeof(tEplLinSdoBufHeader) + - SdoObject.m_uiSize); - if (pBufHeader == NULL) { // no memory available - iRet = -ENOMEM; - goto Exit; - } - // initiate temporary buffer - pBufHeader->m_pUserArg = SdoObject.m_pUserArg; // original user argument pointer - pBufHeader->m_pData = SdoObject.m_le_pData; // original data pointer from app - pData = pBufHeader + sizeof(tEplLinSdoBufHeader); - - iErr = - copy_from_user(pData, SdoObject.m_le_pData, - SdoObject.m_uiSize); - - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if (SdoObject.m_fValidSdoComConHdl != FALSE) { - pSdoComConHdl = &SdoObject.m_SdoComConHdl; - } else { - pSdoComConHdl = NULL; - } - - EplRet = - EplApiWriteObject(pSdoComConHdl, - SdoObject.m_uiNodeId, - SdoObject.m_uiIndex, - SdoObject.m_uiSubindex, pData, - SdoObject.m_uiSize, - SdoObject.m_SdoType, pBufHeader); - - // return actual SDO handle (SdoObject.m_SdoComConHdl) - iErr = put_user(SdoObject.m_SdoComConHdl, - (unsigned int *)(ulArg_p + - (unsigned long) - &SdoObject. - m_SdoComConHdl - - (unsigned long) - &SdoObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if (EplRet != kEplApiTaskDeferred) { // succeeded or error ocurred, but task not deferred - vfree(pBufHeader); - } - - iRet = (int)EplRet; - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_FREE_SDO_CHANNEL: - { - // forward SDO handle to EPL stack - EplRet = - EplApiFreeSdoChannel((tEplSdoComConHdl) ulArg_p); - - iRet = (int)EplRet; - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // ---------------------------------------------------------- - case EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE: - { - tEplLinNodeCmdObject NodeCmdObject; - - iErr = - copy_from_user(&NodeCmdObject, - (const void *)ulArg_p, - sizeof(NodeCmdObject)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - EplRet = - EplApiMnTriggerStateChange(NodeCmdObject.m_uiNodeId, - NodeCmdObject. - m_NodeCommand); - iRet = (int)EplRet; - break; - } -#endif - - // ---------------------------------------------------------- - case EPLLIN_CMD_GET_EVENT: - { - tEplLinEvent Event; - - // save event structure - iErr = - copy_from_user(&Event, (const void *)ulArg_p, - sizeof(Event)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - // save return code from application's event callback function - RetCbEvent_g = Event.m_RetCbEvent; - - if (RetCbEvent_g == kEplShutdown) { - // pass control to event queue kernel thread, but signal termination - atomic_set(&AtomicEventState_g, - EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbEvent_g); - // exit with error -> EplApiProcess() will leave the infinite loop - iRet = 1; - goto Exit; - } - // pass control to event queue kernel thread - atomic_set(&AtomicEventState_g, EVENT_STATE_IOCTL); - wake_up_interruptible(&WaitQueueCbEvent_g); - - // fall asleep itself in own wait queue - iErr = wait_event_interruptible(WaitQueueProcess_g, - (atomic_read - (&AtomicEventState_g) - == EVENT_STATE_READY) - || - (atomic_read - (&AtomicEventState_g) - == EVENT_STATE_TERM)); - if (iErr != 0) { // waiting was interrupted by signal - // pass control to event queue kernel thread, but signal termination - atomic_set(&AtomicEventState_g, - EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbEvent_g); - // exit with this error -> EplApiProcess() will leave the infinite loop - iRet = iErr; - goto Exit; - } else if (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM) { // termination in progress - // pass control to event queue kernel thread, but signal termination - wake_up_interruptible(&WaitQueueCbEvent_g); - // exit with this error -> EplApiProcess() will leave the infinite loop - iRet = 1; - goto Exit; - } - // copy event to user space - iErr = - copy_to_user(Event.m_pEventType, &EventType_g, - sizeof(EventType_g)); - if (iErr != 0) { // not all data could be copied - iRet = -EIO; - goto Exit; - } - // $$$ d.k. perform SDO event processing - if (EventType_g == kEplApiEventSdo) { - void *pData; - tEplLinSdoBufHeader *pBufHeader; - - pBufHeader = - (tEplLinSdoBufHeader *) pEventArg_g->m_Sdo. - m_pUserArg; - pData = - pBufHeader + sizeof(tEplLinSdoBufHeader); - - if (pEventArg_g->m_Sdo.m_SdoAccessType == - kEplSdoAccessTypeRead) { - // copy read data to user space - iErr = - copy_to_user(pBufHeader->m_pData, - pData, - pEventArg_g->m_Sdo. - m_uiTransferredByte); - if (iErr != 0) { // not all data could be copied - iRet = -EIO; - goto Exit; - } - } - pEventArg_g->m_Sdo.m_pUserArg = - pBufHeader->m_pUserArg; - vfree(pBufHeader); - } - - iErr = - copy_to_user(Event.m_pEventArg, pEventArg_g, - min(sizeof(tEplApiEventArg), - Event.m_uiEventArgSize)); - if (iErr != 0) { // not all data could be copied - iRet = -EIO; - goto Exit; - } - // return to EplApiProcess(), which will call the application's event callback function - iRet = 0; - - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_PI_SETUP: - { - EplRet = EplApiProcessImageSetup(); - iRet = (int)EplRet; - - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_PI_IN: - { - tEplApiProcessImage ProcessImageIn; - - // save process image structure - iErr = - copy_from_user(&ProcessImageIn, - (const void *)ulArg_p, - sizeof(ProcessImageIn)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - // pass control to event queue kernel thread - atomic_set(&AtomicSyncState_g, EVENT_STATE_IOCTL); - - // fall asleep itself in own wait queue - iErr = wait_event_interruptible(WaitQueuePI_In_g, - (atomic_read - (&AtomicSyncState_g) == - EVENT_STATE_READY) - || - (atomic_read - (&AtomicSyncState_g) == - EVENT_STATE_TERM)); - if (iErr != 0) { // waiting was interrupted by signal - // pass control to sync kernel thread, but signal termination - atomic_set(&AtomicSyncState_g, - EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbSync_g); - // exit with this error -> application will leave the infinite loop - iRet = iErr; - goto Exit; - } else if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM) { // termination in progress - // pass control to sync kernel thread, but signal termination - wake_up_interruptible(&WaitQueueCbSync_g); - // exit with this error -> application will leave the infinite loop - iRet = 1; - goto Exit; - } - // exchange process image - EplRet = EplApiProcessImageExchangeIn(&ProcessImageIn); - - // return to EplApiProcessImageExchangeIn() - iRet = (int)EplRet; - - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_PI_OUT: - { - tEplApiProcessImage ProcessImageOut; - - // save process image structure - iErr = - copy_from_user(&ProcessImageOut, - (const void *)ulArg_p, - sizeof(ProcessImageOut)); - if (iErr != 0) { - iRet = -EIO; - goto Exit; - } - - if (atomic_read(&AtomicSyncState_g) != - EVENT_STATE_READY) { - iRet = (int)kEplInvalidOperation; - goto Exit; - } - // exchange process image - EplRet = - EplApiProcessImageExchangeOut(&ProcessImageOut); - - // pass control to sync kernel thread - atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM); - wake_up_interruptible(&WaitQueueCbSync_g); - - // return to EplApiProcessImageExchangeout() - iRet = (int)EplRet; - - break; - } - - // ---------------------------------------------------------- - case EPLLIN_CMD_NMT_COMMAND: - { - // forward NMT command to EPL stack - EplRet = EplApiExecNmtCommand((tEplNmtEvent) ulArg_p); - - iRet = (int)EplRet; - - break; - } - - // ---------------------------------------------------------- - default: - { - break; - } - } - - Exit: - -// TRACE1("EPL: - EplLinIoctl (iRet=%d)\n", iRet); - return (iRet); - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p) -{ - tEplKernel EplRet = kEplSuccessful; - int iErr; - - // block any further call to this function, i.e. enter critical section - iErr = down_interruptible(&SemaphoreCbEvent_g); - if (iErr != 0) { // waiting was interrupted by signal - EplRet = kEplShutdown; - goto Exit; - } - // wait for EplApiProcess() to call ioctl - // normally it should be waiting already for us to pass a new event - iErr = wait_event_interruptible(WaitQueueCbEvent_g, - (atomic_read(&AtomicEventState_g) == - EVENT_STATE_IOCTL) - || (atomic_read(&AtomicEventState_g) == - EVENT_STATE_TERM)); - if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM)) { // waiting was interrupted by signal - EplRet = kEplShutdown; - goto LeaveCriticalSection; - } - // save event information for ioctl - EventType_g = EventType_p; - pEventArg_g = pEventArg_p; - - // pass control to application's event callback function, i.e. EplApiProcess() - atomic_set(&AtomicEventState_g, EVENT_STATE_READY); - wake_up_interruptible(&WaitQueueProcess_g); - - // now, the application's event callback function processes the event - - // wait for completion of application's event callback function, i.e. EplApiProcess() calls ioctl again - iErr = wait_event_interruptible(WaitQueueCbEvent_g, - (atomic_read(&AtomicEventState_g) == - EVENT_STATE_IOCTL) - || (atomic_read(&AtomicEventState_g) == - EVENT_STATE_TERM)); - if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM)) { // waiting was interrupted by signal - EplRet = kEplShutdown; - goto LeaveCriticalSection; - } - // read return code from application's event callback function - EplRet = RetCbEvent_g; - - LeaveCriticalSection: - up(&SemaphoreCbEvent_g); - - Exit: - // check if NMT_GS_OFF is reached - if (EventType_p == kEplApiEventNmtStateChange) { - if (pEventArg_p->m_NmtStateChange.m_NewNmtState == kEplNmtGsOff) { // NMT state machine was shut down - TRACE0("EPL: EplLinCbEvent(NMT_GS_OFF)\n"); - uiEplState_g = EPL_STATE_SHUTDOWN; - atomic_set(&AtomicEventState_g, EVENT_STATE_TERM); - wake_up(&WaitQueueRelease_g); - } else { // NMT state machine is running - uiEplState_g = EPL_STATE_RUNNING; - } - } - - return EplRet; -} - -tEplKernel EplLinCbSync(void) -{ - tEplKernel EplRet = kEplSuccessful; - int iErr; - - // check if user process waits for sync - if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_IOCTL) { - // pass control to application, i.e. EplApiProcessImageExchangeIn() - atomic_set(&AtomicSyncState_g, EVENT_STATE_READY); - wake_up_interruptible(&WaitQueuePI_In_g); - - // now, the application processes the sync event - - // wait for call of EplApiProcessImageExchangeOut() - iErr = wait_event_interruptible(WaitQueueCbSync_g, - (atomic_read(&AtomicSyncState_g) - == EVENT_STATE_IOCTL) - || - (atomic_read(&AtomicSyncState_g) - == EVENT_STATE_TERM)); - if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_IOCTL)) { // waiting was interrupted by signal or application called wrong function - EplRet = kEplShutdown; - } - } else { // application is currently not waiting for sync - // continue without interruption - // TPDO are set valid by caller (i.e. EplEventkProcess()) - } - - TGT_DBG_SIGNAL_TRACE_POINT(1); - - return EplRet; -} - -// EOF diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c deleted file mode 100644 index 7d55086a8e4..00000000000 --- a/drivers/staging/epl/EplApiProcessImage.c +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for EPL API module (process image) - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplApiProcessImage.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.7 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/10/10 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "Epl.h" - -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplApi */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0)) -typedef struct { -#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0 - u8 m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN]; -#endif -#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0 - u8 m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT]; -#endif - -} tEplApiProcessImageInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplApiProcessImageInstance EplApiProcessImageInstance_g; -#endif - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplApiProcessImageSetup() -// -// Description: sets up static process image -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplApiProcessImageSetup(void) -{ - tEplKernel Ret = kEplSuccessful; -#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0)) - unsigned int uiVarEntries; - tEplObdSize ObdSize; -#endif - -#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0 - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN; - ObdSize = 1; - Ret = EplApiLinkObject(0x2000, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); - - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN; - ObdSize = 1; - Ret = EplApiLinkObject(0x2001, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 2; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize; - Ret = EplApiLinkObject(0x2010, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 2; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize; - Ret = EplApiLinkObject(0x2011, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 4; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize; - Ret = EplApiLinkObject(0x2020, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 4; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize; - Ret = EplApiLinkObject(0x2021, - EplApiProcessImageInstance_g. - m_abProcessImageInput, &uiVarEntries, &ObdSize, - 1); -#endif - -#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0 - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT; - ObdSize = 1; - Ret = EplApiLinkObject(0x2030, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); - - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT; - ObdSize = 1; - Ret = EplApiLinkObject(0x2031, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 2; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize; - Ret = EplApiLinkObject(0x2040, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 2; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize; - Ret = EplApiLinkObject(0x2041, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 4; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize; - Ret = EplApiLinkObject(0x2050, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); - - ObdSize = 4; - uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize; - Ret = EplApiLinkObject(0x2051, - EplApiProcessImageInstance_g. - m_abProcessImageOutput, &uiVarEntries, &ObdSize, - 1); -#endif - - return Ret; -} - -//---------------------------------------------------------------------------- -// Function: EplApiProcessImageExchangeIn() -// -// Description: replaces passed input process image with the one of EPL stack -// -// Parameters: pPI_p = input process image -// -// Returns: tEplKernel = error code -// -// State: -//---------------------------------------------------------------------------- - -tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0 - copy_to_user(pPI_p->m_pImage, - EplApiProcessImageInstance_g.m_abProcessImageInput, - min(pPI_p->m_uiSize, - sizeof(EplApiProcessImageInstance_g. - m_abProcessImageInput))); -#endif - - return Ret; -} - -//---------------------------------------------------------------------------- -// Function: EplApiProcessImageExchangeOut() -// -// Description: copies passed output process image to EPL stack. -// -// Parameters: pPI_p = output process image -// -// Returns: tEplKernel = error code -// -// State: -//---------------------------------------------------------------------------- - -tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0 - copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput, - pPI_p->m_pImage, - min(pPI_p->m_uiSize, - sizeof(EplApiProcessImageInstance_g. - m_abProcessImageOutput))); -#endif - - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -// EOF diff --git a/drivers/staging/epl/EplCfg.h b/drivers/staging/epl/EplCfg.h deleted file mode 100644 index 38e958a042a..00000000000 --- a/drivers/staging/epl/EplCfg.h +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: configuration file - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplCfg.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/06 k.t.: Start of Implementation - -****************************************************************************/ - -#ifndef _EPLCFG_H_ -#define _EPLCFG_H_ - -// ========================================================================= -// generic defines which for whole EPL Stack -// ========================================================================= -#define EPL_USE_DELETEINST_FUNC TRUE - -// needed to support datatypes over 32 bit by global.h -#define USE_VAR64 - -// EPL_MAX_INSTANCES specifies count of instances of all EPL modules. -// If it is greater than 1 the first parameter of all -// functions is the instance number. -#define EPL_MAX_INSTANCES 1 - -// This defines the target hardware. Here is encoded wich CPU and wich external -// peripherals are connected. For possible values refere to target.h. If -// necessary value is not available EPL stack has to -// be adapted and tested. -#define TARGET_HARDWARE TGTHW_PC_WRAPP - -// use no FIFOs, make direct calls -//#define EPL_NO_FIFO - -// use no IPC between user- and kernelspace modules, make direct calls -#define EPL_NO_USER_KERNEL - -#ifndef BENCHMARK_MODULES -#define BENCHMARK_MODULES 0 //0xEE800042L -#endif - -// Default defug level: -// Only debug traces of these modules will be compiled which flags are set in define DEF_DEBUG_LVL. -#ifndef DEF_DEBUG_LVL -#define DEF_DEBUG_LVL 0xEC000000L -#endif -// EPL_DBGLVL_OBD = 0x00000004L -// * EPL_DBGLVL_ASSERT = 0x20000000L -// * EPL_DBGLVL_ERROR = 0x40000000L -// * EPL_DBGLVL_ALWAYS = 0x80000000L - -// EPL_MODULE_INTEGRATION defines all modules which are included in -// EPL application. Please add or delete modules for your application. -#define EPL_MODULE_INTEGRATION EPL_MODULE_OBDK \ - | EPL_MODULE_PDOK \ - | EPL_MODULE_NMT_MN \ - | EPL_MODULE_SDOS \ - | EPL_MODULE_SDOC \ - | EPL_MODULE_SDO_ASND \ - | EPL_MODULE_SDO_UDP \ - | EPL_MODULE_NMT_CN \ - | EPL_MODULE_NMTU \ - | EPL_MODULE_NMTK \ - | EPL_MODULE_DLLK \ - | EPL_MODULE_DLLU \ - | EPL_MODULE_VETH -// | EPL_MODULE_OBDU - -// ========================================================================= -// EPL ethernet driver (Edrv) specific defines -// ========================================================================= - -// switch this define to TRUE if Edrv supports fast tx frames -#define EDRV_FAST_TXFRAMES FALSE -//#define EDRV_FAST_TXFRAMES TRUE - -// switch this define to TRUE if Edrv supports early receive interrupts -#define EDRV_EARLY_RX_INT FALSE -//#define EDRV_EARLY_RX_INT TRUE - -// enables setting of several port pins for benchmarking purposes -#define EDRV_BENCHMARK FALSE -//#define EDRV_BENCHMARK TRUE // MCF_GPIO_PODR_PCIBR - -// Call Tx handler (i.e. EplDllCbFrameTransmitted()) already if DMA has finished, -// otherwise call the Tx handler if frame was actually transmitted over ethernet. -#define EDRV_DMA_TX_HANDLER FALSE -//#define EDRV_DMA_TX_HANDLER TRUE - -// number of used ethernet controller -//#define EDRV_USED_ETH_CTRL 1 - -// ========================================================================= -// Data Link Layer (DLL) specific defines -// ========================================================================= - -// switch this define to TRUE if Edrv supports fast tx frames -// and DLL shall pass PRes as ready to Edrv after SoC -#define EPL_DLL_PRES_READY_AFTER_SOC FALSE -//#define EPL_DLL_PRES_READY_AFTER_SOC TRUE - -// switch this define to TRUE if Edrv supports fast tx frames -// and DLL shall pass PRes as ready to Edrv after SoA -#define EPL_DLL_PRES_READY_AFTER_SOA FALSE -//#define EPL_DLL_PRES_READY_AFTER_SOA TRUE - -// ========================================================================= -// OBD specific defines -// ========================================================================= - -// switch this define to TRUE if Epl should compare object range -// automaticly -#define EPL_OBD_CHECK_OBJECT_RANGE FALSE -//#define EPL_OBD_CHECK_OBJECT_RANGE TRUE - -// set this define to TRUE if there are strings or domains in OD, which -// may be changed in object size and/or object data pointer by its object -// callback function (called event kObdEvWrStringDomain) -//#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM FALSE -#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM TRUE - -#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB TRUE - -// ========================================================================= -// Timer module specific defines -// ========================================================================= - -// if TRUE it uses the Timer module implementation of EPL user also in EPL kernel -#define EPL_TIMER_USE_USER TRUE - -// if TRUE the high resolution timer module will be used -#define EPL_TIMER_USE_HIGHRES TRUE -//#define EPL_TIMER_USE_HIGHRES FALSE - -#endif //_EPLCFG_H_ diff --git a/drivers/staging/epl/EplDef.h b/drivers/staging/epl/EplDef.h deleted file mode 100644 index 1dc8108449c..00000000000 --- a/drivers/staging/epl/EplDef.h +++ /dev/null @@ -1,355 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL default constants - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDef.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.15 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DEF_H_ -#define _EPL_DEF_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_C_ADR_BROADCAST 0xFF // EPL broadcast address -#define EPL_C_ADR_DIAG_DEF_NODE_ID 0xFD // EPL default address of dignostic device -#define EPL_C_ADR_DUMMY_NODE_ID 0xFC // EPL dummy node address -#define EPL_C_ADR_INVALID 0x00 // invalid EPL address -#define EPL_C_ADR_MN_DEF_NODE_ID 0xF0 // EPL default address of MN -#define EPL_C_ADR_RT1_DEF_NODE_ID 0xFE // EPL default address of router type 1 -#define EPL_C_DLL_ASND_PRIO_NMTRQST 7 // increased ASnd request priority to be used by NMT Requests -#define EPL_C_DLL_ASND_PRIO_STD 0 // standard ASnd request priority -#define EPL_C_DLL_ETHERTYPE_EPL 0x88AB -#define EPL_C_DLL_ISOCHR_MAX_PAYL 1490 // Byte: maximum size of PReq and PRes payload data, requires C_IP_MAX_MTU -#define EPL_C_DLL_MAX_ASYNC_MTU 1500 // Byte: maximum asynchronous payload in bytes -#define EPL_C_DLL_MAX_PAYL_OFFSET 1499 // Byte: maximum offset of Ethernet frame payload, requires C_IP_MAX_MTU -#define EPL_C_DLL_MAX_RS 7 -#define EPL_C_DLL_MIN_ASYNC_MTU 282 // Byte: minimum asynchronous payload in bytes. -#define EPL_C_DLL_MIN_PAYL_OFFSET 45 // Byte: minimum offset of Ethernet frame payload -#define EPL_C_DLL_MULTICAST_ASND 0x01111E000004LL // EPL ASnd multicast MAC address, canonical form -#define EPL_C_DLL_MULTICAST_PRES 0x01111E000002LL // EPL PRes multicast MAC address, canonical form -#define EPL_C_DLL_MULTICAST_SOA 0x01111E000003LL // EPL SoA multicast MAC address, canonical form -#define EPL_C_DLL_MULTICAST_SOC 0x01111E000001LL // EPL Soc multicast MAC address, canonical form -#define EPL_C_DLL_PREOP1_START_CYCLES 10 // number of unassigning SoA frames at start of NMT_MS_PRE_OPERATIONAL_1 -#define EPL_C_DLL_T_BITTIME 10 // ns: Transmission time per bit on 100 Mbit/s network -#define EPL_C_DLL_T_EPL_PDO_HEADER 10 // Byte: size of PReq and PRes EPL PDO message header -#define EPL_C_DLL_T_ETH2_WRAPPER 18 // Byte: size of Ethernet type II wrapper consisting of header and checksum -#define EPL_C_DLL_T_IFG 640 // ns: Ethernet Interframe Gap -#define EPL_C_DLL_T_MIN_FRAME 5120 // ns: Size of minimum Ethernet frame (without preamble) -#define EPL_C_DLL_T_PREAMBLE 960 // ns: Size of Ethernet frame preamble - -#define EPL_C_DLL_MINSIZE_SOC 36 // minimum size of SoC without padding and CRC -#define EPL_C_DLL_MINSIZE_PREQ 60 // minimum size of PRec without CRC -#define EPL_C_DLL_MINSIZE_PRES 60 // minimum size of PRes without CRC -#define EPL_C_DLL_MINSIZE_SOA 24 // minimum size of SoA without padding and CRC -#define EPL_C_DLL_MINSIZE_IDENTRES 176 // minimum size of IdentResponse without CRC -#define EPL_C_DLL_MINSIZE_STATUSRES 72 // minimum size of StatusResponse without CRC -#define EPL_C_DLL_MINSIZE_NMTCMD 20 // minimum size of NmtCommand without CommandData, padding and CRC -#define EPL_C_DLL_MINSIZE_NMTCMDEXT 52 // minimum size of NmtCommand without padding and CRC -#define EPL_C_DLL_MINSIZE_NMTREQ 20 // minimum size of NmtRequest without CommandData, padding and CRC -#define EPL_C_DLL_MINSIZE_NMTREQEXT 52 // minimum size of NmtRequest without padding and CRC - -#define EPL_C_ERR_MONITOR_DELAY 10 // Error monitoring start delay (not used in DS 1.0.0) -#define EPL_C_IP_ADR_INVALID 0x00000000L // invalid IP address (0.0.0.0) used to indicate no change -#define EPL_C_IP_INVALID_MTU 0 // Byte: invalid MTU size used to indicate no change -#define EPL_C_IP_MAX_MTU 1518 // Byte: maximum size in bytes of the IP stack which must be processed. -#define EPL_C_IP_MIN_MTU 300 // Byte: minimum size in bytes of the IP stack which must be processed. -#define EPL_C_NMT_STATE_TOLERANCE 5 // Cycles: maximum reaction time to NMT state commands -#define EPL_C_NMT_STATREQ_CYCLE 5 // sec: StatusRequest cycle time to be applied to AsyncOnly CNs -#define EPL_C_SDO_EPL_PORT 3819 - -#define EPL_C_DLL_MAX_ASND_SERVICE_IDS 5 // see tEplDllAsndServiceId in EplDll.h - -// Default configuration -// ====================== - -#ifndef EPL_D_PDO_Granularity_U8 -#define EPL_D_PDO_Granularity_U8 8 // minimum size of objects to be mapped in bits UNSIGNED8 O O 1 1 -#endif - -#ifndef EPL_NMT_MAX_NODE_ID -#define EPL_NMT_MAX_NODE_ID 254 // maximum node-ID -#endif - -#ifndef EPL_D_NMT_MaxCNNumber_U8 -#define EPL_D_NMT_MaxCNNumber_U8 239 // maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239 -#endif - -// defines for EPL API layer static process image -#ifndef EPL_API_PROCESS_IMAGE_SIZE_IN -#define EPL_API_PROCESS_IMAGE_SIZE_IN 0 -#endif - -#ifndef EPL_API_PROCESS_IMAGE_SIZE_OUT -#define EPL_API_PROCESS_IMAGE_SIZE_OUT 0 -#endif - -// configure whether OD access events shall be forwarded -// to user callback function. -// Because of reentrancy for local OD accesses, this has to be disabled -// when application resides in other address space as the stack (e.g. if -// EplApiLinuxUser.c and EplApiLinuxKernel.c are used) -#ifndef EPL_API_OBD_FORWARD_EVENT -#define EPL_API_OBD_FORWARD_EVENT TRUE -#endif - -#ifndef EPL_OBD_MAX_STRING_SIZE -#define EPL_OBD_MAX_STRING_SIZE 32 // is used for objects 0x1008/0x1009/0x100A -#endif - -#ifndef EPL_OBD_USE_STORE_RESTORE -#define EPL_OBD_USE_STORE_RESTORE FALSE -#endif - -#ifndef EPL_OBD_CHECK_OBJECT_RANGE -#define EPL_OBD_CHECK_OBJECT_RANGE TRUE -#endif - -#ifndef EPL_OBD_USE_STRING_DOMAIN_IN_RAM -#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM TRUE -#endif - -#ifndef EPL_OBD_USE_VARIABLE_SUBINDEX_TAB -#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB TRUE -#endif - -#ifndef EPL_OBD_USE_KERNEL -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) -#define EPL_OBD_USE_KERNEL TRUE -#else -#define EPL_OBD_USE_KERNEL FALSE -#endif -#endif - -#ifndef EPL_OBD_INCLUDE_A000_TO_DEVICE_PART -#define EPL_OBD_INCLUDE_A000_TO_DEVICE_PART FALSE -#endif - -#ifndef EPL_VETH_NAME -#define EPL_VETH_NAME "epl" // name of net device in Linux -#endif - -/* -#define EPL_D_CFG_ConfigManager_BOOL // Ability of a MN node to perform Configuration Manager functions BOOLEAN O - N - -#define EPL_D_CFM_VerifyConf_BOOL // Support of objects CFM_VerifyConfiguration_REC, CFM_ExpConfDateList_AU32, CFM_ExpConfTimeList_AU32 BOOLEAN O O N N -#define EPL_D_CFM_VerifyConfId_BOOL // Support of objects CFM_VerifyConfiguration_REC.ConfId_U32 and CFM_ExpConfIdList_AU32 BOOLEAN O O N N -#define EPL_D_DLL_CNFeatureIsochr_BOOL // CN’s ability to perform isochronous functions BOOLEAN - O - Y -#define EPL_D_DLL_CNFeatureMultiplex_BOOL // node’s ability to perform control of multiplexed isochronous communication BOOLEAN - O - N -#define EPL_D_DLL_FeatureCN_BOOL // node’s ability to perform CN functions BOOLEAN O O Y Y -#define EPL_D_DLL_FeatureMN_BOOL // node’s ability to perform MN functions BOOLEAN M O - N -#define EPL_D_DLL_MNFeatureMultiplex_BOOL // MN’s ability to perform control of multiplexed isochronous communication BOOLEAN O - Y - -#define EPL_D_DLL_MNFeaturePResTx_BOOL // MN’s ability to transmit PRes BOOLEAN O - Y - -#define EPL_D_NMT_ASndRxMaxPayload_U16 // size of ASnd frame receive buffer UNSIGNED16 M M - - -#define EPL_D_NMT_ASndTxMaxPayload_U16 // size of ASnd frame transmit buffer UNSIGNED16 M M - - -#define EPL_D_NMT_CNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of reception of SoC UNSIGNED32 - M - - -#define EPL_D_NMT_CNASndMaxLatency_U32 // delay between end of SoA reception and start of ASnd transmission UNSIGNED32 - M - - -#define EPL_D_NMT_CNPResMaxLatency_U32 // delay between end of PReq reception and start of PRes transmission UNSIGNED32 - M - - -#define EPL_D_NMT_CNSoC2PReq_U32 // CN SoC handling maximum time, a subsequent PReq won’t be handled before SoC handling was finished UNSIGNED32 - M - - -#define EPL_D_NMT_DeviceType_U32 // Device Type ID UNSIGNED32 M M - - -#define EPL_D_NMT_EPLVers_U8 EPL // Version implemented by the device UNSIGNED8 M M - - -#define EPL_D_NMT_ExtStateCmd_BOOL // abitilty to support Extended NMT State Commands BOOLEAN O O Y Y -#define EPL_D_NMT_InfoSvc_BOOL // ability to support NMT Info Services BOOLEAN O - Y - -#define EPL_D_NMT_InterfaceAddr_Xh_OSTR // Physical Address of Interface No. Xh OCTET_STRING M M - - -#define EPL_D_NMT_InterfaceDescr_Xh_VSTR // Description text of Interface No. Xh VISIBLE_STRINGM M - - -#define EPL_D_NMT_InterfaceMtu_Xh_U32 // MTU of Interface No. Xh UNSIGNED32 M M - - -#define EPL_D_NMT_InterfaceType_Xh_U8 // Type of Interface No. Xh UNSIGNED8 M M - - -#define EPL_D_NMT_IsochrRxMaxPayload_U16 // size of isochronous frame receive buffer UNSIGNED16 M M - - -#define EPL_D_NMT_IsochrTxMaxPayload_U16 // size of isochronous frame transmit buffer UNSIGNED16 M M - - -#define EPL_D_NMT_ManufactDevName_VS // Manufacturer Device Name VISIBLE_STRING O O - - -#define EPL_D_NMT_ManufactHwVers_VS // Manufacturer HW version VISIBLE_STRING O O - - -#define EPL_D_NMT_ManufactSwVers_VS // Manufacturer SW version VISIBLE_STRING O O - - -#define EPL_D_NMT_MaxCNNodeID_U8 // maximum Node ID available for regular CNs the entry provides an upper limit to the NodeID available for cross traffic PDO reception from a regular CN UNSIGNED8 O O 239 239 -#define EPL_D_NMT_MaxCNNumber_U8 // maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239 -#define EPL_D_NMT_MaxHeartbeats_U8 // number of guard channels UNSIGNED8 O O 254 254 -#define EPL_D_NMT_MNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of transmission of SoC UNSIGNED32 M - - - -#define EPL_D_NMT_MNMultiplCycMax_U8 // maximum number of EPL cycles per multiplexed cycle UNSIGNED8 O - 0 - -#define EPL_D_NMT_MNPRes2PReq_U32 // delay between end of PRes reception and start of PReq transmission UNSIGNED32 M - - - -#define EPL_D_NMT_MNPRes2PRes_U32 // delay between end of reception of PRes from CNn and start of transmission of PRes by MN UNSIGNED32 M - - - -#define EPL_D_NMT_MNPResRx2SoA_U32 // delay between end of reception of PRes from CNn and start of transmission of SoA by MN UNSIGNED32 M - - - -#define EPL_D_NMT_MNPResTx2SoA_U32 // delay between end of PRes transmission by MN and start of transmission of SoA by MN UNSIGNED32 M - - - -#define EPL_D_NMT_MNSoA2ASndTx_U32 // delay between end of transmission of SoA and start of transmission of ASnd by MN UNSIGNED32 M - - - -#define EPL_D_NMT_MNSoC2PReq_U32 // MN minimum delay between end of SoC transmission and start of PReq transmission UNSIGNED32 M - - - -#define EPL_D_NMT_NMTSvcViaUDPIP_BOOL // Ability of a node to perform NMT services via UDP/IP BOOLEAN O - Y - -#define EPL_D_NMT_NodeIDByHW_BOOL // Ability of a node to support NodeID setup by HW BOOLEAN O O Y Y -#define EPL_D_NMT_NodeIDBySW_BOOL // Ability of a node to support NodeID setup by SW BOOLEAN O O N N -#define EPL_D_NMT_ProductCode_U32 // Identity Object Product Code UNSIGNED32 M M - - -#define EPL_D_NMT_RevisionNo_U32 // Identity Object Revision Number UNSIGNED32 M M - - -#define EPL_D_NMT_SerialNo_U32 // Identity Object Serial Number UNSIGNED32 M M - - -#define EPL_D_NMT_SimpleBoot_BOOL // Ability of a MN node to perform Simple Boot Process, if not set Indivual Boot Process shall be proviced BOOLEAN M - - - -#define EPL_D_NMT_VendorID_U32 // Identity Object Vendor ID UNSIGNED32 M M - - -#define EPL_D_NWL_Forward_BOOL // Ability of node to forward datagrams BOOLEAN O O N N -#define EPL_D_NWL_IPSupport_BOOL // Ability of the node cummunicate via IP BOOLEAN - - Y Y -#define EPL_D_PDO_DynamicMapping_BOOL // Ability of a node to perform dynamic PDO mapping BOOLEAN O O Y Y -#define EPL_D_PDO_MaxDescrMem_U32 // maximum cumulative memory consumption of TPDO and RPDO describing objects in byte UNSIGNED32 O O MAX_U32 MAX_U32 -#define EPL_D_PDO_RPDOChannels_U8 // number of supported RPDO channels UNSIGNED8 O O 256 256 -#define EPL_D_PDO_RPDOMaxMem_U32 // Maximum memory available for RPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32 -#define EPL_D_PDO_RPDOObjects_U8 // Number of supported mapped objects per RPDO channel UNSIGNED8 O O 254 254 -#define EPL_D_PDO_TPDOChannels_U8 // number of supported TPDO channels UNSIGNED8 O - 256 - -#define EPL_D_PDO_TPDOMaxMem_U32 // Maximum memory available for TPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32 -#define EPL_D_PDO_TPDOObjects_U8 // Number of supported mapped objects per TPDO channel UNSIGNED8 O O 254 254 -#define EPL_D_SDO_ViaASnd_BOOL // Ability of a CN to perform SDO transfer by EPL ASnd BOOLEAN - M - - -#define EPL_D_SDO_ViaPDO_BOOL // Ability of a node to perform SDO transfer by PDO BOOLEAN O O N N -#define EPL_D_SDO_ViaUDPIP_BOOL // Ability of a CN to perform SDO transfer by UDP/IP BOOLEAN - M - - -#define EPL_D_SYN_OptimizedSync_BOOL // Ability of node to perform optimized synchronisation BOOLEAN O O N N -*/ - -// Emergency error codes -// ====================== -#define EPL_E_NO_ERROR 0x0000 -// 0xFxxx manufacturer specific error codes -#define EPL_E_NMT_NO_IDENT_RES 0xF001 -#define EPL_E_NMT_NO_STATUS_RES 0xF002 - -// 0x816x HW errors -#define EPL_E_DLL_BAD_PHYS_MODE 0x8161 -#define EPL_E_DLL_COLLISION 0x8162 -#define EPL_E_DLL_COLLISION_TH 0x8163 -#define EPL_E_DLL_CRC_TH 0x8164 -#define EPL_E_DLL_LOSS_OF_LINK 0x8165 -#define EPL_E_DLL_MAC_BUFFER 0x8166 -// 0x82xx Protocol errors -#define EPL_E_DLL_ADDRESS_CONFLICT 0x8201 -#define EPL_E_DLL_MULTIPLE_MN 0x8202 -// 0x821x Frame size errors -#define EPL_E_PDO_SHORT_RX 0x8210 -#define EPL_E_PDO_MAP_VERS 0x8211 -#define EPL_E_NMT_ASND_MTU_DIF 0x8212 -#define EPL_E_NMT_ASND_MTU_LIM 0x8213 -#define EPL_E_NMT_ASND_TX_LIM 0x8214 -// 0x823x Timing errors -#define EPL_E_NMT_CYCLE_LEN 0x8231 -#define EPL_E_DLL_CYCLE_EXCEED 0x8232 -#define EPL_E_DLL_CYCLE_EXCEED_TH 0x8233 -#define EPL_E_NMT_IDLE_LIM 0x8234 -#define EPL_E_DLL_JITTER_TH 0x8235 -#define EPL_E_DLL_LATE_PRES_TH 0x8236 -#define EPL_E_NMT_PREQ_CN 0x8237 -#define EPL_E_NMT_PREQ_LIM 0x8238 -#define EPL_E_NMT_PRES_CN 0x8239 -#define EPL_E_NMT_PRES_RX_LIM 0x823A -#define EPL_E_NMT_PRES_TX_LIM 0x823B -// 0x824x Frame errors -#define EPL_E_DLL_INVALID_FORMAT 0x8241 -#define EPL_E_DLL_LOSS_PREQ_TH 0x8242 -#define EPL_E_DLL_LOSS_PRES_TH 0x8243 -#define EPL_E_DLL_LOSS_SOA_TH 0x8244 -#define EPL_E_DLL_LOSS_SOC_TH 0x8245 -// 0x84xx BootUp Errors -#define EPL_E_NMT_BA1 0x8410 // other MN in MsNotActive active -#define EPL_E_NMT_BA1_NO_MN_SUPPORT 0x8411 // MN is not supported -#define EPL_E_NMT_BPO1 0x8420 // mandatory CN was not found or failed in BootStep1 -#define EPL_E_NMT_BPO1_GET_IDENT 0x8421 // IdentRes was not received -#define EPL_E_NMT_BPO1_DEVICE_TYPE 0x8422 // wrong device type -#define EPL_E_NMT_BPO1_VENDOR_ID 0x8423 // wrong vendor ID -#define EPL_E_NMT_BPO1_PRODUCT_CODE 0x8424 // wrong product code -#define EPL_E_NMT_BPO1_REVISION_NO 0x8425 // wrong revision number -#define EPL_E_NMT_BPO1_SERIAL_NO 0x8426 // wrong serial number -#define EPL_E_NMT_BPO1_CF_VERIFY 0x8428 // verification of configuration failed -#define EPL_E_NMT_BPO2 0x8430 // mandatory CN failed in BootStep2 -#define EPL_E_NMT_BRO 0x8440 // CheckCommunication failed for mandatory CN -#define EPL_E_NMT_WRONG_STATE 0x8480 // mandatory CN has wrong NMT state - -// Defines for object 0x1F80 NMT_StartUp_U32 -// ========================================== -#define EPL_NMTST_STARTALLNODES 0x00000002L // Bit 1 -#define EPL_NMTST_NO_AUTOSTART 0x00000004L // Bit 2 -#define EPL_NMTST_NO_STARTNODE 0x00000008L // Bit 3 -#define EPL_NMTST_RESETALL_MAND_CN 0x00000010L // Bit 4 -#define EPL_NMTST_STOPALL_MAND_CN 0x00000040L // Bit 6 -#define EPL_NMTST_NO_AUTOPREOP2 0x00000080L // Bit 7 -#define EPL_NMTST_NO_AUTOREADYTOOP 0x00000100L // Bit 8 -#define EPL_NMTST_EXT_CNIDENTCHECK 0x00000200L // Bit 9 -#define EPL_NMTST_SWVERSIONCHECK 0x00000400L // Bit 10 -#define EPL_NMTST_CONFCHECK 0x00000800L // Bit 11 -#define EPL_NMTST_NO_RETURN_PREOP1 0x00001000L // Bit 12 -#define EPL_NMTST_BASICETHERNET 0x00002000L // Bit 13 - -// Defines for object 0x1F81 NMT_NodeAssignment_AU32 -// ================================================== -#define EPL_NODEASSIGN_NODE_EXISTS 0x00000001L // Bit 0 -#define EPL_NODEASSIGN_NODE_IS_CN 0x00000002L // Bit 1 -#define EPL_NODEASSIGN_START_CN 0x00000004L // Bit 2 -#define EPL_NODEASSIGN_MANDATORY_CN 0x00000008L // Bit 3 -#define EPL_NODEASSIGN_KEEPALIVE 0x00000010L //currently not used in EPL V2 standard -#define EPL_NODEASSIGN_SWVERSIONCHECK 0x00000020L // Bit 5 -#define EPL_NODEASSIGN_SWUPDATE 0x00000040L // Bit 6 -#define EPL_NODEASSIGN_ASYNCONLY_NODE 0x00000100L // Bit 8 -#define EPL_NODEASSIGN_MULTIPLEXED_CN 0x00000200L // Bit 9 -#define EPL_NODEASSIGN_RT1 0x00000400L // Bit 10 -#define EPL_NODEASSIGN_RT2 0x00000800L // Bit 11 -#define EPL_NODEASSIGN_MN_PRES 0x00001000L // Bit 12 -#define EPL_NODEASSIGN_VALID 0x80000000L // Bit 31 - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_DEF_H_ diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h deleted file mode 100644 index b960199bd0e..00000000000 --- a/drivers/staging/epl/EplDll.h +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for DLL module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDll.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/08 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLL_H_ -#define _EPL_DLL_H_ - -#include "EplInc.h" -#include "EplFrame.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_DLL_MAX_ASND_SERVICE_ID -#define EPL_DLL_MAX_ASND_SERVICE_ID (EPL_C_DLL_MAX_ASND_SERVICE_IDS + 1) // last is kEplDllAsndSdo == 5 -#endif - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef enum { - kEplDllAsndNotDefined = 0x00, - kEplDllAsndIdentResponse = 0x01, - kEplDllAsndStatusResponse = 0x02, - kEplDllAsndNmtRequest = 0x03, - kEplDllAsndNmtCommand = 0x04, - kEplDllAsndSdo = 0x05 -} tEplDllAsndServiceId; - -typedef enum { - kEplDllAsndFilterNone = 0x00, - kEplDllAsndFilterLocal = 0x01, // receive only ASnd frames with local or broadcast node ID - kEplDllAsndFilterAny = 0x02, // receive any ASnd frame -} tEplDllAsndFilter; - -typedef enum { - kEplDllReqServiceNo = 0x00, - kEplDllReqServiceIdent = 0x01, - kEplDllReqServiceStatus = 0x02, - kEplDllReqServiceNmtRequest = 0x03, - kEplDllReqServiceUnspecified = 0xFF, - -} tEplDllReqServiceId; - -typedef enum { - kEplDllAsyncReqPrioNmt = 0x07, // PRIO_NMT_REQUEST - kEplDllAsyncReqPrio6 = 0x06, - kEplDllAsyncReqPrio5 = 0x05, - kEplDllAsyncReqPrio4 = 0x04, - kEplDllAsyncReqPrioGeneric = 0x03, // PRIO_GENERIC_REQUEST - kEplDllAsyncReqPrio2 = 0x02, // till WSP 0.1.3: PRIO_ABOVE_GENERIC - kEplDllAsyncReqPrio1 = 0x01, // till WSP 0.1.3: PRIO_BELOW_GENERIC - kEplDllAsyncReqPrio0 = 0x00, // till WSP 0.1.3: PRIO_GENERIC_REQUEST - -} tEplDllAsyncReqPriority; - -typedef struct { - unsigned int m_uiFrameSize; - tEplFrame *m_pFrame; - tEplNetTime m_NetTime; - -} tEplFrameInfo; - -typedef struct { - unsigned int m_uiSizeOfStruct; - BOOL m_fAsyncOnly; // do not need to register PRes-Frame - unsigned int m_uiNodeId; // local node ID - - // 0x1F82: NMT_FeatureFlags_U32 - u32 m_dwFeatureFlags; - // Cycle Length (0x1006: NMT_CycleLen_U32) in [us] - u32 m_dwCycleLen; // required for error detection - // 0x1F98: NMT_CycleTiming_REC - // 0x1F98.1: IsochrTxMaxPayload_U16 - unsigned int m_uiIsochrTxMaxPayload; // const - // 0x1F98.2: IsochrRxMaxPayload_U16 - unsigned int m_uiIsochrRxMaxPayload; // const - // 0x1F98.3: PResMaxLatency_U32 - u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes - // 0x1F98.4: PReqActPayloadLimit_U16 - unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+24 bytes) - // 0x1F98.5: PResActPayloadLimit_U16 - unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+24 bytes) - // 0x1F98.6: ASndMaxLatency_U32 - u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes - // 0x1F98.7: MultiplCycleCnt_U8 - unsigned int m_uiMultiplCycleCnt; // required for error detection - // 0x1F98.8: AsyncMTU_U16 - unsigned int m_uiAsyncMtu; // required to set up max frame size - // $$$ 0x1F98.9: Prescaler_U16 - // $$$ Multiplexed Slot - - // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns] - u32 m_dwLossOfFrameTolerance; - - // 0x1F8A: NMT_MNCycleTiming_REC - // 0x1F8A.1: WaitSoCPReq_U32 in [ns] - u32 m_dwWaitSocPreq; - - // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] - u32 m_dwAsyncSlotTimeout; - -} tEplDllConfigParam; - -typedef struct { - unsigned int m_uiSizeOfStruct; - u32 m_dwDeviceType; // NMT_DeviceType_U32 - u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32 - u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32 - u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32 - u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32 - u64 m_qwVendorSpecificExt1; - u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32 - u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32 - u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_dwIpAddress; - u32 m_dwSubnetMask; - u32 m_dwDefaultGateway; - u8 m_sHostname[32]; - u8 m_abVendorSpecificExt2[48]; - -} tEplDllIdentParam; - -typedef struct { - unsigned int m_uiNodeId; - u16 m_wPreqPayloadLimit; // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16 - u16 m_wPresPayloadLimit; // object 0x1F8D: NMT_PResPayloadLimitList_AU16 - u32 m_dwPresTimeout; // object 0x1F92: NMT_MNCNPResTimeout_AU32 - -} tEplDllNodeInfo; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_DLL_H_ diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h deleted file mode 100644 index 70b27b1b676..00000000000 --- a/drivers/staging/epl/EplDllCal.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for DLL Communication Abstraction Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLLCAL_H_ -#define _EPL_DLLCAL_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -/*#ifndef EPL_DLLCAL_BUFFER_ID_RX -#define EPL_DLLCAL_BUFFER_ID_RX "EplSblDllCalRx" -#endif - -#ifndef EPL_DLLCAL_BUFFER_SIZE_RX -#define EPL_DLLCAL_BUFFER_SIZE_RX 32767 -#endif -*/ -#ifndef EPL_DLLCAL_BUFFER_ID_TX_NMT -#define EPL_DLLCAL_BUFFER_ID_TX_NMT "EplSblDllCalTxNmt" -#endif - -#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_NMT -#define EPL_DLLCAL_BUFFER_SIZE_TX_NMT 32767 -#endif - -#ifndef EPL_DLLCAL_BUFFER_ID_TX_GEN -#define EPL_DLLCAL_BUFFER_ID_TX_GEN "EplSblDllCalTxGen" -#endif - -#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_GEN -#define EPL_DLLCAL_BUFFER_SIZE_TX_GEN 32767 -#endif - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct { - tEplDllAsndServiceId m_ServiceId; - tEplDllAsndFilter m_Filter; - -} tEplDllCalAsndServiceIdFilter; - -typedef struct { - tEplDllReqServiceId m_Service; - unsigned int m_uiNodeId; - u8 m_bSoaFlag1; - -} tEplDllCalIssueRequest; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_DLLKCAL_H_ diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c deleted file mode 100644 index 0572c3d0aef..00000000000 --- a/drivers/staging/epl/EplDllk.c +++ /dev/null @@ -1,4052 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for kernel DLL module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllk.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.21 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "kernel/EplDllk.h" -#include "kernel/EplDllkCal.h" -#include "kernel/EplEventk.h" -#include "kernel/EplNmtk.h" -#include "edrv.h" -#include "Benchmark.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -#include "kernel/EplPdok.h" -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) -#include "kernel/VirtualEthernet.h" -#endif - -//#if EPL_TIMER_USE_HIGHRES != FALSE -#include "kernel/EplTimerHighResk.h" -//#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) == 0) -#error "EPL module DLLK needs EPL module NMTK!" -#endif - -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) && (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) -#error "EPL module DLLK: select only one of EPL_DLL_PRES_READY_AFTER_SOA and EPL_DLL_PRES_READY_AFTER_SOC." -#endif - -#if ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) \ - && (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) -#error "EPL module DLLK: currently, EPL_DLL_PRES_READY_AFTER_* is not supported if EPL_MODULE_NMT_MN is enabled." -#endif - -#if (EDRV_FAST_TXFRAMES == FALSE) && \ - ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) -#error "EPL module DLLK: EPL_DLL_PRES_READY_AFTER_* is enabled, but not EDRV_FAST_TXFRAMES." -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif -#define EPL_DLLK_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \ - TGT_DBG_POST_TRACE_VALUE((kEplEventSinkDllk << 28) | (Event_p << 24) \ - | (uiNodeId_p << 16) | wErrorCode_p) - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplDllk */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// defines for indexes of tEplDllInstance.m_pTxFrameInfo -#define EPL_DLLK_TXFRAME_IDENTRES 0 // IdentResponse on CN / MN -#define EPL_DLLK_TXFRAME_STATUSRES 1 // StatusResponse on CN / MN -#define EPL_DLLK_TXFRAME_NMTREQ 2 // NMT Request from FIFO on CN / MN -#define EPL_DLLK_TXFRAME_NONEPL 3 // non-EPL frame from FIFO on CN / MN -#define EPL_DLLK_TXFRAME_PRES 4 // PRes on CN / MN -#define EPL_DLLK_TXFRAME_SOC 5 // SoC on MN -#define EPL_DLLK_TXFRAME_SOA 6 // SoA on MN -#define EPL_DLLK_TXFRAME_PREQ 7 // PReq on MN -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -#define EPL_DLLK_TXFRAME_COUNT (7 + EPL_D_NMT_MaxCNNumber_U8 + 2) // on MN: 7 + MaxPReq of regular CNs + 1 Diag + 1 Router -#else -#define EPL_DLLK_TXFRAME_COUNT 5 // on CN: 5 -#endif - -#define EPL_DLLK_BUFLEN_EMPTY 0 // buffer is empty -#define EPL_DLLK_BUFLEN_FILLING 1 // just the buffer is being filled -#define EPL_DLLK_BUFLEN_MIN 60 // minimum ethernet frame length - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef enum { - kEplDllGsInit = 0x00, // MN/CN: initialisation (< PreOp2) - kEplDllCsWaitPreq = 0x01, // CN: wait for PReq frame - kEplDllCsWaitSoc = 0x02, // CN: wait for SoC frame - kEplDllCsWaitSoa = 0x03, // CN: wait for SoA frame - kEplDllMsNonCyclic = 0x04, // MN: reduced EPL cycle (PreOp1) - kEplDllMsWaitSocTrig = 0x05, // MN: wait for SoC trigger (cycle timer) - kEplDllMsWaitPreqTrig = 0x06, // MN: wait for (first) PReq trigger (WaitSoCPReq_U32) - kEplDllMsWaitPres = 0x07, // MN: wait for PRes frame from CN - kEplDllMsWaitSoaTrig = 0x08, // MN: wait for SoA trigger (PRes transmitted) - kEplDllMsWaitAsndTrig = 0x09, // MN: wait for ASnd trigger (SoA transmitted) - kEplDllMsWaitAsnd = 0x0A, // MN: wait for ASnd frame if SoA contained invitation - -} tEplDllState; - -typedef struct { - u8 m_be_abSrcMac[6]; - tEdrvTxBuffer *m_pTxBuffer; // Buffers for Tx-Frames - unsigned int m_uiMaxTxFrames; - u8 m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes - u8 m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN - u8 m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes - tEplDllConfigParam m_DllConfigParam; - tEplDllIdentParam m_DllIdentParam; - tEplDllState m_DllState; - tEplDllkCbAsync m_pfnCbAsync; - tEplDllAsndFilter m_aAsndFilter[EPL_DLL_MAX_ASND_SERVICE_ID]; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplDllkNodeInfo *m_pFirstNodeInfo; - tEplDllkNodeInfo *m_pCurNodeInfo; - tEplDllkNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID]; - tEplDllReqServiceId m_LastReqServiceId; - unsigned int m_uiLastTargetNodeId; -#endif - -#if EPL_TIMER_USE_HIGHRES != FALSE - tEplTimerHdl m_TimerHdlCycle; // used for EPL cycle monitoring on CN and generation on MN -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplTimerHdl m_TimerHdlResponse; // used for CN response monitoring -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -#endif - - unsigned int m_uiCycleCount; // cycle counter (needed for multiplexed cycle support) - unsigned long long m_ullFrameTimeout; // frame timeout (cycle length + loss of frame tolerance) - -} tEplDllkInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -// if no dynamic memory allocation shall be used -// define structures statically -static tEplDllkInstance EplDllkInstance_g; - -static tEdrvTxBuffer aEplDllkTxBuffer_l[EPL_DLLK_TXFRAME_COUNT]; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -// change DLL state on event -static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, - tEplNmtState NmtState_p); - -// called from EdrvInterruptHandler() -static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p); - -// called from EdrvInterruptHandler() -static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p); - -// check frame and set missing information -static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, - unsigned int uiFrameSize_p); - -// called by high resolution timer module to monitor EPL cycle as CN -#if EPL_TIMER_USE_HIGHRES != FALSE -static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -// MN: returns internal node info structure -static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p); - -// transmit SoA -static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p, - BOOL fEnableInvitation_p); - -static tEplKernel EplDllkMnSendSoc(void); - -static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p); - -static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId - ReqServiceId_p, - unsigned int uiNodeId_p); - -static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p); - -static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p); - -#endif - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAddInstance() -// -// Description: add and initialize new instance of EPL stack -// -// Parameters: pInitParam_p = initialisation parameters like MAC address -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEdrvInitParam EdrvInitParam; - - // reset instance structure - EPL_MEMSET(&EplDllkInstance_g, 0, sizeof(EplDllkInstance_g)); - -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = EplTimerHighReskInit(); - if (Ret != kEplSuccessful) { // error occured while initializing high resolution timer module - goto Exit; - } -#endif - - // if dynamic memory allocation available - // allocate instance structure - // allocate TPDO and RPDO table with default size - - // initialize and link pointers in instance structure to frame tables - EplDllkInstance_g.m_pTxBuffer = aEplDllkTxBuffer_l; - EplDllkInstance_g.m_uiMaxTxFrames = - ARRAY_SIZE(aEplDllkTxBuffer_l); - - // initialize state - EplDllkInstance_g.m_DllState = kEplDllGsInit; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // set up node info structure - for (uiIndex = 0; uiIndex < tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { - EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1; - EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit = - 0xFFFF; - } -#endif - - // initialize Edrv - EPL_MEMCPY(EdrvInitParam.m_abMyMacAddr, pInitParam_p->m_be_abSrcMac, 6); - EdrvInitParam.m_pfnRxHandler = EplDllkCbFrameReceived; - EdrvInitParam.m_pfnTxHandler = EplDllkCbFrameTransmitted; - Ret = EdrvInit(&EdrvInitParam); - if (Ret != kEplSuccessful) { // error occured while initializing ethernet driver - goto Exit; - } - // copy local MAC address from Ethernet driver back to local instance structure - // because Ethernet driver may have read it from controller EEPROM - EPL_MEMCPY(EplDllkInstance_g.m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, - 6); - EPL_MEMCPY(pInitParam_p->m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6); - - // initialize TxBuffer array - for (uiIndex = 0; uiIndex < EplDllkInstance_g.m_uiMaxTxFrames; - uiIndex++) { - EplDllkInstance_g.m_pTxBuffer[uiIndex].m_pbBuffer = NULL; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - Ret = VEthAddInstance(pInitParam_p); -#endif - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDelInstance() -// -// Description: deletes an instance of EPL stack -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDelInstance(void) -{ - tEplKernel Ret = kEplSuccessful; - - // reset state - EplDllkInstance_g.m_DllState = kEplDllGsInit; - -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = EplTimerHighReskDelInstance(); -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - Ret = VEthDelInstance(); -#endif - - Ret = EdrvShutdown(); - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCreateTxFrame -// -// Description: creates the buffer for a Tx frame and registers it to the -// ethernet driver -// -// Parameters: puiHandle_p = OUT: handle to frame buffer -// ppFrame_p = OUT: pointer to pointer of EPL frame -// puiFrameSize_p = IN/OUT: pointer to size of frame -// returned size is always equal or larger than -// requested size, if that is not possible -// an error will be returned -// MsgType_p = EPL message type -// ServiceId_p = Service ID in case of ASnd frame, otherwise -// kEplDllAsndNotDefined -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p, - tEplFrame ** ppFrame_p, - unsigned int *puiFrameSize_p, - tEplMsgType MsgType_p, - tEplDllAsndServiceId ServiceId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrame *pTxFrame; - unsigned int uiHandle = EplDllkInstance_g.m_uiMaxTxFrames; - tEdrvTxBuffer *pTxBuffer = NULL; - - if (MsgType_p == kEplMsgTypeAsnd) { - // search for fixed Tx buffers - if (ServiceId_p == kEplDllAsndIdentResponse) { - uiHandle = EPL_DLLK_TXFRAME_IDENTRES; - } else if (ServiceId_p == kEplDllAsndStatusResponse) { - uiHandle = EPL_DLLK_TXFRAME_STATUSRES; - } else if ((ServiceId_p == kEplDllAsndNmtRequest) - || (ServiceId_p == kEplDllAsndNmtCommand)) { - uiHandle = EPL_DLLK_TXFRAME_NMTREQ; - } - - if (uiHandle >= EplDllkInstance_g.m_uiMaxTxFrames) { // look for free entry - uiHandle = EPL_DLLK_TXFRAME_PREQ; - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; - uiHandle++, pTxBuffer++) { - if (pTxBuffer->m_pbBuffer == NULL) { // free entry found - break; - } - } - } - } else if (MsgType_p == kEplMsgTypeNonEpl) { - uiHandle = EPL_DLLK_TXFRAME_NONEPL; - } else if (MsgType_p == kEplMsgTypePres) { - uiHandle = EPL_DLLK_TXFRAME_PRES; - } else if (MsgType_p == kEplMsgTypeSoc) { - uiHandle = EPL_DLLK_TXFRAME_SOC; - } else if (MsgType_p == kEplMsgTypeSoa) { - uiHandle = EPL_DLLK_TXFRAME_SOA; - } else { // look for free entry - uiHandle = EPL_DLLK_TXFRAME_PREQ; - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; - uiHandle++, pTxBuffer++) { - if (pTxBuffer->m_pbBuffer == NULL) { // free entry found - break; - } - } - if (pTxBuffer->m_pbBuffer != NULL) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - } - - // test if requested entry is free - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - if (pTxBuffer->m_pbBuffer != NULL) { // entry is not free - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - // setup Tx buffer - pTxBuffer->m_EplMsgType = MsgType_p; - pTxBuffer->m_uiMaxBufferLen = *puiFrameSize_p; - - Ret = EdrvAllocTxMsgBuffer(pTxBuffer); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // because buffer size may be larger than requested - // memorize real length of frame - pTxBuffer->m_uiTxMsgLen = *puiFrameSize_p; - - // fill whole frame with 0 - EPL_MEMSET(pTxBuffer->m_pbBuffer, 0, pTxBuffer->m_uiMaxBufferLen); - - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (MsgType_p != kEplMsgTypeNonEpl) { // fill out Frame only if it is an EPL frame - // ethertype - AmiSetWordToBe(&pTxFrame->m_be_wEtherType, - EPL_C_DLL_ETHERTYPE_EPL); - // source node ID - AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId, - (u8) EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId); - // source MAC address - EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0], - &EplDllkInstance_g.m_be_abSrcMac[0], 6); - switch (MsgType_p) { - case kEplMsgTypeAsnd: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_ASND); - // destination node ID - switch (ServiceId_p) { - case kEplDllAsndIdentResponse: - case kEplDllAsndStatusResponse: - { // IdentResponses and StatusResponses are Broadcast - AmiSetByteToLe(&pTxFrame-> - m_le_bDstNodeId, - (u8) - EPL_C_ADR_BROADCAST); - break; - } - - default: - break; - } - // ASnd Service ID - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId, - ServiceId_p); - break; - - case kEplMsgTypeSoc: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_SOC); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (u8) 0); - break; - - case kEplMsgTypeSoa: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_SOA); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (u8) 0); - // EPL profile version - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion, - (u8) EPL_SPEC_VERSION); - break; - - case kEplMsgTypePres: - // destination MAC address - AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_PRES); - // destination node ID - AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, - (u8) EPL_C_ADR_BROADCAST); - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (u8) 0); - // PDO size - //AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0); - break; - - case kEplMsgTypePreq: - // reset Flags - //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (u8) 0); - //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (u8) 0); - // PDO size - //AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0); - break; - - default: - break; - } - // EPL message type - AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p); - } - - *ppFrame_p = pTxFrame; - *puiFrameSize_p = pTxBuffer->m_uiMaxBufferLen; - *puiHandle_p = uiHandle; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeleteTxFrame -// -// Description: deletes the buffer for a Tx frame and frees it in the -// ethernet driver -// -// Parameters: uiHandle_p = IN: handle to frame buffer -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - - if (uiHandle_p >= EplDllkInstance_g.m_uiMaxTxFrames) { // handle is not valid - Ret = kEplDllIllegalHdl; - goto Exit; - } - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle_p]; - - // mark buffer as free so that frame will not be send in future anymore - // $$$ d.k. What's up with running transmissions? - pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - pTxBuffer->m_pbBuffer = NULL; - - // delete Tx buffer - Ret = EdrvReleaseTxMsgBuffer(pTxBuffer); - if (Ret != kEplSuccessful) { // error occured while releasing Tx frame - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkProcess -// -// Description: process the passed event -// -// Parameters: pEvent_p = event to be processed -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkProcess(tEplEvent * pEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrame *pTxFrame; - tEdrvTxBuffer *pTxBuffer; - unsigned int uiHandle; - unsigned int uiFrameSize; - u8 abMulticastMac[6]; - tEplDllAsyncReqPriority AsyncReqPriority; - unsigned int uiFrameCount; - tEplNmtState NmtState; -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - tEplFrameInfo FrameInfo; -#endif - - switch (pEvent_p->m_EventType) { - case kEplEventTypeDllkCreate: - { - // $$$ reset ethernet driver - - NmtState = *((tEplNmtState *) pEvent_p->m_pArg); - - // initialize flags for PRes and StatusRes - EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC; - EplDllkInstance_g.m_bMnFlag1 = 0; - EplDllkInstance_g.m_bFlag2 = 0; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // initialize linked node list - EplDllkInstance_g.m_pFirstNodeInfo = NULL; -#endif - - // register TxFrames in Edrv - - // IdentResponse - uiFrameSize = EPL_C_DLL_MINSIZE_IDENTRES; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndIdentResponse); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // EPL profile version - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_bEplProfileVersion, - (u8) EPL_SPEC_VERSION); - // FeatureFlags - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwFeatureFlags, - EplDllkInstance_g.m_DllConfigParam. - m_dwFeatureFlags); - // MTU - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wMtu, - (u16) EplDllkInstance_g. - m_DllConfigParam.m_uiAsyncMtu); - // PollInSize - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wPollInSize, - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiPreqActPayloadLimit); - // PollOutSize - AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_wPollOutSize, - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiPresActPayloadLimit); - // ResponseTime / PresMaxLatency - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwResponseTime, - EplDllkInstance_g.m_DllConfigParam. - m_dwPresMaxLatency); - // DeviceType - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwDeviceType, - EplDllkInstance_g.m_DllIdentParam. - m_dwDeviceType); - // VendorId - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwVendorId, - EplDllkInstance_g.m_DllIdentParam. - m_dwVendorId); - // ProductCode - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwProductCode, - EplDllkInstance_g.m_DllIdentParam. - m_dwProductCode); - // RevisionNumber - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwRevisionNumber, - EplDllkInstance_g.m_DllIdentParam. - m_dwRevisionNumber); - // SerialNumber - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwSerialNumber, - EplDllkInstance_g.m_DllIdentParam. - m_dwSerialNumber); - // VendorSpecificExt1 - AmiSetQword64ToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_qwVendorSpecificExt1, - EplDllkInstance_g.m_DllIdentParam. - m_qwVendorSpecificExt1); - // VerifyConfigurationDate - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwVerifyConfigurationDate, - EplDllkInstance_g.m_DllIdentParam. - m_dwVerifyConfigurationDate); - // VerifyConfigurationTime - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwVerifyConfigurationTime, - EplDllkInstance_g.m_DllIdentParam. - m_dwVerifyConfigurationTime); - // ApplicationSwDate - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwApplicationSwDate, - EplDllkInstance_g.m_DllIdentParam. - m_dwApplicationSwDate); - // ApplicationSwTime - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse. - m_le_dwApplicationSwTime, - EplDllkInstance_g.m_DllIdentParam. - m_dwApplicationSwTime); - // IPAddress - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwIpAddress, - EplDllkInstance_g.m_DllIdentParam. - m_dwIpAddress); - // SubnetMask - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwSubnetMask, - EplDllkInstance_g.m_DllIdentParam. - m_dwSubnetMask); - // DefaultGateway - AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_dwDefaultGateway, - EplDllkInstance_g.m_DllIdentParam. - m_dwDefaultGateway); - // HostName - EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_sHostname[0], - &EplDllkInstance_g.m_DllIdentParam. - m_sHostname[0], - sizeof(EplDllkInstance_g.m_DllIdentParam. - m_sHostname)); - // VendorSpecificExt2 - EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload. - m_IdentResponse.m_le_abVendorSpecificExt2[0], - &EplDllkInstance_g.m_DllIdentParam. - m_abVendorSpecificExt2[0], - sizeof(EplDllkInstance_g.m_DllIdentParam. - m_abVendorSpecificExt2)); - - // StatusResponse - uiFrameSize = EPL_C_DLL_MINSIZE_STATUSRES; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndStatusResponse); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // PRes $$$ maybe move this to PDO module - if ((EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly == - FALSE) - && (EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit >= 36)) { // it is not configured as async-only CN, - // so take part in isochronous phase and register PRes frame - uiFrameSize = - EplDllkInstance_g.m_DllConfigParam. - m_uiPresActPayloadLimit + 24; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypePres, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - // initially encode TPDO -> inform PDO module - FrameInfo.m_pFrame = pTxFrame; - FrameInfo.m_uiFrameSize = uiFrameSize; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); -#endif - // reset cycle counter - EplDllkInstance_g.m_uiCycleCount = 0; - } else { // it is an async-only CN - // fool EplDllkChangeState() to think that PRes was not expected - EplDllkInstance_g.m_uiCycleCount = 1; - } - - // NMT request - uiFrameSize = EPL_C_IP_MAX_MTU; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, kEplMsgTypeAsnd, - kEplDllAsndNmtRequest); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // mark Tx buffer as empty - EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = - EPL_DLLK_BUFLEN_EMPTY; - - // non-EPL frame - uiFrameSize = EPL_C_IP_MAX_MTU; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeNonEpl, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // mark Tx buffer as empty - EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = - EPL_DLLK_BUFLEN_EMPTY; - - // register multicast MACs in ethernet driver - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOC); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOA); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_PRES); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_ASND); - Ret = EdrvDefineRxMacAddrEntry(abMulticastMac); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (NmtState >= kEplNmtMsNotActive) { // local node is MN - unsigned int uiIndex; - - // SoC - uiFrameSize = EPL_C_DLL_MINSIZE_SOC; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeSoc, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - // SoA - uiFrameSize = EPL_C_DLL_MINSIZE_SOA; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pTxFrame, - &uiFrameSize, - kEplMsgTypeSoa, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { // error occured while registering Tx frame - goto Exit; - } - - for (uiIndex = 0; - uiIndex < - tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { -// EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1; - EplDllkInstance_g.m_aNodeInfo[uiIndex]. - m_wPresPayloadLimit = - (u16) EplDllkInstance_g. - m_DllConfigParam. - m_uiIsochrRxMaxPayload; - } - - // calculate cycle length - EplDllkInstance_g.m_ullFrameTimeout = 1000LL - * - ((unsigned long long)EplDllkInstance_g. - m_DllConfigParam.m_dwCycleLen); - } -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - Ret = EplDllkCalAsyncClearBuffer(); - - break; - } - - case kEplEventTypeDllkDestroy: - { - // destroy all data structures - - NmtState = *((tEplNmtState *) pEvent_p->m_pArg); - - // delete Tx frames - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_IDENTRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_STATUSRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_PRES); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NMTREQ); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NONEPL); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (NmtState >= kEplNmtMsNotActive) { // local node was MN - unsigned int uiIndex; - - Ret = - EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOC); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - Ret = - EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOA); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - for (uiIndex = 0; - uiIndex < - tabentries(EplDllkInstance_g.m_aNodeInfo); - uiIndex++) { - if (EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer != NULL) { - uiHandle = - EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer - - EplDllkInstance_g. - m_pTxBuffer; - EplDllkInstance_g. - m_aNodeInfo[uiIndex]. - m_pPreqTxBuffer = NULL; - Ret = - EplDllkDeleteTxFrame - (uiHandle); - if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame - goto Exit; - } - - } - EplDllkInstance_g.m_aNodeInfo[uiIndex]. - m_wPresPayloadLimit = 0xFFFF; - } - } -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - // deregister multicast MACs in ethernet driver - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOC); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_SOA); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_PRES); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - AmiSetQword48ToBe(&abMulticastMac[0], - EPL_C_DLL_MULTICAST_ASND); - Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac); - - // delete timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskDeleteTimer(&EplDllkInstance_g. - m_TimerHdlCycle); -#endif - - break; - } - - case kEplEventTypeDllkFillTx: - { - // fill TxBuffer of specified priority with new frame if empty - - pTxFrame = NULL; - AsyncReqPriority = - *((tEplDllAsyncReqPriority *) pEvent_p->m_pArg); - switch (AsyncReqPriority) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - { - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]; - if (pTxBuffer->m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is empty and not being filled - if (pTxBuffer->m_uiTxMsgLen == - EPL_DLLK_BUFLEN_EMPTY) { - // mark Tx buffer as filling is in process - pTxBuffer-> - m_uiTxMsgLen = - EPL_DLLK_BUFLEN_FILLING; - // set max buffer size as input parameter - uiFrameSize = - pTxBuffer-> - m_uiMaxBufferLen; - // copy frame from shared loop buffer to Tx buffer - Ret = - EplDllkCalAsyncGetTxFrame - (pTxBuffer-> - m_pbBuffer, - &uiFrameSize, - AsyncReqPriority); - if (Ret == - kEplSuccessful) { - pTxFrame = - (tEplFrame - *) - pTxBuffer-> - m_pbBuffer; - Ret = - EplDllkCheckFrame - (pTxFrame, - uiFrameSize); - - // set buffer valid - pTxBuffer-> - m_uiTxMsgLen - = - uiFrameSize; - } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem - // so just ignore it - Ret = - kEplSuccessful; - // mark Tx buffer as empty - pTxBuffer-> - m_uiTxMsgLen - = - EPL_DLLK_BUFLEN_EMPTY; - } - } - } - break; - } - - default: // generic priority - { - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]; - if (pTxBuffer->m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is empty and not being filled - if (pTxBuffer->m_uiTxMsgLen == - EPL_DLLK_BUFLEN_EMPTY) { - // mark Tx buffer as filling is in process - pTxBuffer-> - m_uiTxMsgLen = - EPL_DLLK_BUFLEN_FILLING; - // set max buffer size as input parameter - uiFrameSize = - pTxBuffer-> - m_uiMaxBufferLen; - // copy frame from shared loop buffer to Tx buffer - Ret = - EplDllkCalAsyncGetTxFrame - (pTxBuffer-> - m_pbBuffer, - &uiFrameSize, - AsyncReqPriority); - if (Ret == - kEplSuccessful) { - pTxFrame = - (tEplFrame - *) - pTxBuffer-> - m_pbBuffer; - Ret = - EplDllkCheckFrame - (pTxFrame, - uiFrameSize); - - // set buffer valid - pTxBuffer-> - m_uiTxMsgLen - = - uiFrameSize; - } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem - // so just ignore it - Ret = - kEplSuccessful; - // mark Tx buffer as empty - pTxBuffer-> - m_uiTxMsgLen - = - EPL_DLLK_BUFLEN_EMPTY; - } - } - } - break; - } - } - - NmtState = EplNmtkGetNmtState(); - - if ((NmtState == kEplNmtCsBasicEthernet) || (NmtState == kEplNmtMsBasicEthernet)) { // send frame immediately - if (pTxFrame != NULL) { // frame is present - // padding is done by Edrv or ethernet controller - Ret = EdrvSendTxMsg(pTxBuffer); - } else { // no frame moved to TxBuffer - // check if TxBuffers contain unsent frames - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - } - if (Ret == kEplInvalidOperation) { // ignore error if caused by already active transmission - Ret = kEplSuccessful; - } - } - // reset PRes flag 2 - EplDllkInstance_g.m_bFlag2 = 0; - } else { - // update Flag 2 (PR, RS) - Ret = - EplDllkCalAsyncGetTxCount(&AsyncReqPriority, - &uiFrameCount); - if (AsyncReqPriority == kEplDllAsyncReqPrioNmt) { // non-empty FIFO with hightest priority is for NMT requests - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - // add one more frame - uiFrameCount++; - } - } else { // non-empty FIFO with highest priority is for generic frames - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame - // use NMT request FIFO, because of higher priority - uiFrameCount = 1; - AsyncReqPriority = - kEplDllAsyncReqPrioNmt; - } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame - // use NMT request FIFO, because of higher priority - // add one more frame - uiFrameCount++; - } - } - - if (uiFrameCount > 7) { // limit frame request to send counter to 7 - uiFrameCount = 7; - } - if (uiFrameCount > 0) { - EplDllkInstance_g.m_bFlag2 = - (u8) (((AsyncReqPriority << - EPL_FRAME_FLAG2_PR_SHIFT) - & EPL_FRAME_FLAG2_PR) - | (uiFrameCount & - EPL_FRAME_FLAG2_RS)); - } else { - EplDllkInstance_g.m_bFlag2 = 0; - } - } - - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - case kEplEventTypeDllkStartReducedCycle: - { - // start the reduced cycle by programming the cycle timer - // it is issued by NMT MN module, when PreOp1 is entered - - // clear the asynchronous queues - Ret = EplDllkCalAsyncClearQueues(); - - // reset cycle counter (everytime a SoA is triggerd in PreOp1 the counter is incremented - // and when it reaches EPL_C_DLL_PREOP1_START_CYCLES the SoA may contain invitations) - EplDllkInstance_g.m_uiCycleCount = 0; - - // remove any CN from isochronous phase - while (EplDllkInstance_g.m_pFirstNodeInfo != NULL) { - EplDllkDeleteNode(EplDllkInstance_g. - m_pFirstNodeInfo->m_uiNodeId); - } - - // change state to NonCyclic, - // hence EplDllkChangeState() will not ignore the next call - EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout, - EplDllkCbMnTimerCycle, 0L, FALSE); - } -#endif - - break; - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - case kEplEventTypeDllkPresReady: - { - // post PRes to transmit FIFO - - NmtState = EplNmtkGetNmtState(); - - if (NmtState != kEplNmtCsBasicEthernet) { - // Does PRes exist? - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer != NULL) { // PRes does exist - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]. - m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op - // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater - NmtState = - kEplNmtCsPreOperational2; - } - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // mark PRes frame as ready for transmission - Ret = - EdrvTxMsgReady(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_PRES]); - } - } - - break; - } -#endif - default: - { - ASSERTMSG(FALSE, - "EplDllkProcess(): unhandled event type!\n"); - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkConfig -// -// Description: configure parameters of DLL -// -// Parameters: pDllConfigParam_p = configuration parameters -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p) -{ - tEplKernel Ret = kEplSuccessful; - -// d.k. check of NMT state disabled, because CycleLen is programmed at run time by MN without reset of CN -/*tEplNmtState NmtState; - - NmtState = EplNmtkGetNmtState(); - - if (NmtState > kEplNmtGsResetConfiguration) - { // only allowed in state DLL_GS_INIT - Ret = kEplInvalidOperation; - goto Exit; - } -*/ - EPL_MEMCPY(&EplDllkInstance_g.m_DllConfigParam, pDllConfigParam_p, - (pDllConfigParam_p->m_uiSizeOfStruct < - sizeof(tEplDllConfigParam) ? pDllConfigParam_p-> - m_uiSizeOfStruct : sizeof(tEplDllConfigParam))); - - if ((EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen != 0) - && (EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance != 0)) { // monitor EPL cycle, calculate frame timeout - EplDllkInstance_g.m_ullFrameTimeout = (1000LL - * - ((unsigned long long) - EplDllkInstance_g. - m_DllConfigParam. - m_dwCycleLen)) - + - ((unsigned long long)EplDllkInstance_g.m_DllConfigParam. - m_dwLossOfFrameTolerance); - } else { - EplDllkInstance_g.m_ullFrameTimeout = 0LL; - } - - if (EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly != FALSE) { // it is configured as async-only CN - // disable multiplexed cycle, that m_uiCycleCount will not be incremented spuriously on SoC - EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt = 0; - } -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetIdentity -// -// Description: configure identity of local node for IdentResponse -// -// Parameters: pDllIdentParam_p = identity -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p) -{ - tEplKernel Ret = kEplSuccessful; - - EPL_MEMCPY(&EplDllkInstance_g.m_DllIdentParam, pDllIdentParam_p, - (pDllIdentParam_p->m_uiSizeOfStruct < - sizeof(tEplDllIdentParam) ? pDllIdentParam_p-> - m_uiSizeOfStruct : sizeof(tEplDllIdentParam))); - - // $$$ if IdentResponse frame exists update it - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkRegAsyncHandler -// -// Description: registers handler for non-EPL frames -// -// Parameters: pfnDllkCbAsync_p = pointer to callback function -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (EplDllkInstance_g.m_pfnCbAsync == NULL) { // no handler registered yet - EplDllkInstance_g.m_pfnCbAsync = pfnDllkCbAsync_p; - } else { // handler already registered - Ret = kEplDllCbAsyncRegistered; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeregAsyncHandler -// -// Description: deregisters handler for non-EPL frames -// -// Parameters: pfnDllkCbAsync_p = pointer to callback function -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (EplDllkInstance_g.m_pfnCbAsync == pfnDllkCbAsync_p) { // same handler is registered - // deregister it - EplDllkInstance_g.m_pfnCbAsync = NULL; - } else { // wrong handler or no handler registered - Ret = kEplDllCbAsyncRegistered; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetAsndServiceIdFilter() -// -// Description: sets the specified node ID filter for the specified -// AsndServiceId. It registers C_DLL_MULTICAST_ASND in ethernet -// driver if any AsndServiceId is open. -// -// Parameters: ServiceId_p = ASnd Service ID -// Filter_p = node ID filter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, - tEplDllAsndFilter Filter_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (ServiceId_p < tabentries(EplDllkInstance_g.m_aAsndFilter)) { - EplDllkInstance_g.m_aAsndFilter[ServiceId_p] = Filter_p; - } - - return Ret; -} - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSetFlag1OfNode() -// -// Description: sets Flag1 (for PReq and SoA) of the specified node ID. -// -// Parameters: uiNodeId_p = node ID -// bSoaFlag1_p = flag1 -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pNodeInfo; - - pNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - // store flag1 in internal node info structure - pNodeInfo->m_bSoaFlag1 = bSoaFlag1_p; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkGetFirstNodeInfo() -// -// Description: returns first info structure of first node in isochronous phase. -// It is only useful for ErrorHandlerk module. -// -// Parameters: ppNodeInfo_p = pointer to pointer of internal node info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - - *ppNodeInfo_p = EplDllkInstance_g.m_pFirstNodeInfo; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAddNode() -// -// Description: adds the specified node to the isochronous phase. -// -// Parameters: pNodeInfo_p = pointer of node info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - tEplDllkNodeInfo **ppIntNodeInfo; - unsigned int uiHandle; - tEplFrame *pFrame; - unsigned int uiFrameSize; - - pIntNodeInfo = EplDllkGetNodeInfo(pNodeInfo_p->m_uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkAddNode, - pNodeInfo_p->m_uiNodeId, 0); - - // copy node configuration - pIntNodeInfo->m_dwPresTimeout = pNodeInfo_p->m_dwPresTimeout; - pIntNodeInfo->m_wPresPayloadLimit = pNodeInfo_p->m_wPresPayloadLimit; - - // $$$ d.k.: actually add node only if MN. On CN it is sufficient to update the node configuration - if (pNodeInfo_p->m_uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // we shall send PRes ourself - // insert our node at the end of the list - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_pNextNodeInfo != NULL)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if (*ppIntNodeInfo != NULL) { - if ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId) { // node was already added to list - // $$$ d.k. maybe this should be an error - goto Exit; - } else { // add our node at the end of the list - ppIntNodeInfo = - &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - } - // set "PReq"-TxBuffer to PRes-TxBuffer - pIntNodeInfo->m_pPreqTxBuffer = - &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - } else { // normal CN shall be added to isochronous phase - // insert node into list in ascending order - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_uiNodeId < - pNodeInfo_p->m_uiNodeId) - && ((*ppIntNodeInfo)->m_uiNodeId != - EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId)) { // node was already added to list - // $$$ d.k. maybe this should be an error - goto Exit; - } - } - - // initialize elements of internal node info structure - pIntNodeInfo->m_bSoaFlag1 = 0; - pIntNodeInfo->m_fSoftDelete = FALSE; - pIntNodeInfo->m_NmtState = kEplNmtCsNotActive; - if (pIntNodeInfo->m_pPreqTxBuffer == NULL) { // create TxBuffer entry - uiFrameSize = pNodeInfo_p->m_wPreqPayloadLimit + 24; - Ret = - EplDllkCreateTxFrame(&uiHandle, &pFrame, &uiFrameSize, - kEplMsgTypePreq, - kEplDllAsndNotDefined); - if (Ret != kEplSuccessful) { - goto Exit; - } - pIntNodeInfo->m_pPreqTxBuffer = - &EplDllkInstance_g.m_pTxBuffer[uiHandle]; - AmiSetByteToLe(&pFrame->m_le_bDstNodeId, - (u8) pNodeInfo_p->m_uiNodeId); - - // set up destination MAC address - EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr, - 6); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - { - tEplFrameInfo FrameInfo; - - // initially encode TPDO -> inform PDO module - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = uiFrameSize; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif - } - pIntNodeInfo->m_ulDllErrorEvents = 0L; - // add node to list - pIntNodeInfo->m_pNextNodeInfo = *ppIntNodeInfo; - *ppIntNodeInfo = pIntNodeInfo; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkDeleteNode() -// -// Description: removes the specified node from the isochronous phase. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - tEplDllkNodeInfo **ppIntNodeInfo; - unsigned int uiHandle; - - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkDelNode, uiNodeId_p, 0); - - // search node in whole list - ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo; - while ((*ppIntNodeInfo != NULL) - && ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) { - ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo; - } - if ((*ppIntNodeInfo == NULL) || ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) { // node was not found in list - // $$$ d.k. maybe this should be an error - goto Exit; - } - // remove node from list - *ppIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo; - - if ((pIntNodeInfo->m_pPreqTxBuffer != NULL) - && (pIntNodeInfo->m_pPreqTxBuffer != &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) { // delete TxBuffer entry - uiHandle = - pIntNodeInfo->m_pPreqTxBuffer - - EplDllkInstance_g.m_pTxBuffer; - pIntNodeInfo->m_pPreqTxBuffer = NULL; - Ret = EplDllkDeleteTxFrame(uiHandle); -/* if (Ret != kEplSuccessful) - { - goto Exit; - }*/ - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkSoftDeleteNode() -// -// Description: removes the specified node not immediately from the isochronous phase. -// Instead the will be removed after error (late/loss PRes) without -// charging the error. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllkNodeInfo *pIntNodeInfo; - - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - - EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkSoftDelNode, - uiNodeId_p, 0); - - pIntNodeInfo->m_fSoftDelete = TRUE; - - Exit: - return Ret; -} - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDllkChangeState -// -// Description: change DLL state on event and diagnose some communication errors -// -// Parameters: NmtEvent_p = DLL event (wrapped in NMT event) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, - tEplNmtState NmtState_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = 0; - DllEvent.m_uiNodeId = 0; - DllEvent.m_NmtState = NmtState_p; - - switch (NmtState_p) { - case kEplNmtGsOff: - case kEplNmtGsInitialising: - case kEplNmtGsResetApplication: - case kEplNmtGsResetCommunication: - case kEplNmtGsResetConfiguration: - case kEplNmtCsBasicEthernet: - // enter DLL_GS_INIT - EplDllkInstance_g.m_DllState = kEplDllGsInit; - break; - - case kEplNmtCsNotActive: - case kEplNmtCsPreOperational1: - // reduced EPL cycle is active - if (NmtEvent_p == kEplNmtEventDllCeSoc) { // SoC received - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq; - } else { - // enter DLL_GS_INIT - EplDllkInstance_g.m_DllState = kEplDllGsInit; - } - break; - - case kEplNmtCsPreOperational2: - case kEplNmtCsReadyToOperate: - case kEplNmtCsOperational: - // full EPL cycle is active - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllCsWaitPreq: - switch (NmtEvent_p) { - // DLL_CT2 - case kEplNmtEventDllCePreq: - // enter DLL_CS_WAIT_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_RECVD_PREQ; - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT8 - case kEplNmtEventDllCeFrameTimeout: - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - case kEplNmtEventDllCeSoa: - // check if multiplexed and PReq should have been received in this cycle - // and if >= NMT_CS_READY_TO_OPERATE - if ((EplDllkInstance_g.m_uiCycleCount == 0) - && (NmtState_p >= kEplNmtCsReadyToOperate)) { // report DLL_CEV_LOSS_OF_PREQ - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_PREQ; - } - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT7 - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoc: - switch (NmtEvent_p) { - // DLL_CT1 - case kEplNmtEventDllCeSoc: - // start of cycle and isochronous phase - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = - kEplDllCsWaitPreq; - break; - - // DLL_CT4 -// case kEplNmtEventDllCePres: - case kEplNmtEventDllCeFrameTimeout: - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // fall through - - case kEplNmtEventDllCePreq: - case kEplNmtEventDllCeSoa: - // report DLL_CEV_LOSS_SOC - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeAsnd: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoa: - switch (NmtEvent_p) { - case kEplNmtEventDllCeFrameTimeout: - // DLL_CT3 - if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2, - // because the previously configured cycle len - // may be wrong. - // 2008/10/15 d.k. If it would not be ignored, - // we would go cyclically to PreOp1 and on next - // SoC back to PreOp2. - break; - } - // fall through - - case kEplNmtEventDllCePreq: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT9 - case kEplNmtEventDllCeSoc: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = - kEplDllCsWaitPreq; - break; - - // DLL_CT10 - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllGsInit: - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq; - break; - - default: - break; - } - break; - - case kEplNmtCsStopped: - // full EPL cycle is active, but without PReq/PRes - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllCsWaitPreq: - switch (NmtEvent_p) { - // DLL_CT2 - case kEplNmtEventDllCePreq: - // enter DLL_CS_WAIT_SOA - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT8 - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // NMT_CS_STOPPED active - // it is Ok if no PReq was received - - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT7 - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoc: - switch (NmtEvent_p) { - // DLL_CT1 - case kEplNmtEventDllCeSoc: - // start of cycle and isochronous phase - // enter DLL_CS_WAIT_SOA - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - - // DLL_CT4 -// case kEplNmtEventDllCePres: - case kEplNmtEventDllCePreq: - case kEplNmtEventDllCeSoa: - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeAsnd: - default: - // remain in this state - break; - } - break; - - case kEplDllCsWaitSoa: - switch (NmtEvent_p) { - // DLL_CT3 - case kEplNmtEventDllCeFrameTimeout: - // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA | - EPL_DLL_ERR_CN_LOSS_SOC; - - case kEplNmtEventDllCeSoa: - // enter DLL_CS_WAIT_SOC - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc; - break; - - // DLL_CT9 - case kEplNmtEventDllCeSoc: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - // remain in DLL_CS_WAIT_SOA - break; - - // DLL_CT10 - case kEplNmtEventDllCeAsnd: - // report DLL_CEV_LOSS_SOA - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOA; - - case kEplNmtEventDllCePreq: - // NMT_CS_STOPPED active and we do not expect any PReq - // so just ignore it - case kEplNmtEventDllCePres: - default: - // remain in this state - break; - } - break; - - case kEplDllGsInit: - default: - // enter DLL_CS_WAIT_PREQ - EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa; - break; - } - break; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - case kEplNmtMsNotActive: - case kEplNmtMsBasicEthernet: - break; - - case kEplNmtMsPreOperational1: - // reduced EPL cycle is active - if (EplDllkInstance_g.m_DllState != kEplDllMsNonCyclic) { // stop cycle timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskDeleteTimer(&EplDllkInstance_g. - m_TimerHdlCycle); -#endif - EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic; - - // stop further processing, - // because it will be restarted by NMT MN module - break; - } - - switch (NmtEvent_p) { - case kEplNmtEventDllMeSocTrig: - case kEplNmtEventDllCeAsnd: - { // because of reduced EPL cycle SoA shall be triggered, not SoC - tEplDllState DummyDllState; - - Ret = - EplDllkAsyncFrameNotReceived - (EplDllkInstance_g.m_LastReqServiceId, - EplDllkInstance_g.m_uiLastTargetNodeId); - - // go ahead and send SoA - Ret = EplDllkMnSendSoa(NmtState_p, - &DummyDllState, - (EplDllkInstance_g. - m_uiCycleCount >= - EPL_C_DLL_PREOP1_START_CYCLES)); - // increment cycle counter to detect if EPL_C_DLL_PREOP1_START_CYCLES empty cycles are elapsed - EplDllkInstance_g.m_uiCycleCount++; - - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_DllConfigParam. - m_dwAsyncSlotTimeout, - EplDllkCbMnTimerCycle, 0L, FALSE); - } -#endif - break; - } - - default: - break; - } - break; - - case kEplNmtMsPreOperational2: - case kEplNmtMsReadyToOperate: - case kEplNmtMsOperational: - // full EPL cycle is active - switch (NmtEvent_p) { - case kEplNmtEventDllMeSocTrig: - { - // update cycle counter - if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active - EplDllkInstance_g.m_uiCycleCount = - (EplDllkInstance_g.m_uiCycleCount + - 1) % - EplDllkInstance_g.m_DllConfigParam. - m_uiMultiplCycleCnt; - // $$$ check multiplexed cycle restart - // -> toggle MC flag - // -> change node linked list - } else { // non-multiplexed cycle active - // start with first node in isochronous phase - EplDllkInstance_g.m_pCurNodeInfo = NULL; - } - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsNonCyclic: - { // start continuous cycle timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g. - m_TimerHdlCycle, - EplDllkInstance_g. - m_ullFrameTimeout, - EplDllkCbMnTimerCycle, 0L, - TRUE); -#endif - // continue with sending SoC - } - - case kEplDllMsWaitAsnd: - case kEplDllMsWaitSocTrig: - { // if m_LastReqServiceId is still valid, - // SoA was not correctly answered - // and user part has to be informed - Ret = - EplDllkAsyncFrameNotReceived - (EplDllkInstance_g. - m_LastReqServiceId, - EplDllkInstance_g. - m_uiLastTargetNodeId); - - // send SoC - Ret = EplDllkMnSendSoc(); - - // new DLL state - EplDllkInstance_g.m_DllState = - kEplDllMsWaitPreqTrig; - - // start WaitSoCPReq Timer -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g. - m_TimerHdlResponse, - EplDllkInstance_g. - m_DllConfigParam. - m_dwWaitSocPreq, - EplDllkCbMnTimerResponse, - 0L, FALSE); -#endif - break; - } - - default: - { // wrong DLL state / cycle time exceeded - DllEvent.m_ulDllErrorEvents |= - EPL_DLL_ERR_MN_CYCTIMEEXCEED; - EplDllkInstance_g.m_DllState = - kEplDllMsWaitSocTrig; - break; - } - } - - break; - } - - case kEplNmtEventDllMePresTimeout: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitPres: - { // PRes not received - - if (EplDllkInstance_g.m_pCurNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN - DllEvent. - m_ulDllErrorEvents - |= - EPL_DLL_ERR_MN_CN_LOSS_PRES; - DllEvent.m_uiNodeId = - EplDllkInstance_g. - m_pCurNodeInfo-> - m_uiNodeId; - } else { // CN shall be deleted softly - Event.m_EventSink = - kEplEventSinkDllkCal; - Event.m_EventType = - kEplEventTypeDllkSoftDelNode; - // $$$ d.k. set Event.m_NetTime to current time - Event.m_uiSize = - sizeof(unsigned - int); - Event.m_pArg = - &EplDllkInstance_g. - m_pCurNodeInfo-> - m_uiNodeId; - Ret = - EplEventkPost - (&Event); - } - - // continue with sending next PReq - } - - case kEplDllMsWaitPreqTrig: - { - // send next PReq - Ret = - EplDllkMnSendPreq - (NmtState_p, - &EplDllkInstance_g. - m_DllState); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllCePres: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitPres: - { // PRes received - // send next PReq - Ret = - EplDllkMnSendPreq - (NmtState_p, - &EplDllkInstance_g. - m_DllState); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllMeSoaTrig: - { - - switch (EplDllkInstance_g.m_DllState) { - case kEplDllMsWaitSoaTrig: - { // MN PRes sent - // send SoA - Ret = - EplDllkMnSendSoa(NmtState_p, - &EplDllkInstance_g. - m_DllState, - TRUE); - - break; - } - - default: - { // wrong DLL state - break; - } - } - - break; - } - - case kEplNmtEventDllCeAsnd: - { // ASnd has been received, but it may be not the requested one -/* - // report if SoA was correctly answered - Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId, - EplDllkInstance_g.m_uiLastTargetNodeId); -*/ - if (EplDllkInstance_g.m_DllState == - kEplDllMsWaitAsnd) { - EplDllkInstance_g.m_DllState = - kEplDllMsWaitSocTrig; - } - break; - } - - default: - break; - } - break; -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - default: - break; - } - - if (DllEvent.m_ulDllErrorEvents != 0) { // error event set -> post it to error handler - Event.m_EventSink = kEplEventSinkErrk; - Event.m_EventType = kEplEventTypeDllError; - // $$$ d.k. set Event.m_NetTime to current time - Event.m_uiSize = sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbFrameReceived() -// -// Description: called from EdrvInterruptHandler() -// -// Parameters: pRxBuffer_p = receive buffer structure -// -// Returns: (none) -// -// -// State: -// -//--------------------------------------------------------------------------- - -static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - tEplNmtEvent NmtEvent = kEplNmtEventNoEvent; - tEplEvent Event; - tEplFrame *pFrame; - tEplFrame *pTxFrame; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrameInfo FrameInfo; - tEplMsgType MsgType; - tEplDllReqServiceId ReqServiceId; - unsigned int uiAsndServiceId; - unsigned int uiNodeId; - u8 bFlag1; - - BENCHMARK_MOD_02_SET(3); - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - pFrame = (tEplFrame *) pRxBuffer_p->m_pbBuffer; - -#if EDRV_EARLY_RX_INT != FALSE - switch (pRxBuffer_p->m_BufferInFrame) { - case kEdrvBufferFirstInFrame: - { - MsgType = - (tEplMsgType) AmiGetByteFromLe(&pFrame-> - m_le_bMessageType); - if (MsgType == kEplMsgTypePreq) { - if (EplDllkInstance_g.m_DllState == kEplDllCsWaitPreq) { // PReq expected and actually received - // d.k.: The condition above is sufficent, because EPL cycle is active - // and no non-EPL frame shall be received in isochronous phase. - // start transmission PRes - // $$$ What if Tx buffer is invalid? - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - Ret = EdrvTxMsgStart(pTxBuffer); -#else - pTxFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // send PRes frame - Ret = EdrvSendTxMsg(pTxBuffer); -#endif - } - } - goto Exit; - } - - case kEdrvBufferMiddleInFrame: - { - goto Exit; - } - - case kEdrvBufferLastInFrame: - { - break; - } - } -#endif - - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = pRxBuffer_p->m_uiRxMsgLen; - FrameInfo.m_NetTime.m_dwNanoSec = pRxBuffer_p->m_NetTime.m_dwNanoSec; - FrameInfo.m_NetTime.m_dwSec = pRxBuffer_p->m_NetTime.m_dwSec; - - if (AmiGetWordFromBe(&pFrame->m_be_wEtherType) != EPL_C_DLL_ETHERTYPE_EPL) { // non-EPL frame - //TRACE2("EplDllkCbFrameReceived: pfnCbAsync=0x%p SrcMAC=0x%llx\n", EplDllkInstance_g.m_pfnCbAsync, AmiGetQword48FromBe(pFrame->m_be_abSrcMac)); - if (EplDllkInstance_g.m_pfnCbAsync != NULL) { // handler for async frames is registered - EplDllkInstance_g.m_pfnCbAsync(&FrameInfo); - } - - goto Exit; - } - - MsgType = (tEplMsgType) AmiGetByteFromLe(&pFrame->m_le_bMessageType); - switch (MsgType) { - case kEplMsgTypePreq: - { - // PReq frame - // d.k.: (we assume that this PReq frame is intended for us and don't check DstNodeId) - if (AmiGetByteFromLe(&pFrame->m_le_bDstNodeId) != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // this PReq is not intended for us - goto Exit; - } - NmtEvent = kEplNmtEventDllCePreq; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } -#if EDRV_EARLY_RX_INT == FALSE - if (NmtState >= kEplNmtCsPreOperational2) { // respond to and process PReq frames only in PreOp2, ReadyToOp and Op - // Does PRes exist? - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist -#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - EdrvTxMsgStart(pTxBuffer); -#else - pTxFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data. - m_Preq. - m_le_bFlag1); - // save EA flag - EplDllkInstance_g.m_bMnFlag1 = - (EplDllkInstance_g. - m_bMnFlag1 & ~EPL_FRAME_FLAG1_EA) - | (bFlag1 & EPL_FRAME_FLAG1_EA); - // preserve MS flag - bFlag1 &= EPL_FRAME_FLAG1_MS; - // add EN flag from Error signaling module - bFlag1 |= - EplDllkInstance_g. - m_bFlag1 & EPL_FRAME_FLAG1_EN; - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // reset only RD flag - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, - bFlag1); - } else { // leave RD flag untouched - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1, - (AmiGetByteFromLe - (&pTxFrame-> - m_Data.m_Pres. - m_le_bFlag1) & - EPL_FRAME_FLAG1_RD) - | bFlag1); - } - // $$$ update EPL_DLL_PRES_READY_AFTER_* code - // send PRes frame - Ret = EdrvSendTxMsg(pTxBuffer); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - } -#endif - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - if (NmtState >= kEplNmtCsReadyToOperate) { // inform PDO module only in ReadyToOp and Op - if (NmtState != kEplNmtCsOperational) { - // reset RD flag and all other flags, but that does not matter, because they were processed above - AmiSetByteToLe(&pFrame->m_Data. - m_Preq. - m_le_bFlag1, 0); - } - // compares real frame size and PDO size - if ((unsigned - int)(AmiGetWordFromLe(&pFrame-> - m_Data. - m_Preq. - m_le_wSize) + - 24) - > FrameInfo.m_uiFrameSize) { // format error - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = - EPL_DLL_ERR_INVALID_FORMAT; - DllEvent.m_uiNodeId = - AmiGetByteFromLe(&pFrame-> - m_le_bSrcNodeId); - DllEvent.m_NmtState = NmtState; - Event.m_EventSink = - kEplEventSinkErrk; - Event.m_EventType = - kEplEventTypeDllError; - Event.m_NetTime = - FrameInfo.m_NetTime; - Event.m_uiSize = - sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - break; - } - // forward PReq frame as RPDO to PDO module - Ret = EplPdokCbPdoReceived(&FrameInfo); - - } -#if (EPL_DLL_PRES_READY_AFTER_SOC != FALSE) - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist - // inform PDO module about PRes after PReq - FrameInfo.m_pFrame = - (tEplFrame *) pTxBuffer->m_pbBuffer; - FrameInfo.m_uiFrameSize = - pTxBuffer->m_uiMaxBufferLen; - Ret = - EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif -#endif - -#if EDRV_EARLY_RX_INT == FALSE - // $$$ inform emergency protocol handling (error signaling module) about flags - } -#endif - - // reset cycle counter - EplDllkInstance_g.m_uiCycleCount = 0; - - break; - } - - case kEplMsgTypePres: - { -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplDllkNodeInfo *pIntNodeInfo; - tEplHeartbeatEvent HeartbeatEvent; -#endif - - // PRes frame - NmtEvent = kEplNmtEventDllCePres; - - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - - if ((NmtState >= kEplNmtCsPreOperational2) - && (NmtState <= kEplNmtCsOperational)) { // process PRes frames only in PreOp2, ReadyToOp and Op of CN - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - } else if (EplDllkInstance_g.m_DllState == kEplDllMsWaitPres) { // or process PRes frames in MsWaitPres - - pIntNodeInfo = EplDllkInstance_g.m_pCurNodeInfo; - if ((pIntNodeInfo == NULL) || (pIntNodeInfo->m_uiNodeId != uiNodeId)) { // ignore PRes, because it is from wrong CN - // $$$ maybe post event to NmtMn module - goto Exit; - } - // forward Flag2 to asynchronous scheduler - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data.m_Asnd. - m_Payload.m_StatusResponse. - m_le_bFlag2); - Ret = - EplDllkCalAsyncSetPendingRequests(uiNodeId, - ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS)); - -#endif - } else { // ignore PRes, because it was received in wrong NMT state - // but execute EplDllkChangeState() and post event to NMT module - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - { // check NMT state of CN - HeartbeatEvent.m_wErrorCode = EPL_E_NO_ERROR; - HeartbeatEvent.m_NmtState = - (tEplNmtState) (AmiGetByteFromLe - (&pFrame->m_Data.m_Pres. - m_le_bNmtStatus) | - EPL_NMT_TYPE_CS); - if (pIntNodeInfo->m_NmtState != HeartbeatEvent.m_NmtState) { // NMT state of CN has changed -> post event to NmtMnu module - if (pIntNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN - HeartbeatEvent.m_uiNodeId = - uiNodeId; - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeHeartbeat; - Event.m_uiSize = - sizeof(HeartbeatEvent); - Event.m_pArg = &HeartbeatEvent; - } else { // CN shall be deleted softly - Event.m_EventSink = - kEplEventSinkDllkCal; - Event.m_EventType = - kEplEventTypeDllkSoftDelNode; - Event.m_uiSize = - sizeof(unsigned int); - Event.m_pArg = - &pIntNodeInfo->m_uiNodeId; - } - Event.m_NetTime = FrameInfo.m_NetTime; - Ret = EplEventkPost(&Event); - - // save current NMT state of CN in internal node structure - pIntNodeInfo->m_NmtState = - HeartbeatEvent.m_NmtState; - } - } -#endif - - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - if ((NmtState != kEplNmtCsPreOperational2) - && (NmtState != kEplNmtMsPreOperational2)) { // inform PDO module only in ReadyToOp and Op - // compare real frame size and PDO size? - if (((unsigned - int)(AmiGetWordFromLe(&pFrame->m_Data. - m_Pres.m_le_wSize) + - 24) - > FrameInfo.m_uiFrameSize) -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - || - (AmiGetWordFromLe - (&pFrame->m_Data.m_Pres.m_le_wSize) > - pIntNodeInfo->m_wPresPayloadLimit) -#endif - ) { // format error - tEplErrorHandlerkEvent DllEvent; - - DllEvent.m_ulDllErrorEvents = - EPL_DLL_ERR_INVALID_FORMAT; - DllEvent.m_uiNodeId = uiNodeId; - DllEvent.m_NmtState = NmtState; - Event.m_EventSink = kEplEventSinkErrk; - Event.m_EventType = - kEplEventTypeDllError; - Event.m_NetTime = FrameInfo.m_NetTime; - Event.m_uiSize = sizeof(DllEvent); - Event.m_pArg = &DllEvent; - Ret = EplEventkPost(&Event); - break; - } - if ((NmtState != kEplNmtCsOperational) - && (NmtState != kEplNmtMsOperational)) { - // reset RD flag and all other flags, but that does not matter, because they were processed above - AmiSetByteToLe(&pFrame->m_Data.m_Pres. - m_le_bFlag1, 0); - } - Ret = EplPdokCbPdoReceived(&FrameInfo); - } -#endif - - break; - } - - case kEplMsgTypeSoc: - { - // SoC frame - NmtEvent = kEplNmtEventDllCeSoc; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } -#if EPL_DLL_PRES_READY_AFTER_SOC != FALSE - // post PRes to transmit FIFO of the ethernet controller, but don't start - // transmission over bus - pTxBuffer = - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]; - // Does PRes exist? - if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - // update frame (NMT state, RD, RS, PR, MS, EN flags) - if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op - // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater - NmtState = kEplNmtCsPreOperational2; - } - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag2, - EplDllkInstance_g.m_bFlag2); - if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op - // $$$ reset only RD flag; set other flags appropriately - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres. - m_le_bFlag1, 0); - } - // $$$ make function that updates Pres, StatusRes - // mark PRes frame as ready for transmission - Ret = EdrvTxMsgReady(pTxBuffer); - } -#endif - - if (NmtState >= kEplNmtCsPreOperational2) { // SoC frames only in PreOp2, ReadyToOp and Op - // trigger synchronous task - Event.m_EventSink = kEplEventSinkSync; - Event.m_EventType = kEplEventTypeSync; - Event.m_uiSize = 0; - Ret = EplEventkPost(&Event); - - // update cycle counter - if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active - EplDllkInstance_g.m_uiCycleCount = - (EplDllkInstance_g.m_uiCycleCount + - 1) % - EplDllkInstance_g.m_DllConfigParam. - m_uiMultiplCycleCnt; - } - } - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if (EplDllkInstance_g.m_ullFrameTimeout != 0) { - Ret = - EplTimerHighReskModifyTimerNs - (&EplDllkInstance_g.m_TimerHdlCycle, - EplDllkInstance_g.m_ullFrameTimeout, - EplDllkCbCnTimer, 0L, FALSE); - } -#endif - - break; - } - - case kEplMsgTypeSoa: - { - // SoA frame - NmtEvent = kEplNmtEventDllCeSoa; - - if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type - break; - } - - pTxFrame = NULL; - - if ((NmtState & EPL_NMT_SUPERSTATE_MASK) != EPL_NMT_CS_EPLMODE) { // do not respond, if NMT state is < PreOp1 (i.e. not EPL_MODE) - break; - } - // check TargetNodeId - uiNodeId = - AmiGetByteFromLe(&pFrame->m_Data.m_Soa. - m_le_bReqServiceTarget); - if (uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // local node is the target of the current request - - // check ServiceId - ReqServiceId = - (tEplDllReqServiceId) - AmiGetByteFromLe(&pFrame->m_Data.m_Soa. - m_le_bReqServiceId); - if (ReqServiceId == kEplDllReqServiceStatus) { // StatusRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist - - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]. - m_pbBuffer; - // update StatusRes frame (NMT state, EN, EC, RS, PR flags) - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag1, - EplDllkInstance_g. - m_bFlag1); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send StatusRes - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(8); - - // update error signaling - bFlag1 = - AmiGetByteFromLe(&pFrame-> - m_Data. - m_Soa. - m_le_bFlag1); - if (((bFlag1 ^ EplDllkInstance_g.m_bMnFlag1) & EPL_FRAME_FLAG1_ER) != 0) { // exception reset flag was changed by MN - // assume same state for EC in next cycle (clear all other bits) - if ((bFlag1 & - EPL_FRAME_FLAG1_ER) - != 0) { - // set EC and reset rest - EplDllkInstance_g. - m_bFlag1 = - EPL_FRAME_FLAG1_EC; - } else { - // reset complete flag 1 (including EC and EN) - EplDllkInstance_g. - m_bFlag1 = - 0; - } - } - // save flag 1 from MN for Status request response cycle - EplDllkInstance_g.m_bMnFlag1 = - bFlag1; - } - } else if (ReqServiceId == kEplDllReqServiceIdent) { // IdentRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]. - m_pbBuffer; - // update IdentRes frame (NMT state, RS, PR flags) - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame-> - m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send IdentRes - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(7); - } - } else if (ReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN) - { // pad frame - EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN; - } */ - // memorize transmission - pTxFrame = - (tEplFrame *) 1; - // send NmtRequest - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (ReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN) - { // pad frame - EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN; - } */ - // memorize transmission - pTxFrame = - (tEplFrame *) 1; - // send non-EPL frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (ReqServiceId == kEplDllReqServiceNo) { // no async service requested -> do nothing - } - } -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - if (pTxFrame == NULL) { // signal process function readiness of PRes frame - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkPresReady; - Event.m_uiSize = 0; - Event.m_pArg = NULL; - Ret = EplEventkPost(&Event); - } -#endif - - // inform PDO module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -// Ret = EplPdokCbSoa(&FrameInfo); -#endif - - // $$$ put SrcNodeId, NMT state and NetTime as HeartbeatEvent into eventqueue - - // $$$ inform emergency protocol handling about flags - break; - } - - case kEplMsgTypeAsnd: - { - // ASnd frame - NmtEvent = kEplNmtEventDllCeAsnd; - - // ASnd service registered? - uiAsndServiceId = - (unsigned int)AmiGetByteFromLe(&pFrame->m_Data. - m_Asnd. - m_le_bServiceId); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if ((EplDllkInstance_g.m_DllState >= kEplDllMsNonCyclic) - && - ((((tEplDllAsndServiceId) uiAsndServiceId) == - kEplDllAsndStatusResponse) - || (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse))) { // StatusRes or IdentRes received - uiNodeId = - AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - if ((EplDllkInstance_g.m_LastReqServiceId == - ((tEplDllReqServiceId) uiAsndServiceId)) - && (uiNodeId == EplDllkInstance_g.m_uiLastTargetNodeId)) { // mark request as responded - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } - if (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse) { // memorize MAC address of CN for PReq - tEplDllkNodeInfo *pIntNodeInfo; - - pIntNodeInfo = - EplDllkGetNodeInfo(uiNodeId); - if (pIntNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - } else { - EPL_MEMCPY(pIntNodeInfo-> - m_be_abMacAddr, - pFrame-> - m_be_abSrcMac, 6); - } - } - // forward Flag2 to asynchronous scheduler - bFlag1 = - AmiGetByteFromLe(&pFrame->m_Data.m_Asnd. - m_Payload.m_StatusResponse. - m_le_bFlag2); - Ret = - EplDllkCalAsyncSetPendingRequests(uiNodeId, - ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS)); - } -#endif - - if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) { // ASnd service ID is valid - if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterAny) { // ASnd service ID is registered - // forward frame via async receive FIFO to userspace - Ret = - EplDllkCalAsyncFrameReceived - (&FrameInfo); - } else if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterLocal) { // ASnd service ID is registered, but only local node ID or broadcasts - // shall be forwarded - uiNodeId = - AmiGetByteFromLe(&pFrame-> - m_le_bDstNodeId); - if ((uiNodeId == - EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId) - || (uiNodeId == EPL_C_ADR_BROADCAST)) { // ASnd frame is intended for us - // forward frame via async receive FIFO to userspace - Ret = - EplDllkCalAsyncFrameReceived - (&FrameInfo); - } - } - } - break; - } - - default: - { - break; - } - } - - if (NmtEvent != kEplNmtEventNoEvent) { // event for DLL and NMT state machine generated - Ret = EplDllkChangeState(NmtEvent, NmtState); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((NmtEvent != kEplNmtEventDllCeAsnd) - && ((NmtState <= kEplNmtCsPreOperational1) || (NmtEvent != kEplNmtEventDllCePres))) { // NMT state machine is not interested in ASnd frames and PRes frames when not CsNotActive or CsPreOp1 - // inform NMT module - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Event.m_pArg = &NmtEvent; - Ret = EplEventkPost(&Event); - } - } - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = EplDllkInstance_g.m_DllState | (NmtEvent << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - BENCHMARK_MOD_02_RESET(3); - return; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbFrameTransmitted() -// -// Description: called from EdrvInterruptHandler(). -// It signals -// -// Parameters: pRxBuffer_p = receive buffer structure -// -// Returns: (none) -// -// -// State: -// -//--------------------------------------------------------------------------- - -static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - tEplDllAsyncReqPriority Priority; - tEplNmtState NmtState; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE) - tEplFrameInfo FrameInfo; -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NMTREQ) { // frame from NMT request FIFO sent - // mark Tx-buffer as empty - pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - - // post event to DLL - Priority = kEplDllAsyncReqPrioNmt; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - } else if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NONEPL) { // frame from generic priority FIFO sent - // mark Tx-buffer as empty - pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY; - - // post event to DLL - Priority = kEplDllAsyncReqPrioGeneric; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - } -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) \ - || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - else if ((pTxBuffer_p->m_EplMsgType == kEplMsgTypePreq) - || (pTxBuffer_p->m_EplMsgType == kEplMsgTypePres)) { // PRes resp. PReq frame sent - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \ - && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) - { - // inform PDO module - FrameInfo.m_pFrame = - (tEplFrame *) pTxBuffer_p->m_pbBuffer; - FrameInfo.m_uiFrameSize = pTxBuffer_p->m_uiMaxBufferLen; - Ret = EplPdokCbPdoTransmitted(&FrameInfo); - } -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - { - // if own Pres on MN, trigger SoA - if ((NmtState >= kEplNmtMsPreOperational2) - && (pTxBuffer_p == - &EplDllkInstance_g. - m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) { - Ret = - EplDllkChangeState(kEplNmtEventDllMeSoaTrig, - NmtState); - } - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - goto Exit; -#endif - } -#endif -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - else if (pTxBuffer_p->m_EplMsgType == kEplMsgTypeSoa) { // SoA frame sent - tEplNmtEvent NmtEvent = kEplNmtEventDllMeSoaSent; - - // check if we are invited - if (EplDllkInstance_g.m_uiLastTargetNodeId == - EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { - tEplFrame *pTxFrame; - - if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceStatus) { // StatusRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist - - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]. - m_pbBuffer; - // update StatusRes frame (NMT state, EN, EC, RS, PR flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag1, - EplDllkInstance_g. - m_bFlag1); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_StatusResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send StatusRes - Ret = - EdrvSendTxMsg(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_STATUSRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(8); - - } - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceIdent) { // IdentRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist - pTxFrame = - (tEplFrame *) EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]. - m_pbBuffer; - // update IdentRes frame (NMT state, RS, PR flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bNmtStatus, - (u8) NmtState); - AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd. - m_Payload. - m_IdentResponse. - m_le_bFlag2, - EplDllkInstance_g. - m_bFlag2); - // send IdentRes - Ret = - EdrvSendTxMsg(&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_IDENTRES]); - if (Ret != kEplSuccessful) { - goto Exit; - } - TGT_DBG_SIGNAL_TRACE_POINT(7); - } - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - // check if this frame is a NMT command, - // then forward this frame back to NmtMnu module, - // because it needs the time, when this frame is - // actually sent, to start the timer for monitoring - // the NMT state change. - - pTxFrame = - (tEplFrame *) - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_pbBuffer; - if ((AmiGetByteFromLe - (&pTxFrame-> - m_le_bMessageType) - == (u8) kEplMsgTypeAsnd) - && - (AmiGetByteFromLe - (&pTxFrame->m_Data.m_Asnd. - m_le_bServiceId) - == (u8) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeNmtMnuNmtCmdSent; - Event.m_uiSize = - EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]. - m_uiTxMsgLen; - Event.m_pArg = pTxFrame; - Ret = - EplEventkPost - (&Event); - - } - // send NmtRequest - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NMTREQ]); - if (Ret != kEplSuccessful) { - goto Exit; - } - - } - } - - } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite - if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist - // check if frame is not empty and not being filled - if (EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]. - m_uiTxMsgLen > - EPL_DLLK_BUFLEN_FILLING) { - // send non-EPL frame - Ret = - EdrvSendTxMsg - (&EplDllkInstance_g. - m_pTxBuffer - [EPL_DLLK_TXFRAME_NONEPL]); - if (Ret != kEplSuccessful) { - goto Exit; - } - - } - } - } - // ASnd frame was sent, remove the request - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } - // forward event to ErrorHandler and PDO module - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Event.m_pArg = &NmtEvent; - Ret = EplEventkPost(&Event); - if (Ret != kEplSuccessful) { - goto Exit; - } - } -#endif - -#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE - else { // d.k.: Why that else? on CN it is entered on IdentRes and StatusRes - goto Exit; - } - - // signal process function readiness of PRes frame - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkPresReady; - Event.m_uiSize = 0; - Event.m_pArg = NULL; - Ret = EplEventkPost(&Event); - -#endif - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g.m_DllState | (pTxBuffer_p-> - m_EplMsgType << 16); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCheckFrame() -// -// Description: check frame and set missing information -// -// Parameters: pFrame_p = ethernet frame -// uiFrameSize_p = size of frame -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, - unsigned int uiFrameSize_p) -{ - tEplMsgType MsgType; - u16 wEtherType; - - // check frame - if (pFrame_p != NULL) { - // check SrcMAC - if (AmiGetQword48FromBe(pFrame_p->m_be_abSrcMac) == 0) { - // source MAC address - EPL_MEMCPY(&pFrame_p->m_be_abSrcMac[0], - &EplDllkInstance_g.m_be_abSrcMac[0], 6); - } - // check ethertype - wEtherType = AmiGetWordFromBe(&pFrame_p->m_be_wEtherType); - if (wEtherType == 0) { - // assume EPL frame - wEtherType = EPL_C_DLL_ETHERTYPE_EPL; - AmiSetWordToBe(&pFrame_p->m_be_wEtherType, wEtherType); - } - - if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) { - // source node ID - AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId, - (u8) EplDllkInstance_g. - m_DllConfigParam.m_uiNodeId); - - // check message type - MsgType = - AmiGetByteFromLe(&pFrame_p->m_le_bMessageType); - if (MsgType == 0) { - MsgType = kEplMsgTypeAsnd; - AmiSetByteToLe(&pFrame_p->m_le_bMessageType, - (u8) MsgType); - } - - if (MsgType == kEplMsgTypeAsnd) { - // destination MAC address - AmiSetQword48ToBe(&pFrame_p->m_be_abDstMac[0], - EPL_C_DLL_MULTICAST_ASND); - } - - } - } - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbCnTimer() -// -// Description: called by timer module. It monitors the EPL cycle when it is a CN. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -#if EPL_TIMER_USE_HIGHRES != FALSE -static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllCeFrameTimeout, NmtState); - if (Ret != kEplSuccessful) { - goto Exit; - } - // 2008/10/15 d.k. reprogramming of timer not necessary, - // because it will be programmed, when SoC is received. -/* - // reprogram timer -#if EPL_TIMER_USE_HIGHRES != FALSE - if ((NmtState > kEplNmtCsPreOperational1) - && (EplDllkInstance_g.m_ullFrameTimeout != 0)) - { - Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE); - } -#endif -*/ - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllCeFrameTimeout << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbMnTimerCycle() -// -// Description: called by timer module. It triggers the SoC when it is a MN. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllMeSocTrig, NmtState); - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllMeSocTrig << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCbMnTimerResponse() -// -// Description: called by timer module. It monitors the PRes timeout. -// -// Parameters: pEventArg_p = timer event argument -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - -#if EPL_TIMER_USE_HIGHRES != FALSE - if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlResponse) { // zombie callback - // just exit - goto Exit; - } -#endif - - NmtState = EplNmtkGetNmtState(); - - if (NmtState <= kEplNmtGsResetConfiguration) { - goto Exit; - } - - Ret = EplDllkChangeState(kEplNmtEventDllMePresTimeout, NmtState); - - Exit: - if (Ret != kEplSuccessful) { - u32 dwArg; - - BENCHMARK_MOD_02_TOGGLE(9); - - dwArg = - EplDllkInstance_g. - m_DllState | (kEplNmtEventDllMePresTimeout << 8); - - // Error event for API layer - Ret = EplEventkPostError(kEplEventSourceDllk, - Ret, sizeof(dwArg), &dwArg); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkGetNodeInfo() -// -// Description: returns node info structure of the specified node. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplDllkNodeInfo* = pointer to internal node info structure -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p) -{ - // $$$ d.k.: use hash algorithm to retrieve the appropriate node info structure - // if size of array is less than 254. - uiNodeId_p--; // node ID starts at 1 but array at 0 - if (uiNodeId_p >= tabentries(EplDllkInstance_g.m_aNodeInfo)) { - return NULL; - } else { - return &EplDllkInstance_g.m_aNodeInfo[uiNodeId_p]; - } -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendSoa() -// -// Description: it updates and transmits the SoA. -// -// Parameters: NmtState_p = current NMT state -// pDllStateProposed_p = proposed DLL state -// fEnableInvitation_p = enable invitation for asynchronous phase -// it will be disabled for EPL_C_DLL_PREOP1_START_CYCLES SoAs -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p, - BOOL fEnableInvitation_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - tEplDllkNodeInfo *pNodeInfo; - - *pDllStateProposed_p = kEplDllMsNonCyclic; - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOA]; - if (pTxBuffer->m_pbBuffer != NULL) { // SoA does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (fEnableInvitation_p != FALSE) { // fetch target of asynchronous phase - if (EplDllkInstance_g.m_bFlag2 == 0) { // own queues are empty - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNo; - } else if (((tEplDllAsyncReqPriority) (EplDllkInstance_g.m_bFlag2 >> EPL_FRAME_FLAG2_PR_SHIFT)) == kEplDllAsyncReqPrioNmt) { // frames in own NMT request queue available - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceNmtRequest; - } else { - EplDllkInstance_g.m_LastReqServiceId = - kEplDllReqServiceUnspecified; - } - Ret = - EplDllkCalAsyncGetSoaRequest(&EplDllkInstance_g. - m_LastReqServiceId, - &EplDllkInstance_g. - m_uiLastTargetNodeId); - if (Ret != kEplSuccessful) { - goto Exit; - } - if (EplDllkInstance_g.m_LastReqServiceId != kEplDllReqServiceNo) { // asynchronous phase will be assigned to one node - if (EplDllkInstance_g.m_uiLastTargetNodeId == EPL_C_ADR_INVALID) { // exchange invalid node ID with local node ID - EplDllkInstance_g.m_uiLastTargetNodeId = - EplDllkInstance_g.m_DllConfigParam. - m_uiNodeId; - // d.k. DLL state WaitAsndTrig is not helpful; - // so just step over to WaitSocTrig, - // because own ASnd is sent automatically in CbFrameTransmitted() after SoA. - //*pDllStateProposed_p = kEplDllMsWaitAsndTrig; - *pDllStateProposed_p = - kEplDllMsWaitSocTrig; - } else { // assignment to CN - *pDllStateProposed_p = - kEplDllMsWaitAsnd; - } - - pNodeInfo = - EplDllkGetNodeInfo(EplDllkInstance_g. - m_uiLastTargetNodeId); - if (pNodeInfo == NULL) { // no node info structure available - Ret = kEplDllNoNodeInfo; - goto Exit; - } - // update frame (EA, ER flags) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bFlag1, - pNodeInfo-> - m_bSoaFlag1 & (EPL_FRAME_FLAG1_EA - | - EPL_FRAME_FLAG1_ER)); - } else { // no assignment of asynchronous phase - *pDllStateProposed_p = kEplDllMsWaitSocTrig; - EplDllkInstance_g.m_uiLastTargetNodeId = - EPL_C_ADR_INVALID; - } - - // update frame (target) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceId, - (u8) EplDllkInstance_g. - m_LastReqServiceId); - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceTarget, - (u8) EplDllkInstance_g. - m_uiLastTargetNodeId); - - } else { // invite nobody - // update frame (target) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceId, (u8) 0); - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa. - m_le_bReqServiceTarget, (u8) 0); - } - - // update frame (NMT state) - AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus, - (u8) NmtState_p); - - // send SoA frame - Ret = EdrvSendTxMsg(pTxBuffer); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendSoc() -// -// Description: it updates and transmits the SoA. -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendSoc(void) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - tEplEvent Event; - - pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOC]; - if (pTxBuffer->m_pbBuffer != NULL) { // SoC does exist - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - // $$$ update NetTime - - // send SoC frame - Ret = EdrvSendTxMsg(pTxBuffer); - if (Ret != kEplSuccessful) { - goto Exit; - } - // trigger synchronous task - Event.m_EventSink = kEplEventSinkSync; - Event.m_EventType = kEplEventTypeSync; - Event.m_uiSize = 0; - Ret = EplEventkPost(&Event); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkMnSendPreq() -// -// Description: it updates and transmits the PReq for the next isochronous CN -// or own PRes if enabled. -// -// Parameters: NmtState_p = current NMT state -// pDllStateProposed_p = proposed DLL state -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p, - tEplDllState * pDllStateProposed_p) -{ - tEplKernel Ret = kEplSuccessful; - tEdrvTxBuffer *pTxBuffer = NULL; - tEplFrame *pTxFrame; - u8 bFlag1 = 0; - - if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // start with first isochronous CN - EplDllkInstance_g.m_pCurNodeInfo = - EplDllkInstance_g.m_pFirstNodeInfo; - } else { // iterate to next isochronous CN - EplDllkInstance_g.m_pCurNodeInfo = - EplDllkInstance_g.m_pCurNodeInfo->m_pNextNodeInfo; - } - - if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // last isochronous CN reached - Ret = EplDllkMnSendSoa(NmtState_p, pDllStateProposed_p, TRUE); - goto Exit; - } else { - pTxBuffer = EplDllkInstance_g.m_pCurNodeInfo->m_pPreqTxBuffer; - bFlag1 = - EplDllkInstance_g.m_pCurNodeInfo-> - m_bSoaFlag1 & EPL_FRAME_FLAG1_EA; - *pDllStateProposed_p = kEplDllMsWaitPres; - - // start PRes Timer - // $$$ d.k.: maybe move this call to CbFrameTransmitted(), because the time should run from there -#if EPL_TIMER_USE_HIGHRES != FALSE - Ret = - EplTimerHighReskModifyTimerNs(&EplDllkInstance_g. - m_TimerHdlResponse, - EplDllkInstance_g. - m_pCurNodeInfo-> - m_dwPresTimeout, - EplDllkCbMnTimerResponse, 0L, - FALSE); -#endif - } - - if (pTxBuffer == NULL) { // PReq does not exist - Ret = kEplDllTxBufNotReady; - goto Exit; - } - - pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer; - - if (pTxFrame != NULL) { // PReq does exist - if (NmtState_p == kEplNmtMsOperational) { // leave RD flag untouched - bFlag1 |= - AmiGetByteFromLe(&pTxFrame->m_Data.m_Preq. - m_le_bFlag1) & EPL_FRAME_FLAG1_RD; - } - - if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) { // PRes of MN will be sent - // update NMT state - AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, - (u8) NmtState_p); - *pDllStateProposed_p = kEplDllMsWaitSoaTrig; - } - // $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary - // update frame (Flag1) - AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, bFlag1); - - // calculate frame size from payload size - pTxBuffer->m_uiTxMsgLen = - AmiGetWordFromLe(&pTxFrame->m_Data.m_Preq.m_le_wSize) + 24; - - // send PReq frame - Ret = EdrvSendTxMsg(pTxBuffer); - } else { - Ret = kEplDllTxFrameInvalid; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkAsyncFrameNotReceived() -// -// Description: passes empty ASnd frame to receive FIFO. -// It will be called only for frames with registered AsndServiceIds -// (only kEplDllAsndFilterAny). -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId - ReqServiceId_p, - unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - u8 abBuffer[18]; - tEplFrame *pFrame = (tEplFrame *) abBuffer; - tEplFrameInfo FrameInfo; - - // check if previous SoA invitation was not answered - switch (ReqServiceId_p) { - case kEplDllReqServiceIdent: - case kEplDllReqServiceStatus: - // ASnd service registered? - if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) { // ASnd service ID is registered - AmiSetByteToLe(&pFrame->m_le_bSrcNodeId, - (u8) uiNodeId_p); - // EPL MsgType ASnd - AmiSetByteToLe(&pFrame->m_le_bMessageType, - (u8) kEplMsgTypeAsnd); - // ASnd Service ID - AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId, - (u8) ReqServiceId_p); - // create frame info structure - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = 18; // empty non existing ASnd frame - // forward frame via async receive FIFO to userspace - Ret = EplDllkCalAsyncFrameReceived(&FrameInfo); - } - break; - default: - // no invitation issued or it was successfully answered or it is uninteresting - break; - } - - return Ret; -} - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) -// EOF diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c deleted file mode 100644 index 0e283d5d018..00000000000 --- a/drivers/staging/epl/EplDllkCal.c +++ /dev/null @@ -1,1260 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for kernel DLL Communication Abstraction Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllkCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.7 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/15 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "kernel/EplDllkCal.h" -#include "kernel/EplDllk.h" -#include "kernel/EplEventk.h" - -#include "EplDllCal.h" -#ifndef EPL_NO_FIFO -#include "SharedBuff.h" -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplDllkCal */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_DLLKCAL_MAX_QUEUES 5 // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { -#ifndef EPL_NO_FIFO -// tShbInstance m_ShbInstanceRx; // FIFO for Rx ASnd frames - tShbInstance m_ShbInstanceTxNmt; // FIFO for Tx frames with NMT request priority - tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority -#else - unsigned int m_uiFrameSizeNmt; - u8 m_abFrameNmt[1500]; - unsigned int m_uiFrameSizeGen; - u8 m_abFrameGen[1500]; -#endif - - tEplDllkCalStatistics m_Statistics; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // IdentRequest queue with CN node IDs - unsigned int m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty - unsigned int m_uiWriteIdentReq; - unsigned int m_uiReadIdentReq; - - // StatusRequest queue with CN node IDs - unsigned int m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty - unsigned int m_uiWriteStatusReq; - unsigned int m_uiReadStatusReq; - - unsigned int m_auiQueueCnRequests[254 * 2]; - // first 254 entries represent the generic requests of the corresponding node - // second 254 entries represent the NMT requests of the corresponding node - unsigned int m_uiNextQueueCnRequest; - unsigned int m_uiNextRequestQueue; -#endif - -} tEplDllkCalInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -// if no dynamic memory allocation shall be used -// define structures statically -static tEplDllkCalInstance EplDllkCalInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAddInstance() -// -// Description: add and initialize new instance of DLL CAL module -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAddInstance(void) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - unsigned int fShbNewCreated; - -/* ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX, - &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated); - // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg - - if (ShbError != kShbOk) - { - Ret = kEplNoResource; - } -*/ - ShbError = - ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_NMT, - EPL_DLLCAL_BUFFER_ID_TX_NMT, - &EplDllkCalInstance_g.m_ShbInstanceTxNmt, - &fShbNewCreated); - // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg - - if (ShbError != kShbOk) { - Ret = kEplNoResource; - } - -/* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal); - // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg - - if (ShbError != kShbOk) - { - Ret = kEplNoResource; - } -*/ - ShbError = - ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_GEN, - EPL_DLLCAL_BUFFER_ID_TX_GEN, - &EplDllkCalInstance_g.m_ShbInstanceTxGen, - &fShbNewCreated); - // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg - - if (ShbError != kShbOk) { - Ret = kEplNoResource; - } - -/* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal); - // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg - - if (ShbError != kShbOk) - { - Ret = kEplNoResource; - } -*/ -#else - EplDllkCalInstance_g.m_uiFrameSizeNmt = 0; - EplDllkCalInstance_g.m_uiFrameSizeGen = 0; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalDelInstance() -// -// Description: deletes instance of DLL CAL module -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalDelInstance(void) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - -/* ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx); - if (ShbError != kShbOk) - { - Ret = kEplNoResource; - } - EplDllkCalInstance_g.m_ShbInstanceRx = NULL; -*/ - ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt); - if (ShbError != kShbOk) { - Ret = kEplNoResource; - } - EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL; - - ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen); - if (ShbError != kShbOk) { - Ret = kEplNoResource; - } - EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL; - -#else - EplDllkCalInstance_g.m_uiFrameSizeNmt = 0; - EplDllkCalInstance_g.m_uiFrameSizeGen = 0; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalProcess -// -// Description: process the passed configuration -// -// Parameters: pEvent_p = event containing configuration options -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - - switch (pEvent_p->m_EventType) { - case kEplEventTypeDllkServFilter: - { - tEplDllCalAsndServiceIdFilter *pServFilter; - - pServFilter = - (tEplDllCalAsndServiceIdFilter *) pEvent_p->m_pArg; - Ret = - EplDllkSetAsndServiceIdFilter(pServFilter-> - m_ServiceId, - pServFilter-> - m_Filter); - break; - } - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - case kEplEventTypeDllkIssueReq: - { - tEplDllCalIssueRequest *pIssueReq; - - pIssueReq = (tEplDllCalIssueRequest *) pEvent_p->m_pArg; - Ret = - EplDllkCalIssueRequest(pIssueReq->m_Service, - pIssueReq->m_uiNodeId, - pIssueReq->m_bSoaFlag1); - break; - } - - case kEplEventTypeDllkAddNode: - { - tEplDllNodeInfo *pNodeInfo; - - pNodeInfo = (tEplDllNodeInfo *) pEvent_p->m_pArg; - Ret = EplDllkAddNode(pNodeInfo); - break; - } - - case kEplEventTypeDllkDelNode: - { - unsigned int *puiNodeId; - - puiNodeId = (unsigned int *)pEvent_p->m_pArg; - Ret = EplDllkDeleteNode(*puiNodeId); - break; - } - - case kEplEventTypeDllkSoftDelNode: - { - unsigned int *puiNodeId; - - puiNodeId = (unsigned int *)pEvent_p->m_pArg; - Ret = EplDllkSoftDeleteNode(*puiNodeId); - break; - } -#endif - - case kEplEventTypeDllkIdentity: - { - tEplDllIdentParam *pIdentParam; - - pIdentParam = (tEplDllIdentParam *) pEvent_p->m_pArg; - if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) { - pIdentParam->m_uiSizeOfStruct = - pEvent_p->m_uiSize; - } - Ret = EplDllkSetIdentity(pIdentParam); - break; - } - - case kEplEventTypeDllkConfig: - { - tEplDllConfigParam *pConfigParam; - - pConfigParam = (tEplDllConfigParam *) pEvent_p->m_pArg; - if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) { - pConfigParam->m_uiSizeOfStruct = - pEvent_p->m_uiSize; - } - Ret = EplDllkConfig(pConfigParam); - break; - } - - default: - break; - } - -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncGetTxCount() -// -// Description: returns count of Tx frames of FIFO with highest priority -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, - unsigned int *puiCount_p) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - unsigned long ulFrameCount; - - // get frame count of Tx FIFO with NMT request priority - ShbError = - ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt, - &ulFrameCount); - // returns kShbOk, kShbInvalidArg - - // error handling - if (ShbError != kShbOk) { - Ret = kEplNoResource; - goto Exit; - } - - if (ulFrameCount > - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt) { - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = - ulFrameCount; - } - - if (ulFrameCount != 0) { // NMT requests are in queue - *pPriority_p = kEplDllAsyncReqPrioNmt; - *puiCount_p = (unsigned int)ulFrameCount; - goto Exit; - } - // get frame count of Tx FIFO with generic priority - ShbError = - ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen, - &ulFrameCount); - // returns kShbOk, kShbInvalidArg - - // error handling - if (ShbError != kShbOk) { - Ret = kEplNoResource; - goto Exit; - } - - if (ulFrameCount > - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen) { - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = - ulFrameCount; - } - - *pPriority_p = kEplDllAsyncReqPrioGeneric; - *puiCount_p = (unsigned int)ulFrameCount; - - Exit: -#else - if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) { - *pPriority_p = kEplDllAsyncReqPrioNmt; - *puiCount_p = 1; - } else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) { - *pPriority_p = kEplDllAsyncReqPrioGeneric; - *puiCount_p = 1; - } else { - *pPriority_p = kEplDllAsyncReqPrioGeneric; - *puiCount_p = 0; - } -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncGetTxFrame() -// -// Description: returns Tx frames from FIFO with specified priority -// -// Parameters: pFrame_p = IN: pointer to buffer -// puiFrameSize_p = IN: max size of buffer -// OUT: actual size of frame -// Priority_p = IN: priority -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p, - unsigned int *puiFrameSize_p, - tEplDllAsyncReqPriority Priority_p) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - unsigned long ulFrameSize; - - switch (Priority_p) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - ShbError = - ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt, - (u8 *) pFrame_p, *puiFrameSize_p, - &ulFrameSize); - // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData - break; - - default: // generic priority - ShbError = - ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen, - (u8 *) pFrame_p, *puiFrameSize_p, - &ulFrameSize); - // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData - break; - - } - - // error handling - if (ShbError != kShbOk) { - if (ShbError == kShbNoReadableData) { - Ret = kEplDllAsyncTxBufferEmpty; - } else { // other error - Ret = kEplNoResource; - } - goto Exit; - } - - *puiFrameSize_p = (unsigned int)ulFrameSize; - - Exit: -#else - switch (Priority_p) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - *puiFrameSize_p = - min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt); - EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt, - *puiFrameSize_p); - EplDllkCalInstance_g.m_uiFrameSizeNmt = 0; - break; - - default: // generic priority - *puiFrameSize_p = - min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen); - EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen, - *puiFrameSize_p); - EplDllkCalInstance_g.m_uiFrameSizeGen = 0; - break; - } - -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncFrameReceived() -// -// Description: passes ASnd frame to receive FIFO. -// It will be called only for frames with registered AsndServiceIds. -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkDlluCal; - Event.m_EventType = kEplEventTypeAsndRx; - Event.m_pArg = pFrameInfo_p->m_pFrame; - Event.m_uiSize = pFrameInfo_p->m_uiFrameSize; - // pass NetTime of frame to userspace - Event.m_NetTime = pFrameInfo_p->m_NetTime; - - Ret = EplEventkPost(&Event); - if (Ret != kEplSuccessful) { - EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++; - } else { - EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncSend() -// -// Description: puts the given frame into the transmit FIFO with the specified -// priority. -// -// Parameters: pFrameInfo_p = frame info structure -// Priority_p = priority -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, - tEplDllAsyncReqPriority Priority_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; -#ifndef EPL_NO_FIFO - tShbError ShbError; - - switch (Priority_p) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - ShbError = - ShbCirWriteDataBlock(EplDllkCalInstance_g. - m_ShbInstanceTxNmt, - pFrameInfo_p->m_pFrame, - pFrameInfo_p->m_uiFrameSize); - // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg - break; - - default: // generic priority - ShbError = - ShbCirWriteDataBlock(EplDllkCalInstance_g. - m_ShbInstanceTxGen, - pFrameInfo_p->m_pFrame, - pFrameInfo_p->m_uiFrameSize); - // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg - break; - - } - - // error handling - switch (ShbError) { - case kShbOk: - break; - - case kShbExceedDataSizeLimit: - Ret = kEplDllAsyncTxBufferFull; - break; - - case kShbBufferFull: - Ret = kEplDllAsyncTxBufferFull; - break; - - case kShbInvalidArg: - default: - Ret = kEplNoResource; - break; - } - -#else - - switch (Priority_p) { - case kEplDllAsyncReqPrioNmt: // NMT request priority - if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0) { - EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt, - pFrameInfo_p->m_pFrame, - pFrameInfo_p->m_uiFrameSize); - EplDllkCalInstance_g.m_uiFrameSizeNmt = - pFrameInfo_p->m_uiFrameSize; - } else { - Ret = kEplDllAsyncTxBufferFull; - goto Exit; - } - break; - - default: // generic priority - if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0) { - EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen, - pFrameInfo_p->m_pFrame, - pFrameInfo_p->m_uiFrameSize); - EplDllkCalInstance_g.m_uiFrameSizeGen = - pFrameInfo_p->m_uiFrameSize; - } else { - Ret = kEplDllAsyncTxBufferFull; - goto Exit; - } - break; - } - -#endif - - // post event to DLL - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority_p; - Event.m_uiSize = sizeof(Priority_p); - Ret = EplEventkPost(&Event); - -#ifdef EPL_NO_FIFO - Exit: -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncClearBuffer() -// -// Description: clears the transmit buffer -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncClearBuffer(void) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - - ShbError = - ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000, - NULL); - ShbError = - ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000, - NULL); - -#else - EplDllkCalInstance_g.m_uiFrameSizeNmt = 0; - EplDllkCalInstance_g.m_uiFrameSizeGen = 0; -#endif - -// EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics)); - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncClearQueues() -// -// Description: clears the transmit buffer -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -tEplKernel EplDllkCalAsyncClearQueues(void) -{ - tEplKernel Ret = kEplSuccessful; - - // clear MN asynchronous queues - EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0; - EplDllkCalInstance_g.m_uiNextRequestQueue = 0; - EplDllkCalInstance_g.m_uiReadIdentReq = 0; - EplDllkCalInstance_g.m_uiWriteIdentReq = 0; - EplDllkCalInstance_g.m_uiReadStatusReq = 0; - EplDllkCalInstance_g.m_uiWriteStatusReq = 0; - - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalGetStatistics() -// -// Description: returns statistics of the asynchronous queues. -// -// Parameters: ppStatistics = statistics structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics) -{ - tEplKernel Ret = kEplSuccessful; -#ifndef EPL_NO_FIFO - tShbError ShbError; - - ShbError = - ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt, - &EplDllkCalInstance_g.m_Statistics. - m_ulCurTxFrameCountNmt); - ShbError = - ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen, - &EplDllkCalInstance_g.m_Statistics. - m_ulCurTxFrameCountGen); -// ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount); - -#else - if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) { - EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1; - } else { - EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0; - } - if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) { - EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1; - } else { - EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0; - } -#endif - - *ppStatistics = &EplDllkCalInstance_g.m_Statistics; - return Ret; -} - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalIssueRequest() -// -// Description: issues a StatusRequest or a IdentRequest to the specified node. -// -// Parameters: Service_p = request service ID -// uiNodeId_p = node ID -// bSoaFlag1_p = flag1 for this node (transmit in SoA and PReq) -// If 0xFF this flag is ignored. -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, - unsigned int uiNodeId_p, u8 bSoaFlag1_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (bSoaFlag1_p != 0xFF) { - Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - // add node to appropriate request queue - switch (Service_p) { - case kEplDllReqServiceIdent: - { - if (((EplDllkCalInstance_g.m_uiWriteIdentReq + - 1) % - tabentries(EplDllkCalInstance_g. - m_auiQueueIdentReq)) - == EplDllkCalInstance_g.m_uiReadIdentReq) { // queue is full - Ret = kEplDllAsyncTxBufferFull; - goto Exit; - } - EplDllkCalInstance_g. - m_auiQueueIdentReq[EplDllkCalInstance_g. - m_uiWriteIdentReq] = uiNodeId_p; - EplDllkCalInstance_g.m_uiWriteIdentReq = - (EplDllkCalInstance_g.m_uiWriteIdentReq + - 1) % - tabentries(EplDllkCalInstance_g.m_auiQueueIdentReq); - break; - } - - case kEplDllReqServiceStatus: - { - if (((EplDllkCalInstance_g.m_uiWriteStatusReq + - 1) % - tabentries(EplDllkCalInstance_g. - m_auiQueueStatusReq)) - == EplDllkCalInstance_g.m_uiReadStatusReq) { // queue is full - Ret = kEplDllAsyncTxBufferFull; - goto Exit; - } - EplDllkCalInstance_g. - m_auiQueueStatusReq[EplDllkCalInstance_g. - m_uiWriteStatusReq] = - uiNodeId_p; - EplDllkCalInstance_g.m_uiWriteStatusReq = - (EplDllkCalInstance_g.m_uiWriteStatusReq + - 1) % - tabentries(EplDllkCalInstance_g. - m_auiQueueStatusReq); - break; - } - - default: - { - Ret = kEplDllInvalidParam; - goto Exit; - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncGetSoaRequest() -// -// Description: returns next request for SoA. This function is called by DLLk module. -// -// Parameters: pReqServiceId_p = pointer to request service ID -// IN: available request for MN NMT or generic request queue (Flag2.PR) -// or kEplDllReqServiceNo if queues are empty -// OUT: next request -// puiNodeId_p = OUT: pointer to node ID of next request -// = EPL_C_ADR_INVALID, if request is self addressed -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p, - unsigned int *puiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiCount; - -// *pReqServiceId_p = kEplDllReqServiceNo; - - for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--) { - switch (EplDllkCalInstance_g.m_uiNextRequestQueue) { - case 0: - { // CnGenReq - for (; - EplDllkCalInstance_g. - m_uiNextQueueCnRequest < - (tabentries - (EplDllkCalInstance_g. - m_auiQueueCnRequests) / 2); - EplDllkCalInstance_g. - m_uiNextQueueCnRequest++) { - if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found - // remove one request from queue - EplDllkCalInstance_g. - m_auiQueueCnRequests - [EplDllkCalInstance_g. - m_uiNextQueueCnRequest]--; - *puiNodeId_p = - EplDllkCalInstance_g. - m_uiNextQueueCnRequest + 1; - *pReqServiceId_p = - kEplDllReqServiceUnspecified; - EplDllkCalInstance_g. - m_uiNextQueueCnRequest++; - if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) { // last node reached - // continue with CnNmtReq queue at next SoA - EplDllkCalInstance_g. - m_uiNextRequestQueue - = 1; - } - goto Exit; - } - } - // all CnGenReq queues are empty -> continue with CnNmtReq queue - EplDllkCalInstance_g.m_uiNextRequestQueue = 1; - break; - } - - case 1: - { // CnNmtReq - for (; - EplDllkCalInstance_g. - m_uiNextQueueCnRequest < - tabentries(EplDllkCalInstance_g. - m_auiQueueCnRequests); - EplDllkCalInstance_g. - m_uiNextQueueCnRequest++) { - if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found - // remove one request from queue - EplDllkCalInstance_g. - m_auiQueueCnRequests - [EplDllkCalInstance_g. - m_uiNextQueueCnRequest]--; - *puiNodeId_p = - EplDllkCalInstance_g. - m_uiNextQueueCnRequest + 1 - - (tabentries - (EplDllkCalInstance_g. - m_auiQueueCnRequests) / - 2); - *pReqServiceId_p = - kEplDllReqServiceNmtRequest; - EplDllkCalInstance_g. - m_uiNextQueueCnRequest++; - if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests)) { // last node reached - // restart CnGenReq queue - EplDllkCalInstance_g. - m_uiNextQueueCnRequest - = 0; - // continue with MnGenReq queue at next SoA - EplDllkCalInstance_g. - m_uiNextRequestQueue - = 2; - } - goto Exit; - } - } - // restart CnGenReq queue - EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0; - // all CnNmtReq queues are empty -> continue with MnGenReq queue - EplDllkCalInstance_g.m_uiNextRequestQueue = 2; - break; - } - - case 2: - { // MnNmtReq and MnGenReq - // next queue will be MnIdentReq queue - EplDllkCalInstance_g.m_uiNextRequestQueue = 3; - if (*pReqServiceId_p != kEplDllReqServiceNo) { - *puiNodeId_p = EPL_C_ADR_INVALID; // DLLk must exchange this with the actual node ID - goto Exit; - } - break; - } - - case 3: - { // MnIdentReq - // next queue will be MnStatusReq queue - EplDllkCalInstance_g.m_uiNextRequestQueue = 4; - if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq) { // queue is not empty - *puiNodeId_p = - EplDllkCalInstance_g. - m_auiQueueIdentReq - [EplDllkCalInstance_g. - m_uiReadIdentReq]; - EplDllkCalInstance_g.m_uiReadIdentReq = - (EplDllkCalInstance_g. - m_uiReadIdentReq + - 1) % - tabentries(EplDllkCalInstance_g. - m_auiQueueIdentReq); - *pReqServiceId_p = - kEplDllReqServiceIdent; - goto Exit; - } - break; - } - - case 4: - { // MnStatusReq - // next queue will be CnGenReq queue - EplDllkCalInstance_g.m_uiNextRequestQueue = 0; - if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq) { // queue is not empty - *puiNodeId_p = - EplDllkCalInstance_g. - m_auiQueueStatusReq - [EplDllkCalInstance_g. - m_uiReadStatusReq]; - EplDllkCalInstance_g.m_uiReadStatusReq = - (EplDllkCalInstance_g. - m_uiReadStatusReq + - 1) % - tabentries(EplDllkCalInstance_g. - m_auiQueueStatusReq); - *pReqServiceId_p = - kEplDllReqServiceStatus; - goto Exit; - } - break; - } - - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDllkCalAsyncSetPendingRequests() -// -// Description: sets the pending asynchronous frame requests of the specified node. -// This will add the node to the asynchronous request scheduler. -// -// Parameters: uiNodeId_p = node ID -// AsyncReqPrio_p = asynchronous request priority -// uiCount_p = count of asynchronous frames -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, - tEplDllAsyncReqPriority - AsyncReqPrio_p, - unsigned int uiCount_p) -{ - tEplKernel Ret = kEplSuccessful; - - // add node to appropriate request queue - switch (AsyncReqPrio_p) { - case kEplDllAsyncReqPrioNmt: - { - uiNodeId_p--; - if (uiNodeId_p >= - (tabentries - (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) { - Ret = kEplDllInvalidParam; - goto Exit; - } - uiNodeId_p += - tabentries(EplDllkCalInstance_g. - m_auiQueueCnRequests) / 2; - EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = - uiCount_p; - break; - } - - default: - { - uiNodeId_p--; - if (uiNodeId_p >= - (tabentries - (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) { - Ret = kEplDllInvalidParam; - goto Exit; - } - EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = - uiCount_p; - break; - } - } - - Exit: - return Ret; -} -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// Callback handler for new data signaling -//--------------------------------------------------------------------------- - -#ifndef EPL_NO_FIFO -/*static void EplDllkCalTxNmtSignalHandler ( - tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p) -{ -tEplKernel Ret = kEplSuccessful; -tEplEvent Event; -tEplDllAsyncReqPriority Priority; -#ifndef EPL_NO_FIFO -tShbError ShbError; -unsigned long ulBlockCount; - - ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount); - if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt) - { - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount; - } - -#endif - - // post event to DLL - Priority = kEplDllAsyncReqPrioNmt; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - -} - -static void EplDllkCalTxGenSignalHandler ( - tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p) -{ -tEplKernel Ret = kEplSuccessful; -tEplEvent Event; -tEplDllAsyncReqPriority Priority; -#ifndef EPL_NO_FIFO -tShbError ShbError; -unsigned long ulBlockCount; - - ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount); - if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen) - { - EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount; - } - -#endif - - // post event to DLL - Priority = kEplDllAsyncReqPrioGeneric; - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &Priority; - Event.m_uiSize = sizeof(Priority); - Ret = EplEventkPost(&Event); - -} -*/ -#endif - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c deleted file mode 100644 index f96fe84c497..00000000000 --- a/drivers/staging/epl/EplDlluCal.c +++ /dev/null @@ -1,529 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for DLL Communication Abstraction Layer module in EPL user part - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDlluCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.7 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "user/EplDlluCal.h" -#include "user/EplEventu.h" - -#include "EplDllCal.h" - -// include only if direct call between user- and kernelspace is enabled -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) -#include "kernel/EplDllkCal.h" -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplDlluCal */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - tEplDlluCbAsnd m_apfnDlluCbAsnd[EPL_DLL_MAX_ASND_SERVICE_ID]; - -} tEplDlluCalInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -// if no dynamic memory allocation shall be used -// define structures statically -static tEplDlluCalInstance EplDlluCalInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId - ServiceId_p, - tEplDllAsndFilter Filter_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalAddInstance() -// -// Description: add and initialize new instance of DLL CAL module -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalAddInstance(void) -{ - tEplKernel Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof(EplDlluCalInstance_g)); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalDelInstance() -// -// Description: deletes an instance of DLL CAL module -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalDelInstance(void) -{ - tEplKernel Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof(EplDlluCalInstance_g)); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalProcess -// -// Description: process the passed asynch frame -// -// Parameters: pEvent_p = event containing frame to be processed -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplMsgType MsgType; - unsigned int uiAsndServiceId; - tEplFrameInfo FrameInfo; - - if (pEvent_p->m_EventType == kEplEventTypeAsndRx) { - FrameInfo.m_pFrame = (tEplFrame *) pEvent_p->m_pArg; - FrameInfo.m_uiFrameSize = pEvent_p->m_uiSize; - // extract NetTime - FrameInfo.m_NetTime = pEvent_p->m_NetTime; - - MsgType = - (tEplMsgType) AmiGetByteFromLe(&FrameInfo.m_pFrame-> - m_le_bMessageType); - if (MsgType != kEplMsgTypeAsnd) { - Ret = kEplInvalidOperation; - goto Exit; - } - - uiAsndServiceId = - (unsigned int)AmiGetByteFromLe(&FrameInfo.m_pFrame->m_Data. - m_Asnd.m_le_bServiceId); - if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) { // ASnd service ID is valid - if (EplDlluCalInstance_g.m_apfnDlluCbAsnd[uiAsndServiceId] != NULL) { // handler was registered - Ret = - EplDlluCalInstance_g. - m_apfnDlluCbAsnd[uiAsndServiceId] - (&FrameInfo); - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalRegAsndService() -// -// Description: registers the specified handler for the specified -// AsndServiceId with the specified node ID filter. -// -// Parameters: ServiceId_p = ASnd Service ID -// pfnDlluCbAsnd_p = callback function -// Filter_p = node ID filter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p, - tEplDlluCbAsnd pfnDlluCbAsnd_p, - tEplDllAsndFilter Filter_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (ServiceId_p < tabentries(EplDlluCalInstance_g.m_apfnDlluCbAsnd)) { - // memorize function pointer - EplDlluCalInstance_g.m_apfnDlluCbAsnd[ServiceId_p] = - pfnDlluCbAsnd_p; - - if (pfnDlluCbAsnd_p == NULL) { // close filter - Filter_p = kEplDllAsndFilterNone; - } - // set filter in DLL module in kernel part - Ret = EplDlluCalSetAsndServiceIdFilter(ServiceId_p, Filter_p); - - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalAsyncSend() -// -// Description: sends the frame with the specified priority. -// -// Parameters: pFrameInfo_p = frame -// m_uiFrameSize does not include the -// ethernet header (14 bytes) -// Priority_p = priority -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo_p, - tEplDllAsyncReqPriority Priority_p) -{ - tEplKernel Ret = kEplSuccessful; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - pFrameInfo_p->m_uiFrameSize += 14; // add size of ethernet header - Ret = EplDllkCalAsyncSend(pFrameInfo_p, Priority_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalIssueRequest() -// -// Description: issues a StatusRequest or a IdentRequest to the specified node. -// -// Parameters: Service_p = request service ID -// uiNodeId_p = node ID -// bSoaFlag1_p = flag1 for this node (transmit in SoA and PReq) -// If 0xFF this flag is ignored. -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p, - unsigned int uiNodeId_p, u8 bSoaFlag1_p) -{ - tEplKernel Ret = kEplSuccessful; - - // add node to appropriate request queue - switch (Service_p) { - case kEplDllReqServiceIdent: - case kEplDllReqServiceStatus: - { - tEplEvent Event; - tEplDllCalIssueRequest IssueReq; - - Event.m_EventSink = kEplEventSinkDllkCal; - Event.m_EventType = kEplEventTypeDllkIssueReq; - IssueReq.m_Service = Service_p; - IssueReq.m_uiNodeId = uiNodeId_p; - IssueReq.m_bSoaFlag1 = bSoaFlag1_p; - Event.m_pArg = &IssueReq; - Event.m_uiSize = sizeof(IssueReq); - - Ret = EplEventuPost(&Event); - break; - } - - default: - { - Ret = kEplDllInvalidParam; - goto Exit; - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalAddNode() -// -// Description: adds the specified node to the isochronous phase. -// -// Parameters: pNodeInfo_p = pointer of node info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkDllkCal; - Event.m_EventType = kEplEventTypeDllkAddNode; - Event.m_pArg = pNodeInfo_p; - Event.m_uiSize = sizeof(tEplDllNodeInfo); - - Ret = EplEventuPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalDeleteNode() -// -// Description: removes the specified node from the isochronous phase. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkDllkCal; - Event.m_EventType = kEplEventTypeDllkDelNode; - Event.m_pArg = &uiNodeId_p; - Event.m_uiSize = sizeof(uiNodeId_p); - - Ret = EplEventuPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalSoftDeleteNode() -// -// Description: removes the specified node softly from the isochronous phase. -// -// Parameters: uiNodeId_p = node ID -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkDllkCal; - Event.m_EventType = kEplEventTypeDllkSoftDelNode; - Event.m_pArg = &uiNodeId_p; - Event.m_uiSize = sizeof(uiNodeId_p); - - Ret = EplEventuPost(&Event); - - return Ret; -} - -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplDlluCalSetAsndServiceIdFilter() -// -// Description: forwards call to EplDllkSetAsndServiceIdFilter() in kernel part -// -// Parameters: ServiceId_p = ASnd Service ID -// Filter_p = node ID filter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId - ServiceId_p, - tEplDllAsndFilter Filter_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - tEplDllCalAsndServiceIdFilter ServFilter; - - Event.m_EventSink = kEplEventSinkDllkCal; - Event.m_EventType = kEplEventTypeDllkServFilter; - ServFilter.m_ServiceId = ServiceId_p; - ServFilter.m_Filter = Filter_p; - Event.m_pArg = &ServFilter; - Event.m_uiSize = sizeof(ServFilter); - - Ret = EplEventuPost(&Event); - - return Ret; -} - -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplErrDef.h b/drivers/staging/epl/EplErrDef.h deleted file mode 100644 index 2aee12cfd28..00000000000 --- a/drivers/staging/epl/EplErrDef.h +++ /dev/null @@ -1,294 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: definitions for all EPL-function return codes - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplErrDef.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.9 $ $Date: 2008/06/23 14:56:33 $ - - $State: Exp $ - - Build Environment: - all - - ------------------------------------------------------------------------- - - Revision History: - - 2005/12/05 -as: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_ERRORDEF_H_ -#define _EPL_ERRORDEF_H_ - -//--------------------------------------------------------------------------- -// return codes -//--------------------------------------------------------------------------- - -typedef enum { - // area for generic errors 0x0000 - 0x000F - kEplSuccessful = 0x0000, // no error/successful run - kEplIllegalInstance = 0x0001, // the called Instanz does not exist - kEplInvalidInstanceParam = 0x0002, // - kEplNoFreeInstance = 0x0003, // XxxAddInstance was called but no free instance is available - kEplWrongSignature = 0x0004, // wrong signature while writing to object 0x1010 or 0x1011 - kEplInvalidOperation = 0x0005, // operation not allowed in this situation - kEplInvalidNodeId = 0x0007, // invalid NodeId was specified - kEplNoResource = 0x0008, // resource could not be created (Windows, PxROS, ...) - kEplShutdown = 0x0009, // stack is shutting down - kEplReject = 0x000A, // reject the subsequent command - - // area for EDRV module 0x0010 - 0x001F -// kEplEdrvNoFrame = 0x0010, // no CAN message was received -// kEplEdrvMsgHigh = 0x0011, // CAN message with high priority was received -// kEplEdrvMsgLow = 0x0012, // CAN message with low priority was received - kEplEdrvInitError = 0x0013, // initialisation error - kEplEdrvNoFreeBufEntry = 0x0014, // no free entry in internal buffer table for Tx frames - kEplEdrvBufNotExisting = 0x0015, // specified Tx buffer does not exist -// kEplEdrvNoFreeChannel = 0x0014, // CAN controller has not a free channel -// kEplEdrvTxBuffHighOverrun = 0x0015, // buffer for high priority CAN transmit messages has overrun -// kEplEdrvTxBuffLowOverrun = 0x0016, // buffer for low priority CAN transmit messages has overrun -// kEplEdrvIllegalBdi = 0x0017, // unsupported baudrate within baudrate table -// kEplEdrvBusy = 0x0018, // remote frame can not be updated because no bus contact or CAN - // transmission is activ -// kEplEdrvInvalidDriverType = 0x0019, // (PC: Windows or Linux) invalid driver type -// kEplEdrvDriverNotFound = 0x001A, // (PC: Windows or Linux) driver (DLL) could not be found -// kEplEdrvInvalidBaseAddress = 0x001B, // (PC: Windows or Linux) driver could not found the CAN controller -// kEplEdrvInvalidParam = 0x001C, // invalid param in function call - - // area for COB module 0x0020 - 0x002F -/* kEplCobNoFreeEntry = 0x0020, // no free entry in RX- or TX-COB table - kEplCobAlreadyExist = 0x0021, // COB-ID already exists in RX- resp. TX-COB table - */ - kEplDllIllegalHdl = 0x0022, // illegal handle for a TxFrame was passed - kEplDllCbAsyncRegistered = 0x0023, // handler for non-EPL frames was already registered before -// kEplDllAsyncRxBufferFull = 0x0024, // receive buffer for asynchronous frames is full - kEplDllAsyncTxBufferEmpty = 0x0025, // transmit buffer for asynchronous frames is empty - kEplDllAsyncTxBufferFull = 0x0026, // transmit buffer for asynchronous frames is full - kEplDllNoNodeInfo = 0x0027, // MN: too less space in the internal node info structure - kEplDllInvalidParam = 0x0028, // invalid parameters passed to function - kEplDllTxBufNotReady = 0x002E, // TxBuffer (e.g. for PReq) is not ready yet - kEplDllTxFrameInvalid = 0x002F, // TxFrame (e.g. for PReq) is invalid or does not exist -/* kEplCobIllegalCanId = 0x0023, // COB-ID is not allowed (like 0x000 is reserved for NMT, ...) - kEplCobInvalidCanId = 0x0024, // COB-ID is switched off - kEplCobCdrvStateSet = 0x0025, // at least one bit of CAN driver state is set - kEplCobNoFreeEntryHighBuf = 0x0026, // no free entry in high priotity RX- or TX-COB table - kEplCobOwnId = 0x0027, // COB-ID already exists in own module which calls CobDefine() or CobCheck() -*/ - // area for OBD module 0x0030 - 0x003F - kEplObdIllegalPart = 0x0030, // unknown OD part - kEplObdIndexNotExist = 0x0031, // object index does not exist in OD - kEplObdSubindexNotExist = 0x0032, // subindex does not exist in object index - kEplObdReadViolation = 0x0033, // read access to a write-only object - kEplObdWriteViolation = 0x0034, // write access to a read-only object - kEplObdAccessViolation = 0x0035, // access not allowed - kEplObdUnknownObjectType = 0x0036, // object type not defined/known - kEplObdVarEntryNotExist = 0x0037, // object does not contain VarEntry structure - kEplObdValueTooLow = 0x0038, // value to write to an object is too low - kEplObdValueTooHigh = 0x0039, // value to write to an object is too high - kEplObdValueLengthError = 0x003A, // value to write is to long or to short -// kEplObdIllegalFloat = 0x003B, // illegal float variable -// kEplObdWrongOdBuilderKey = 0x003F, // OD was generated with demo version of tool ODBuilder - - // area for NMT module 0x0040 - 0x004F - kEplNmtUnknownCommand = 0x0040, // unknown NMT command - kEplNmtInvalidFramePointer = 0x0041, // pointer to the frame is not valid - kEplNmtInvalidEvent = 0x0042, // invalid event send to NMT-modul - kEplNmtInvalidState = 0x0043, // unknown state in NMT-State-Maschine - kEplNmtInvalidParam = 0x0044, // invalid parameters specified - - // area for SDO/UDP module 0x0050 - 0x005F - kEplSdoUdpMissCb = 0x0050, // missing callback-function pointer during inti of - // module - kEplSdoUdpNoSocket = 0x0051, // error during init of socket - kEplSdoUdpSocketError = 0x0052, // error during usage of socket - kEplSdoUdpThreadError = 0x0053, // error during start of listen thread - kEplSdoUdpNoFreeHandle = 0x0054, // no free connection handle for Udp - kEplSdoUdpSendError = 0x0055, // Error during send of frame - kEplSdoUdpInvalidHdl = 0x0056, // the connection handle is invalid - - // area for SDO Sequence layer module 0x0060 - 0x006F - kEplSdoSeqMissCb = 0x0060, // no callback-function assign - kEplSdoSeqNoFreeHandle = 0x0061, // no free handle for connection - kEplSdoSeqInvalidHdl = 0x0062, // invalid handle in SDO sequence layer - kEplSdoSeqUnsupportedProt = 0x0063, // unsupported Protocol selected - kEplSdoSeqNoFreeHistory = 0x0064, // no free entry in history - kEplSdoSeqFrameSizeError = 0x0065, // the size of the frames is not correct - kEplSdoSeqRequestAckNeeded = 0x0066, // indeicates that the history buffer is full - // and a ack request is needed - kEplSdoSeqInvalidFrame = 0x0067, // frame not valid - kEplSdoSeqConnectionBusy = 0x0068, // connection is busy -> retry later - kEplSdoSeqInvalidEvent = 0x0069, // invalid event received - - // area for SDO Command Layer Module 0x0070 - 0x007F - kEplSdoComUnsupportedProt = 0x0070, // unsupported Protocol selected - kEplSdoComNoFreeHandle = 0x0071, // no free handle for connection - kEplSdoComInvalidServiceType = 0x0072, // invalid SDO service type specified - kEplSdoComInvalidHandle = 0x0073, // handle invalid - kEplSdoComInvalidSendType = 0x0074, // the stated to of frame to send is - // not possible - kEplSdoComNotResponsible = 0x0075, // internal error: command layer handle is - // not responsible for this event from sequence layer - kEplSdoComHandleExists = 0x0076, // handle to same node already exists - kEplSdoComHandleBusy = 0x0077, // transfer via this handle is already running - kEplSdoComInvalidParam = 0x0078, // invalid parameters passed to function - - // area for EPL Event-Modul 0x0080 - 0x008F - kEplEventUnknownSink = 0x0080, // unknown sink for event - kEplEventPostError = 0x0081, // error during post of event - - // area for EPL Timer Modul 0x0090 - 0x009F - kEplTimerInvalidHandle = 0x0090, // invalid handle for timer - kEplTimerNoTimerCreated = 0x0091, // no timer was created caused by - // an error - - // area for EPL SDO/Asnd Module 0x00A0 - 0x0AF - kEplSdoAsndInvalidNodeId = 0x00A0, //0 node id is invalid - kEplSdoAsndNoFreeHandle = 0x00A1, // no free handle for connection - kEplSdoAsndInvalidHandle = 0x00A2, // handle for connection is invalid - - // area for PDO module 0x00B0 - 0x00BF - kEplPdoNotExist = 0x00B0, // selected PDO does not exist - kEplPdoLengthExceeded = 0x00B1, // length of PDO mapping exceedes 64 bis - kEplPdoGranularityMismatch = 0x00B2, // configured PDO granularity is not equal to supported granularity - kEplPdoInitError = 0x00B3, // error during initialisation of PDO module - kEplPdoErrorPdoEncode = 0x00B4, // error during encoding a PDO - kEplPdoErrorPdoDecode = 0x00B5, // error during decoding a PDO - kEplPdoErrorSend = 0x00B6, // error during sending a PDO - kEplPdoErrorSyncWin = 0x00B7, // the SYNC window runs out during sending SYNC-PDOs - kEplPdoErrorMapp = 0x00B8, // invalid PDO mapping - kEplPdoVarNotFound = 0x00B9, // variable was not found in function PdoSignalVar() - kEplPdoErrorEmcyPdoLen = 0x00BA, // the length of a received PDO is unequal to the expected value - kEplPdoWriteConstObject = 0x00BB, // constant object can not be written - // (only TxType, Inhibit-, Event Time for CANopen Kit) - - // area for LSS slave module -/* kEplLsssResetNode = 0x0080, // NMT command "reset node" has to be processed after LSS configuration - // new of NodeId - kEplLsssInvalidNodeId = 0x0081, // no valid NodeId is configured -> wait until it is configured with - // LSS service before calling CcmConnectToNet() -*/ - // area for emergency consumer module 0x0090 - 0x009F -/* kEplEmccNoFreeProducerEntry = 0x0090, // no free entry to add a Emergency Producer - kEplEmccNodeIdNotExist = 0x0091, // selected NodeId was never added - kEplEmccNodeIdInvalid = 0x0092, // selected NodeId is outside of range (0x01 until 0x7F) - kEplEmccNodeIdExist = 0x0093, // selected NodeId already exist -*/ - // area for dynamic OD 0x00A0 - 0x00AF -/* kEplDynNoMemory = 0x00A0, // no memory available - kEplDynInvalidConfig = 0x00A1, // invalid configuration in segment container -*/ - // area for hertbeat consumer module 0x00B0 - 0x00BF -/* kEplHbcEntryNotExist = 0x00B0, // Heartbeat Producer node not configured - kEplHbcEntryAlreadyExist = 0x00B1, // NodeId was already defined in heartbeat consumer table (object 0x1016) -*/ - // Configuration manager module 0x00C0 - 0x00CF - kEplCfgMaConfigError = 0x00C0, // error in configuration manager - kEplCfgMaSdocTimeOutError = 0x00C1, // error in configuration manager, Sdo timeout - kEplCfgMaInvalidDcf = 0x00C2, // configration file not valid - kEplCfgMaUnsupportedDcf = 0x00C3, // unsupported Dcf format - kEplCfgMaConfigWithErrors = 0x00C4, // configuration finished with errors - kEplCfgMaNoFreeConfig = 0x00C5, // no free configuration entry - kEplCfgMaNoConfigData = 0x00C6, // no configuration data present - kEplCfgMaUnsuppDatatypeDcf = 0x00C7, // unsupported datatype found in dcf - // -> this entry was not configured - - // area for LSS master module 0x00D0 - 0x00DF -/* kEplLssmIllegalMode = 0x00D0, // illegal LSS mode (operation / configuration) - kEplLssmIllegalState = 0x00D1, // function was called in illegal state of LSS master - kEplLssmBusy = 0x00D2, // LSS process is busy with an previous service - kEplLssmIllegalCmd = 0x00D3, // illegal command code was set for function LssmInquireIdentity() - kEplLssmTimeout = 0x00D4, // LSS slave did not answer a LSS service - kEplLssmErrorInConfirm = 0x00D5, // LSS slave replied an error code for a LSS service -*/ - // area for CCM modules 0x00E0 - 0xEF -/* kEplCcmStoreUnvalidState = 0x00E0, // memory device not available due device state - kEplCcmStoreHwError = 0x00E1, // hw error due device access -*/ - // area for SRDO module 0x0100 - 0x011F -/* kEplSrdoNotExist = 0x0100, // selected SRDO does not exist - kEplSrdoGranularityMismatch = 0x0101, // configured SRDO granularity is not equal to supported granularity - kEplSrdoCfgTimingError = 0x0102, // configuration is not ok (Timing) - kEplSrdoCfgIdError = 0x0103, // configuration is not ok (CobIds) - kEplSrdoCfgCrcError = 0x0104, // configuration is not ok (CRC) - kEplSrdoNmtError = 0x0105, // an action was tried in a wrong NMT state - kEplSrdoInvalidCfg = 0x0106, // an action was tried with an invald SRDO configuration - kEplSrdoInvalid = 0x0107, // an action was tried with an invald SRDO - kEplSrdoRxTxConflict = 0x0108, // an transmission was tried with an receive SRDO (or the other way) - kEplSrdoIllegalCanId = 0x0109, // the CanId is invalid - kEplSrdoCanIdAlreadyInUse = 0x010A, // the CanId is already in use - kEplSrdoNotInOrder = 0x010B, // the two messages of a SRDO are not in order - kEplSrdoSctTimeout = 0x010C, // timeout of SCT - kEplSrdoSrvtTimeout = 0x010D, // timeout of SRVT - kEplSrdoCanIdNotValid = 0x010E, // one of received CAN-IDs are not equal to configured one - kEplSrdoDlcNotValid = 0x010F, // one of received CAN-DLC are not equal to configured one - kEplSrdoErrorMapp = 0x0110, // wrong values in mapping found - kEplSrdoDataError = 0x0111, // data of CAN messages are not invers - kEplSrdoLengthExceeded = 0x0112, // length of SRDO mapping exceedes 64 bit per CAN-message - kEplSrdoNotHandledInApp = 0x0113, // the SRDO error was not handled in AppSrdoError() - kEplSrdoOverrun = 0x0114 // a RxSRDO was received but the pevious one was not else processed -*/ - - kEplApiTaskDeferred = 0x0140, // EPL performs task in background and informs the application (or vice-versa), when it is finished - kEplApiInvalidParam = 0x0142, // passed invalid parameters to a function (e.g. invalid node id) - - // area untill 0x07FF is reserved - // area for user application from 0x0800 to 0x7FFF - -} tEplKernel; - -#endif -//EOF - -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler -// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c deleted file mode 100644 index 6baed04ef11..00000000000 --- a/drivers/staging/epl/EplErrorHandlerk.c +++ /dev/null @@ -1,810 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for error handler module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplErrorHandlerk.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.9 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/10/02 d.k.: start of the implementation - -****************************************************************************/ - -#include "kernel/EplErrorHandlerk.h" -#include "EplNmt.h" -#include "kernel/EplEventk.h" -#include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul -#include "kernel/EplDllk.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0) -#error "EPL ErrorHandler module needs EPL module OBDK!" -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - u32 m_dwCumulativeCnt; // subindex 1 - u32 m_dwThresholdCnt; // subindex 2 - u32 m_dwThreshold; // subindex 3 - -} tEplErrorHandlerkErrorCounter; - -typedef struct { - tEplErrorHandlerkErrorCounter m_CnLossSoc; // object 0x1C0B - tEplErrorHandlerkErrorCounter m_CnLossPreq; // object 0x1C0D - tEplErrorHandlerkErrorCounter m_CnCrcErr; // object 0x1C0F - unsigned long m_ulDllErrorEvents; - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - tEplErrorHandlerkErrorCounter m_MnCrcErr; // object 0x1C00 - tEplErrorHandlerkErrorCounter m_MnCycTimeExceed; // object 0x1C02 - u32 m_adwMnCnLossPresCumCnt[254]; // object 0x1C07 - u32 m_adwMnCnLossPresThrCnt[254]; // object 0x1C08 - u32 m_adwMnCnLossPresThreshold[254]; // object 0x1C09 - BOOL m_afMnCnLossPresEvent[254]; -#endif - -} tEplErrorHandlerkInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplErrorHandlerkInstance EplErrorHandlerkInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter - * pErrorCounter_p, - unsigned int uiIndex_p); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p, - unsigned int uiValueCount_p, - unsigned int uiIndex_p); -#endif - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkInit -// -// Description: function initialize the first instance -// -// -// -// Parameters: -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplErrorHandlerkInit(void) -{ - tEplKernel Ret; - - Ret = EplErrorHandlerkAddInstance(); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkAddInstance -// -// Description: function add one more instance -// -// -// -// Parameters: -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplErrorHandlerkAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset only event variable, - // all other instance members are reset by OD or may keep their current value - // d.k.: this is necessary for the cumulative counters, which shall not be reset - EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0; - - // link counters to OD - // $$$ d.k. if OD resides in userspace, fetch pointer to shared memory, - // which shall have the same structure as the instance (needs to be declared globally). - // Other idea: error counter shall belong to the process image - // (reset of counters by SDO write are a little bit tricky). - - Ret = - EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g. - m_CnLossSoc, 0x1C0B); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = - EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g. - m_CnLossPreq, 0x1C0D); - // ignore return code, because object 0x1C0D is conditional - - Ret = - EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g. - m_CnCrcErr, 0x1C0F); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - Ret = - EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g. - m_MnCrcErr, 0x1C00); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = - EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g. - m_MnCycTimeExceed, 0x1C02); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = - EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresCumCnt, - tabentries(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresCumCnt), - 0x1C07); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = - EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThrCnt, - tabentries(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThrCnt), - 0x1C08); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = - EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThreshold, - tabentries(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThreshold), - 0x1C09); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkDelInstance -// -// Description: function delete instance an free the bufferstructure -// -// -// -// Parameters: -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplErrorHandlerkDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkProcess -// -// Description: processes error events from DLL -// -// -// -// Parameters: pEvent_p = pointer to event-structur from buffer -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - unsigned long ulDllErrorEvents; - tEplEvent Event; - tEplNmtEvent NmtEvent; - - Ret = kEplSuccessful; - - // check m_EventType - switch (pEvent_p->m_EventType) { - case kEplEventTypeDllError: - { - tEplErrorHandlerkEvent *pErrHandlerEvent = - (tEplErrorHandlerkEvent *) pEvent_p->m_pArg; - - ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents; - - // check the several error events - if ((EplErrorHandlerkInstance_g.m_CnLossSoc. - m_dwThreshold > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0)) { // loss of SoC event occured - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g.m_CnLossSoc. - m_dwCumulativeCnt++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g.m_CnLossSoc. - m_dwThresholdCnt += 8; - if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) { // threshold is reached - // $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH - - // post event to NMT state machine - NmtEvent = kEplNmtEventNmtCycleError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_LOSS_SOC; - } - - if ((EplErrorHandlerkInstance_g.m_CnLossPreq. - m_dwThreshold > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0)) { // loss of PReq event occured - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g.m_CnLossPreq. - m_dwCumulativeCnt++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g.m_CnLossPreq. - m_dwThresholdCnt += 8; - if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) { // threshold is reached - // $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH - - // post event to NMT state machine - NmtEvent = kEplNmtEventNmtCycleError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - } - - if ((EplErrorHandlerkInstance_g.m_CnLossPreq. - m_dwThresholdCnt > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) { // PReq correctly received - // decrement threshold counter by 1 - EplErrorHandlerkInstance_g.m_CnLossPreq. - m_dwThresholdCnt--; - } - - if ((EplErrorHandlerkInstance_g.m_CnCrcErr. - m_dwThreshold > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0)) { // CRC error event occured - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g.m_CnCrcErr. - m_dwCumulativeCnt++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g.m_CnCrcErr. - m_dwThresholdCnt += 8; - if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) { // threshold is reached - // $$$ d.k.: generate error history entry E_DLL_CRC_TH - - // post event to NMT state machine - NmtEvent = kEplNmtEventNmtCycleError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= - EPL_DLL_ERR_CN_CRC; - } - - if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) { // invalid format error occured (only direct reaction) - // $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) { // MN is active - if (pErrHandlerEvent->m_uiNodeId != 0) { - tEplHeartbeatEvent - HeartbeatEvent; - - // remove node from isochronous phase - Ret = - EplDllkDeleteNode - (pErrHandlerEvent-> - m_uiNodeId); - - // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN - HeartbeatEvent.m_uiNodeId = - pErrHandlerEvent-> - m_uiNodeId; - HeartbeatEvent.m_NmtState = - kEplNmtCsNotActive; - HeartbeatEvent.m_wErrorCode = - EPL_E_DLL_INVALID_FORMAT; - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeHeartbeat; - Event.m_uiSize = - sizeof(HeartbeatEvent); - Event.m_pArg = &HeartbeatEvent; - Ret = EplEventkPost(&Event); - } - // $$$ and else should lead to InternComError - } else -#endif - { // CN is active - // post event to NMT state machine - NmtEvent = kEplNmtEventInternComError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if ((EplErrorHandlerkInstance_g.m_MnCrcErr. - m_dwThreshold > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0)) { // CRC error event occured - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g.m_MnCrcErr. - m_dwCumulativeCnt++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g.m_MnCrcErr. - m_dwThresholdCnt += 8; - if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) { // threshold is reached - // $$$ d.k.: generate error history entry E_DLL_CRC_TH - - // post event to NMT state machine - NmtEvent = kEplNmtEventNmtCycleError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= - EPL_DLL_ERR_MN_CRC; - } - - if ((EplErrorHandlerkInstance_g.m_MnCycTimeExceed. - m_dwThreshold > 0) - && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0)) { // cycle time exceeded event occured - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g.m_MnCycTimeExceed. - m_dwCumulativeCnt++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g.m_MnCycTimeExceed. - m_dwThresholdCnt += 8; - if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) { // threshold is reached - // $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH - - // post event to NMT state machine - NmtEvent = kEplNmtEventNmtCycleError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_EventType = - kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplEventkPost(&Event); - } - // $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED - EplErrorHandlerkInstance_g.m_ulDllErrorEvents |= - EPL_DLL_ERR_MN_CYCTIMEEXCEED; - } - - if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) { // CN loss PRes event occured - unsigned int uiNodeId; - - uiNodeId = pErrHandlerEvent->m_uiNodeId - 1; - if ((uiNodeId < - tabentries(EplErrorHandlerkInstance_g. - m_adwMnCnLossPresCumCnt)) - && (EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThreshold[uiNodeId] > - 0)) { - // increment cumulative counter by 1 - EplErrorHandlerkInstance_g. - m_adwMnCnLossPresCumCnt[uiNodeId]++; - // increment threshold counter by 8 - EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThrCnt[uiNodeId] += - 8; - if (EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThrCnt[uiNodeId] - >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) { // threshold is reached - tEplHeartbeatEvent - HeartbeatEvent; - - // $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH - - // remove node from isochronous phase - Ret = - EplDllkDeleteNode - (pErrHandlerEvent-> - m_uiNodeId); - - // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN - HeartbeatEvent.m_uiNodeId = - pErrHandlerEvent-> - m_uiNodeId; - HeartbeatEvent.m_NmtState = - kEplNmtCsNotActive; - HeartbeatEvent.m_wErrorCode = - EPL_E_DLL_LOSS_PRES_TH; - Event.m_EventSink = - kEplEventSinkNmtMnu; - Event.m_EventType = - kEplEventTypeHeartbeat; - Event.m_uiSize = - sizeof(HeartbeatEvent); - Event.m_pArg = &HeartbeatEvent; - Ret = EplEventkPost(&Event); - } - EplErrorHandlerkInstance_g. - m_afMnCnLossPresEvent[uiNodeId] = - TRUE; - } - } -#endif - - break; - } - - // NMT event - case kEplEventTypeNmtEvent: - { - if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllCeSoa) { // SoA event of CN -> decrement threshold counters - - if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0) { // decrement loss of SoC threshold counter, because it didn't occur last cycle - if (EplErrorHandlerkInstance_g. - m_CnLossSoc.m_dwThresholdCnt > 0) { - EplErrorHandlerkInstance_g. - m_CnLossSoc. - m_dwThresholdCnt--; - } - } - - if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0) { // decrement CRC threshold counter, because it didn't occur last cycle - if (EplErrorHandlerkInstance_g. - m_CnCrcErr.m_dwThresholdCnt > 0) { - EplErrorHandlerkInstance_g. - m_CnCrcErr. - m_dwThresholdCnt--; - } - } - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - else if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent) { // SoA event of MN -> decrement threshold counters - tEplDllkNodeInfo *pIntNodeInfo; - unsigned int uiNodeId; - - Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo); - if (Ret != kEplSuccessful) { - break; - } - // iterate through node info structure list - while (pIntNodeInfo != NULL) { - uiNodeId = pIntNodeInfo->m_uiNodeId - 1; - if (uiNodeId < - tabentries - (EplErrorHandlerkInstance_g. - m_adwMnCnLossPresCumCnt)) { - if (EplErrorHandlerkInstance_g. - m_afMnCnLossPresEvent - [uiNodeId] == FALSE) { - if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0) { - EplErrorHandlerkInstance_g. - m_adwMnCnLossPresThrCnt - [uiNodeId]--; - } - } else { - EplErrorHandlerkInstance_g. - m_afMnCnLossPresEvent - [uiNodeId] = FALSE; - } - } - pIntNodeInfo = - pIntNodeInfo->m_pNextNodeInfo; - } - - if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0) { // decrement CRC threshold counter, because it didn't occur last cycle - if (EplErrorHandlerkInstance_g. - m_MnCrcErr.m_dwThresholdCnt > 0) { - EplErrorHandlerkInstance_g. - m_MnCrcErr. - m_dwThresholdCnt--; - } - } - - if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0) { // decrement cycle exceed threshold counter, because it didn't occur last cycle - if (EplErrorHandlerkInstance_g. - m_MnCycTimeExceed.m_dwThresholdCnt > - 0) { - EplErrorHandlerkInstance_g. - m_MnCycTimeExceed. - m_dwThresholdCnt--; - } - } - } -#endif - - // reset error events - EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L; - - break; - } - - // unknown type - default: - { - } - - } // end of switch(pEvent_p->m_EventType) - - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkLinkErrorCounter -// -// Description: link specified error counter structure to OD entry -// -// Parameters: pErrorCounter_p = pointer to error counter structure -// uiIndex_p = OD index -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter - * pErrorCounter_p, - unsigned int uiIndex_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplVarParam VarParam; - - VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt; - VarParam.m_Size = sizeof(u32); - VarParam.m_uiIndex = uiIndex_p; - VarParam.m_uiSubindex = 0x01; - VarParam.m_ValidFlag = kVarValidAll; - Ret = EplObdDefineVar(&VarParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - - VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt; - VarParam.m_Size = sizeof(u32); - VarParam.m_uiIndex = uiIndex_p; - VarParam.m_uiSubindex = 0x02; - VarParam.m_ValidFlag = kVarValidAll; - Ret = EplObdDefineVar(&VarParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - - VarParam.m_pData = &pErrorCounter_p->m_dwThreshold; - VarParam.m_Size = sizeof(u32); - VarParam.m_uiIndex = uiIndex_p; - VarParam.m_uiSubindex = 0x03; - VarParam.m_ValidFlag = kVarValidAll; - Ret = EplObdDefineVar(&VarParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplErrorHandlerkLinkErrorCounter -// -// Description: link specified error counter structure to OD entry -// -// Parameters: pErrorCounter_p = pointer to error counter structure -// uiIndex_p = OD index -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p, - unsigned int uiValueCount_p, - unsigned int uiIndex_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplVarParam VarParam; - tEplObdSize EntrySize; - u8 bIndexEntries; - - EntrySize = (tEplObdSize) sizeof(bIndexEntries); - Ret = EplObdReadEntry(uiIndex_p, - 0x00, (void *)&bIndexEntries, &EntrySize); - - if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) { - // Object doesn't exist or invalid entry number - Ret = kEplObdIndexNotExist; - goto Exit; - } - - if (bIndexEntries < uiValueCount_p) { - uiValueCount_p = bIndexEntries; - } - - VarParam.m_Size = sizeof(u32); - VarParam.m_uiIndex = uiIndex_p; - VarParam.m_ValidFlag = kVarValidAll; - - for (VarParam.m_uiSubindex = 0x01; - VarParam.m_uiSubindex <= uiValueCount_p; VarParam.m_uiSubindex++) { - VarParam.m_pData = pdwValue_p; - Ret = EplObdDefineVar(&VarParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - pdwValue_p++; - } - - Exit: - return Ret; -} -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h deleted file mode 100644 index 910bd69a18c..00000000000 --- a/drivers/staging/epl/EplEvent.h +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for event module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplEvent.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_EVENT_H_ -#define _EPL_EVENT_H_ - -#include "EplInc.h" -#include "EplNmt.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// name and size of event queues -#define EPL_EVENT_NAME_SHB_KERNEL_TO_USER "ShbKernelToUser" -#ifndef EPL_EVENT_SIZE_SHB_KERNEL_TO_USER -#define EPL_EVENT_SIZE_SHB_KERNEL_TO_USER 32768 // 32 kByte -#endif - -#define EPL_EVENT_NAME_SHB_USER_TO_KERNEL "ShbUserToKernel" -#ifndef EPL_EVENT_SIZE_SHB_USER_TO_KERNEL -#define EPL_EVENT_SIZE_SHB_USER_TO_KERNEL 32768 // 32 kByte -#endif - -// max size of event argument -#ifndef EPL_MAX_EVENT_ARG_SIZE -#define EPL_MAX_EVENT_ARG_SIZE 256 // because of PDO -#endif - -#define EPL_DLL_ERR_MN_CRC 0x00000001L // object 0x1C00 -#define EPL_DLL_ERR_MN_COLLISION 0x00000002L // object 0x1C01 -#define EPL_DLL_ERR_MN_CYCTIMEEXCEED 0x00000004L // object 0x1C02 -#define EPL_DLL_ERR_MN_LOSS_LINK 0x00000008L // object 0x1C03 -#define EPL_DLL_ERR_MN_CN_LATE_PRES 0x00000010L // objects 0x1C04-0x1C06 -#define EPL_DLL_ERR_MN_CN_LOSS_PRES 0x00000080L // objects 0x1C07-0x1C09 -#define EPL_DLL_ERR_CN_COLLISION 0x00000400L // object 0x1C0A -#define EPL_DLL_ERR_CN_LOSS_SOC 0x00000800L // object 0x1C0B -#define EPL_DLL_ERR_CN_LOSS_SOA 0x00001000L // object 0x1C0C -#define EPL_DLL_ERR_CN_LOSS_PREQ 0x00002000L // object 0x1C0D -#define EPL_DLL_ERR_CN_RECVD_PREQ 0x00004000L // decrement object 0x1C0D/2 -#define EPL_DLL_ERR_CN_SOC_JITTER 0x00008000L // object 0x1C0E -#define EPL_DLL_ERR_CN_CRC 0x00010000L // object 0x1C0F -#define EPL_DLL_ERR_CN_LOSS_LINK 0x00020000L // object 0x1C10 -#define EPL_DLL_ERR_MN_LOSS_STATRES 0x00040000L // objects 0x1C15-0x1C17 (should be operated by NmtMnu module) -#define EPL_DLL_ERR_BAD_PHYS_MODE 0x00080000L // no object -#define EPL_DLL_ERR_MAC_BUFFER 0x00100000L // no object (NMT_GT6) -#define EPL_DLL_ERR_INVALID_FORMAT 0x00200000L // no object (NMT_GT6) -#define EPL_DLL_ERR_ADDRESS_CONFLICT 0x00400000L // no object (remove CN from configuration) - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -// EventType determines the argument of the event -typedef enum { - kEplEventTypeNmtEvent = 0x01, // NMT event - // arg is pointer to tEplNmtEvent - kEplEventTypePdoRx = 0x02, // PDO frame received event (PRes/PReq) - // arg is pointer to tEplFrame - kEplEventTypePdoTx = 0x03, // PDO frame transmitted event (PRes/PReq) - // arg is pointer to tEplFrameInfo - kEplEventTypePdoSoa = 0x04, // SoA frame received event (isochronous phase completed) - // arg is pointer to nothing - kEplEventTypeSync = 0x05, // Sync event (e.g. SoC or anticipated SoC) - // arg is pointer to nothing - kEplEventTypeTimer = 0x06, // Timer event - // arg is pointer to tEplTimerEventArg - kEplEventTypeHeartbeat = 0x07, // Heartbeat event - // arg is pointer to tEplHeartbeatEvent - kEplEventTypeDllkCreate = 0x08, // DLL kernel create event - // arg is pointer to the new tEplNmtState - kEplEventTypeDllkDestroy = 0x09, // DLL kernel destroy event - // arg is pointer to the old tEplNmtState - kEplEventTypeDllkFillTx = 0x0A, // DLL kernel fill TxBuffer event - // arg is pointer to tEplDllAsyncReqPriority - kEplEventTypeDllkPresReady = 0x0B, // DLL kernel PRes ready event - // arg is pointer to nothing - kEplEventTypeError = 0x0C, // Error event for API layer - // arg is pointer to tEplEventError - kEplEventTypeNmtStateChange = 0x0D, // indicate change of NMT-State - // arg is pointer to tEplEventNmtStateChange - kEplEventTypeDllError = 0x0E, // DLL error event for Error handler - // arg is pointer to tEplErrorHandlerkEvent - kEplEventTypeAsndRx = 0x0F, // received ASnd frame for DLL user module - // arg is pointer to tEplFrame - kEplEventTypeDllkServFilter = 0x10, // configure ServiceIdFilter - // arg is pointer to tEplDllCalServiceIdFilter - kEplEventTypeDllkIdentity = 0x11, // configure Identity - // arg is pointer to tEplDllIdentParam - kEplEventTypeDllkConfig = 0x12, // configure ConfigParam - // arg is pointer to tEplDllConfigParam - kEplEventTypeDllkIssueReq = 0x13, // issue Ident/Status request - // arg is pointer to tEplDllCalIssueRequest - kEplEventTypeDllkAddNode = 0x14, // add node to isochronous phase - // arg is pointer to tEplDllNodeInfo - kEplEventTypeDllkDelNode = 0x15, // remove node from isochronous phase - // arg is pointer to unsigned int - kEplEventTypeDllkSoftDelNode = 0x16, // remove node softly from isochronous phase - // arg is pointer to unsigned int - kEplEventTypeDllkStartReducedCycle = 0x17, // start reduced EPL cycle on MN - // arg is pointer to nothing - kEplEventTypeNmtMnuNmtCmdSent = 0x18, // NMT command was actually sent - // arg is pointer to tEplFrame - -} tEplEventType; - -// EventSink determines the consumer of the event -typedef enum { - kEplEventSinkSync = 0x00, // Sync event for application or kernel EPL module - kEplEventSinkNmtk = 0x01, // events for Nmtk module - kEplEventSinkDllk = 0x02, // events for Dllk module - kEplEventSinkDlluCal = 0x03, // events for DlluCal module - kEplEventSinkDllkCal = 0x04, // events for DllkCal module - kEplEventSinkPdok = 0x05, // events for Pdok module - kEplEventSinkNmtu = 0x06, // events for Nmtu module - kEplEventSinkErrk = 0x07, // events for Error handler module - kEplEventSinkErru = 0x08, // events for Error signaling module - kEplEventSinkSdoAsySeq = 0x09, // events for asyncronous SDO Sequence Layer module - kEplEventSinkNmtMnu = 0x0A, // events for NmtMnu module - kEplEventSinkLedu = 0x0B, // events for Ledu module - kEplEventSinkApi = 0x0F, // events for API module - -} tEplEventSink; - -// EventSource determines the source of an errorevent -typedef enum { - // kernelspace modules - kEplEventSourceDllk = 0x01, // Dllk module - kEplEventSourceNmtk = 0x02, // Nmtk module - kEplEventSourceObdk = 0x03, // Obdk module - kEplEventSourcePdok = 0x04, // Pdok module - kEplEventSourceTimerk = 0x05, // Timerk module - kEplEventSourceEventk = 0x06, // Eventk module - kEplEventSourceSyncCb = 0x07, // sync-Cb - kEplEventSourceErrk = 0x08, // Error handler module - - // userspace modules - kEplEventSourceDllu = 0x10, // Dllu module - kEplEventSourceNmtu = 0x11, // Nmtu module - kEplEventSourceNmtCnu = 0x12, // NmtCnu module - kEplEventSourceNmtMnu = 0x13, // NmtMnu module - kEplEventSourceObdu = 0x14, // Obdu module - kEplEventSourceSdoUdp = 0x15, // Sdo/Udp module - kEplEventSourceSdoAsnd = 0x16, // Sdo/Asnd module - kEplEventSourceSdoAsySeq = 0x17, // Sdo asynchronus Sequence Layer module - kEplEventSourceSdoCom = 0x18, // Sdo command layer module - kEplEventSourceTimeru = 0x19, // Timeru module - kEplEventSourceCfgMau = 0x1A, // CfgMau module - kEplEventSourceEventu = 0x1B, // Eventu module - kEplEventSourceEplApi = 0x1C, // Api module - kEplEventSourceLedu = 0x1D, // Ledu module - -} tEplEventSource; - -// structure of EPL event (element order must not be changed!) -typedef struct { - tEplEventType m_EventType /*:28 */ ; // event type - tEplEventSink m_EventSink /*:4 */ ; // event sink - tEplNetTime m_NetTime; // timestamp - unsigned int m_uiSize; // size of argument - void *m_pArg; // argument of event - -} tEplEvent; - -// short structure of EPL event without argument and its size (element order must not be changed!) -typedef struct { - tEplEventType m_EventType /*:28 */ ; // event type - tEplEventSink m_EventSink /*:4 */ ; // event sink - tEplNetTime m_NetTime; // timestamp - -} tEplEventShort; - -typedef struct { - unsigned int m_uiIndex; - unsigned int m_uiSubIndex; - -} tEplEventObdError; - -// structure for kEplEventTypeError -typedef struct { - tEplEventSource m_EventSource; // module which posted this error event - tEplKernel m_EplError; // EPL error which occured - union { - u8 m_bArg; - u32 m_dwArg; - tEplEventSource m_EventSource; // from Eventk/u module (originating error source) - tEplEventObdError m_ObdError; // from Obd module -// tEplErrHistoryEntry m_HistoryEntry; // from Nmtk/u module - - } m_Arg; - -} tEplEventError; - -// structure for kEplEventTypeDllError -typedef struct { - unsigned long m_ulDllErrorEvents; // EPL_DLL_ERR_* - unsigned int m_uiNodeId; - tEplNmtState m_NmtState; - -} tEplErrorHandlerkEvent; - -// callback function to get informed about sync event -typedef tEplKernel(*tEplSyncCb) (void); - -// callback function for generic events -typedef tEplKernel(*tEplProcessEventCb) (tEplEvent *pEplEvent_p); - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_EVENT_H_ diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c deleted file mode 100644 index ef36815c798..00000000000 --- a/drivers/staging/epl/EplEventk.c +++ /dev/null @@ -1,853 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Epl-Kernelspace-Event-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplEventk.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.9 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 k.t.: start of the implementation - -****************************************************************************/ - -#include "kernel/EplEventk.h" -#include "kernel/EplNmtk.h" -#include "kernel/EplDllk.h" -#include "kernel/EplDllkCal.h" -#include "kernel/EplErrorHandlerk.h" -#include "Benchmark.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -#include "kernel/EplPdok.h" -#include "kernel/EplPdokCal.h" -#endif - -#ifdef EPL_NO_FIFO -#include "user/EplEventu.h" -#else -#include "SharedBuff.h" -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { -#ifndef EPL_NO_FIFO - tShbInstance m_pShbKernelToUserInstance; - tShbInstance m_pShbUserToKernelInstance; -#else - -#endif - tEplSyncCb m_pfnCbSync; - unsigned int m_uiUserToKernelFullCount; - -} tEplEventkInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -static tEplEventkInstance EplEventkInstance_g; -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -// callback function for incoming events -#ifndef EPL_NO_FIFO -static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p); -#endif - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEventkInit -// -// Description: function initializes the first instance -// -// Parameters: pfnCbSync_p = callback-function for sync event -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p) -{ - tEplKernel Ret; - - Ret = EplEventkAddInstance(pfnCbSync_p); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventkAddInstance -// -// Description: function adds one more instance -// -// Parameters: pfnCbSync_p = callback-function for sync event -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; - unsigned int fShbNewCreated; -#endif - - Ret = kEplSuccessful; - - // init instance structure - EplEventkInstance_g.m_uiUserToKernelFullCount = 0; - - // save cb-function - EplEventkInstance_g.m_pfnCbSync = pfnCbSync_p; - -#ifndef EPL_NO_FIFO - // init shared loop buffer - // kernel -> user - ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER, - EPL_EVENT_NAME_SHB_KERNEL_TO_USER, - &EplEventkInstance_g. - m_pShbKernelToUserInstance, - &fShbNewCreated); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - // user -> kernel - ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL, - EPL_EVENT_NAME_SHB_USER_TO_KERNEL, - &EplEventkInstance_g. - m_pShbUserToKernelInstance, - &fShbNewCreated); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - // register eventhandler - ShbError = - ShbCirSetSignalHandlerNewData(EplEventkInstance_g. - m_pShbUserToKernelInstance, - EplEventkRxSignalHandlerCb, - kshbPriorityHigh); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkAddInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - - Exit: -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventkDelInstance -// -// Description: function deletes instance and frees the buffers -// -// Parameters: void -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkDelInstance(void) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; -#endif - - Ret = kEplSuccessful; - -#ifndef EPL_NO_FIFO - // set eventhandler to NULL - ShbError = - ShbCirSetSignalHandlerNewData(EplEventkInstance_g. - m_pShbUserToKernelInstance, NULL, - kShbPriorityNormal); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkDelInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } - // free buffer User -> Kernel - ShbError = - ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbUserToKernelInstance); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } else { - EplEventkInstance_g.m_pShbUserToKernelInstance = NULL; - } - - // free buffer Kernel -> User - ShbError = - ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbKernelToUserInstance); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } else { - EplEventkInstance_g.m_pShbKernelToUserInstance = NULL; - } -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventkProcess -// -// Description: Kernelthread that dispatches events in kernel part -// -// Parameters: pEvent_p = pointer to event-structure from buffer -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkProcess(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - tEplEventSource EventSource; - - Ret = kEplSuccessful; - - // error handling if event queue is full - if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) { // UserToKernel event queue has run out of space -> kEplNmtEventInternComError -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - tEplEvent Event; - tEplNmtEvent NmtEvent; -#endif -#ifndef EPL_NO_FIFO - tShbError ShbError; -#endif - - // directly call NMTk process function, because event queue is full -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - NmtEvent = kEplNmtEventInternComError; - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_NetTime.m_dwNanoSec = 0; - Event.m_NetTime.m_dwSec = 0; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent; - Event.m_uiSize = sizeof(NmtEvent); - Ret = EplNmtkProcess(&Event); -#endif - - // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION) - // now, it is safe to reset the counter and empty the event queue -#ifndef EPL_NO_FIFO - ShbError = - ShbCirResetBuffer(EplEventkInstance_g. - m_pShbUserToKernelInstance, 1000, NULL); -#endif - - EplEventkInstance_g.m_uiUserToKernelFullCount = 0; - TGT_DBG_SIGNAL_TRACE_POINT(22); - - // also discard the current event (it doesn't matter if we lose another event) - goto Exit; - } - // check m_EventSink - switch (pEvent_p->m_EventSink) { - case kEplEventSinkSync: - { - if (EplEventkInstance_g.m_pfnCbSync != NULL) { - Ret = EplEventkInstance_g.m_pfnCbSync(); - if (Ret == kEplSuccessful) { -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - // mark TPDOs as valid - Ret = EplPdokCalSetTpdosValid(TRUE); -#endif - } else if ((Ret != kEplReject) - && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceSyncCb; - - // Error event for API layer - EplEventkPostError - (kEplEventSourceEventk, Ret, - sizeof(EventSource), &EventSource); - } - } - break; - } - - // NMT-Kernel-Modul - case kEplEventSinkNmtk: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - Ret = EplNmtkProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceNmtk; - - // Error event for API layer - EplEventkPostError(kEplEventSourceEventk, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent) - && - ((*((tEplNmtEvent *) pEvent_p->m_pArg) == - kEplNmtEventDllCeSoa) -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - || (*((tEplNmtEvent *) pEvent_p->m_pArg) == - kEplNmtEventDllMeSoaSent) -#endif - )) { // forward SoA event to error handler - Ret = EplErrorHandlerkProcess(pEvent_p); - if ((Ret != kEplSuccessful) - && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceErrk; - - // Error event for API layer - EplEventkPostError - (kEplEventSourceEventk, Ret, - sizeof(EventSource), &EventSource); - } -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - // forward SoA event to PDO module - pEvent_p->m_EventType = kEplEventTypePdoSoa; - Ret = EplPdokProcess(pEvent_p); - if ((Ret != kEplSuccessful) - && (Ret != kEplShutdown)) { - EventSource = kEplEventSourcePdok; - - // Error event for API layer - EplEventkPostError - (kEplEventSourceEventk, Ret, - sizeof(EventSource), &EventSource); - } -#endif - - } - break; -#endif - } - - // events for Dllk module - case kEplEventSinkDllk: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceDllk; - - // Error event for API layer - EplEventkPostError(kEplEventSourceEventk, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif - break; - } - - // events for DllkCal module - case kEplEventSinkDllkCal: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkCalProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceDllk; - - // Error event for API layer - EplEventkPostError(kEplEventSourceEventk, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif - break; - } - - // - case kEplEventSinkPdok: - { - // PDO-Module -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - Ret = EplPdokProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourcePdok; - - // Error event for API layer - EplEventkPostError(kEplEventSourceEventk, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif - break; - } - - // events for Error handler module - case kEplEventSinkErrk: - { - // only call error handler if DLL is present -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplErrorHandlerkProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceErrk; - - // Error event for API layer - EplEventkPostError(kEplEventSourceEventk, - Ret, - sizeof(EventSource), - &EventSource); - } - break; -#endif - } - - // unknown sink - default: - { - Ret = kEplEventUnknownSink; - } - - } // end of switch(pEvent_p->m_EventSink) - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventkPost -// -// Description: post events from kernel part -// -// Parameters: pEvent_p = pointer to event-structure from buffer -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkPost(tEplEvent *pEvent_p) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; - tShbCirChunk ShbCirChunk; - unsigned long ulDataSize; - unsigned int fBufferCompleted; -#endif - - Ret = kEplSuccessful; - - // the event must be posted by using the abBuffer - // it is neede because the Argument must by copied - // to the buffer too and not only the pointer - -#ifndef EPL_NO_FIFO - // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue. - ulDataSize = - sizeof(tEplEvent) + - ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0); -#endif - - // decide in which buffer the event have to write - switch (pEvent_p->m_EventSink) { - // kernelspace modules - case kEplEventSinkSync: - case kEplEventSinkNmtk: - case kEplEventSinkDllk: - case kEplEventSinkDllkCal: - case kEplEventSinkPdok: - case kEplEventSinkErrk: - { -#ifndef EPL_NO_FIFO - // post message - BENCHMARK_MOD_27_SET(2); - ShbError = - ShbCirAllocDataBlock(EplEventkInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, ulDataSize); - switch (ShbError) { - case kShbOk: - break; - - case kShbBufferFull: - { - EplEventkInstance_g. - m_uiUserToKernelFullCount++; - Ret = kEplEventPostError; - goto Exit; - } - - default: - { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - } - ShbError = - ShbCirWriteDataChunk(EplEventkInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, pEvent_p, - sizeof(tEplEvent), - &fBufferCompleted); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - if (fBufferCompleted == FALSE) { - ShbError = - ShbCirWriteDataChunk(EplEventkInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, - pEvent_p->m_pArg, - (unsigned long) - pEvent_p->m_uiSize, - &fBufferCompleted); - if ((ShbError != kShbOk) - || (fBufferCompleted == FALSE)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - } - BENCHMARK_MOD_27_RESET(2); - -#else - Ret = EplEventkProcess(pEvent_p); -#endif - - break; - } - - // userspace modules - case kEplEventSinkNmtu: - case kEplEventSinkNmtMnu: - case kEplEventSinkSdoAsySeq: - case kEplEventSinkApi: - case kEplEventSinkDlluCal: - case kEplEventSinkErru: - { -#ifndef EPL_NO_FIFO - // post message -// BENCHMARK_MOD_27_SET(3); // 74 µs until reset - ShbError = - ShbCirAllocDataBlock(EplEventkInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, ulDataSize); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - ShbError = - ShbCirWriteDataChunk(EplEventkInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, pEvent_p, - sizeof(tEplEvent), - &fBufferCompleted); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - if (fBufferCompleted == FALSE) { - ShbError = - ShbCirWriteDataChunk(EplEventkInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, - pEvent_p->m_pArg, - (unsigned long) - pEvent_p->m_uiSize, - &fBufferCompleted); - if ((ShbError != kShbOk) - || (fBufferCompleted == FALSE)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventkPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - } -// BENCHMARK_MOD_27_RESET(3); // 82 µs until ShbCirGetReadDataSize() in EplEventu - -#else - Ret = EplEventuProcess(pEvent_p); -#endif - - break; - } - - default: - { - Ret = kEplEventUnknownSink; - } - - } // end of switch(pEvent_p->m_EventSink) - -#ifndef EPL_NO_FIFO - Exit: -#endif - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventkPostError -// -// Description: post error event from kernel part to API layer -// -// Parameters: EventSource_p = source-module of the error event -// EplError_p = code of occured error -// ArgSize_p = size of the argument -// pArg_p = pointer to the argument -// -// Returns: tEpKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplEventkPostError(tEplEventSource EventSource_p, - tEplKernel EplError_p, - unsigned int uiArgSize_p, void *pArg_p) -{ - tEplKernel Ret; - u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE]; - tEplEventError *pEventError = (tEplEventError *) abBuffer; - tEplEvent EplEvent; - - Ret = kEplSuccessful; - - // create argument - pEventError->m_EventSource = EventSource_p; - pEventError->m_EplError = EplError_p; - EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p); - - // create event - EplEvent.m_EventType = kEplEventTypeError; - EplEvent.m_EventSink = kEplEventSinkApi; - EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime)); - EplEvent.m_uiSize = - (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p); - EplEvent.m_pArg = &abBuffer[0]; - - // post errorevent - Ret = EplEventkPost(&EplEvent); - - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEventkRxSignalHandlerCb() -// -// Description: Callback-function for events from user and kernel part -// -// Parameters: pShbRxInstance_p = Instance-pointer of buffer -// ulDataSize_p = size of data -// -// Returns: void -// -// State: -// -//--------------------------------------------------------------------------- - -#ifndef EPL_NO_FIFO -static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p) -{ - tEplEvent *pEplEvent; - tShbError ShbError; -//unsigned long ulBlockCount; -//unsigned long ulDataSize; - u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE]; - // d.k.: abDataBuffer contains the complete tEplEvent structure - // and behind this the argument - - TGT_DBG_SIGNAL_TRACE_POINT(20); - - BENCHMARK_MOD_27_RESET(0); - // copy data from event queue - ShbError = ShbCirReadDataBlock(pShbRxInstance_p, - &abDataBuffer[0], - sizeof(abDataBuffer), &ulDataSize_p); - if (ShbError != kShbOk) { - // error goto exit - goto Exit; - } - // resolve the pointer to the event structure - pEplEvent = (tEplEvent *) abDataBuffer; - // set Datasize - pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent)); - if (pEplEvent->m_uiSize > 0) { - // set pointer to argument - pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)]; - } else { - //set pointer to NULL - pEplEvent->m_pArg = NULL; - } - - BENCHMARK_MOD_27_SET(0); - // call processfunction - EplEventkProcess(pEplEvent); - - Exit: - return; -} -#endif - -// EOF diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c deleted file mode 100644 index 3ae2841ad02..00000000000 --- a/drivers/staging/epl/EplEventu.c +++ /dev/null @@ -1,813 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Epl-Userspace-Event-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplEventu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplEventu.h" -#include "user/EplNmtu.h" -#include "user/EplNmtMnu.h" -#include "user/EplSdoAsySequ.h" -#include "user/EplDlluCal.h" -#include "user/EplLedu.h" -#include "Benchmark.h" - -#ifdef EPL_NO_FIFO -#include "kernel/EplEventk.h" -#else -#include "SharedBuff.h" -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { -#ifndef EPL_NO_FIFO - tShbInstance m_pShbKernelToUserInstance; - tShbInstance m_pShbUserToKernelInstance; -#endif - tEplProcessEventCb m_pfnApiProcessEventCb; - -} tEplEventuInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//#ifndef EPL_NO_FIFO -static tEplEventuInstance EplEventuInstance_g; -//#endif - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -#ifndef EPL_NO_FIFO -// callback function for incomming events -static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p); -#endif - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEventuInit -// -// Description: function initialize the first instance -// -// -// -// Parameters: pfnApiProcessEventCb_p = function pointer for API event callback -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p) -{ - tEplKernel Ret; - - Ret = EplEventuAddInstance(pfnApiProcessEventCb_p); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventuAddInstance -// -// Description: function add one more instance -// -// -// -// Parameters: pfnApiProcessEventCb_p = function pointer for API event callback -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; - unsigned int fShbNewCreated; -#endif - - Ret = kEplSuccessful; - - // init instance variables - EplEventuInstance_g.m_pfnApiProcessEventCb = pfnApiProcessEventCb_p; - -#ifndef EPL_NO_FIFO - // init shared loop buffer - // kernel -> user - ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER, - EPL_EVENT_NAME_SHB_KERNEL_TO_USER, - &EplEventuInstance_g. - m_pShbKernelToUserInstance, - &fShbNewCreated); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - - // user -> kernel - ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL, - EPL_EVENT_NAME_SHB_USER_TO_KERNEL, - &EplEventuInstance_g. - m_pShbUserToKernelInstance, - &fShbNewCreated); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - // register eventhandler - ShbError = - ShbCirSetSignalHandlerNewData(EplEventuInstance_g. - m_pShbKernelToUserInstance, - EplEventuRxSignalHandlerCb, - kShbPriorityNormal); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuAddInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - goto Exit; - } - - Exit: -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventuDelInstance -// -// Description: function delete instance an free the bufferstructure -// -// -// -// Parameters: -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuDelInstance(void) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; -#endif - - Ret = kEplSuccessful; - -#ifndef EPL_NO_FIFO - // set eventhandler to NULL - ShbError = - ShbCirSetSignalHandlerNewData(EplEventuInstance_g. - m_pShbKernelToUserInstance, NULL, - kShbPriorityNormal); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuDelInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } - // free buffer User -> Kernel - ShbError = - ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbUserToKernelInstance); - if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } else { - EplEventuInstance_g.m_pShbUserToKernelInstance = NULL; - } - - // free buffer Kernel -> User - ShbError = - ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbKernelToUserInstance); - if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n", - ShbError); - Ret = kEplNoResource; - } else { - EplEventuInstance_g.m_pShbKernelToUserInstance = NULL; - } - -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventuProcess -// -// Description: Kernelthread that dispatches events in kernelspace -// -// -// -// Parameters: pEvent_p = pointer to event-structur from buffer -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuProcess(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - tEplEventSource EventSource; - - Ret = kEplSuccessful; - - // check m_EventSink - switch (pEvent_p->m_EventSink) { - // NMT-User-Module - case kEplEventSinkNmtu: - { -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = EplNmtuProcessEvent(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceNmtu; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif - break; - } - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // NMT-MN-User-Module - case kEplEventSinkNmtMnu: - { - Ret = EplNmtMnuProcessEvent(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceNmtMnu; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } - break; - } -#endif - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) \ - || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)) - // events for asynchronus SDO Sequence Layer - case kEplEventSinkSdoAsySeq: - { - Ret = EplSdoAsySeqProcessEvent(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceSdoAsySeq; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } - break; - } -#endif - - // LED user part module - case kEplEventSinkLedu: - { -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - Ret = EplLeduProcessEvent(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceLedu; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } -#endif - break; - } - - // event for EPL api - case kEplEventSinkApi: - { - if (EplEventuInstance_g.m_pfnApiProcessEventCb != NULL) { - Ret = - EplEventuInstance_g. - m_pfnApiProcessEventCb(pEvent_p); - if ((Ret != kEplSuccessful) - && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceEplApi; - - // Error event for API layer - EplEventuPostError - (kEplEventSourceEventu, Ret, - sizeof(EventSource), &EventSource); - } - } - break; - - } - - case kEplEventSinkDlluCal: - { - Ret = EplDlluCalProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) { - EventSource = kEplEventSourceDllu; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } - break; - - } - - case kEplEventSinkErru: - { - /* - Ret = EplErruProcess(pEvent_p); - if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) - { - EventSource = kEplEventSourceErru; - - // Error event for API layer - EplEventuPostError(kEplEventSourceEventu, - Ret, - sizeof(EventSource), - &EventSource); - } - */ - break; - - } - - // unknown sink - default: - { - Ret = kEplEventUnknownSink; - } - - } // end of switch(pEvent_p->m_EventSink) - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventuPost -// -// Description: post events from userspace -// -// -// -// Parameters: pEvent_p = pointer to event-structur from buffer -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuPost(tEplEvent *pEvent_p) -{ - tEplKernel Ret; -#ifndef EPL_NO_FIFO - tShbError ShbError; - tShbCirChunk ShbCirChunk; - unsigned long ulDataSize; - unsigned int fBufferCompleted; -#endif - - Ret = kEplSuccessful; - -#ifndef EPL_NO_FIFO - // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue. - ulDataSize = - sizeof(tEplEvent) + - ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0); -#endif - - // decide in which buffer the event have to write - switch (pEvent_p->m_EventSink) { - // kernelspace modules - case kEplEventSinkSync: - case kEplEventSinkNmtk: - case kEplEventSinkDllk: - case kEplEventSinkDllkCal: - case kEplEventSinkPdok: - case kEplEventSinkErrk: - { -#ifndef EPL_NO_FIFO - // post message - ShbError = - ShbCirAllocDataBlock(EplEventuInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, ulDataSize); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - ShbError = - ShbCirWriteDataChunk(EplEventuInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, pEvent_p, - sizeof(tEplEvent), - &fBufferCompleted); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - if (fBufferCompleted == FALSE) { - ShbError = - ShbCirWriteDataChunk(EplEventuInstance_g. - m_pShbUserToKernelInstance, - &ShbCirChunk, - pEvent_p->m_pArg, - (unsigned long) - pEvent_p->m_uiSize, - &fBufferCompleted); - if ((ShbError != kShbOk) - || (fBufferCompleted == FALSE)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - } -#else - Ret = EplEventkProcess(pEvent_p); -#endif - - break; - } - - // userspace modules - case kEplEventSinkNmtMnu: - case kEplEventSinkNmtu: - case kEplEventSinkSdoAsySeq: - case kEplEventSinkApi: - case kEplEventSinkDlluCal: - case kEplEventSinkErru: - case kEplEventSinkLedu: - { -#ifndef EPL_NO_FIFO - // post message - ShbError = - ShbCirAllocDataBlock(EplEventuInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, ulDataSize); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - ShbError = - ShbCirWriteDataChunk(EplEventuInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, pEvent_p, - sizeof(tEplEvent), - &fBufferCompleted); - if (ShbError != kShbOk) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - if (fBufferCompleted == FALSE) { - ShbError = - ShbCirWriteDataChunk(EplEventuInstance_g. - m_pShbKernelToUserInstance, - &ShbCirChunk, - pEvent_p->m_pArg, - (unsigned long) - pEvent_p->m_uiSize, - &fBufferCompleted); - if ((ShbError != kShbOk) - || (fBufferCompleted == FALSE)) { - EPL_DBGLVL_EVENTK_TRACE1 - ("EplEventuPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n", - ShbError); - Ret = kEplEventPostError; - goto Exit; - } - } -#else - Ret = EplEventuProcess(pEvent_p); -#endif - - break; - } - - default: - { - Ret = kEplEventUnknownSink; - } - - } // end of switch(pEvent_p->m_EventSink) - -#ifndef EPL_NO_FIFO - Exit: -#endif - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplEventuPostError -// -// Description: post errorevent from userspace -// -// -// -// Parameters: EventSource_p = source-module of the errorevent -// EplError_p = code of occured error -// uiArgSize_p = size of the argument -// pArg_p = pointer to the argument -// -// -// Returns: tEpKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplEventuPostError(tEplEventSource EventSource_p, - tEplKernel EplError_p, - unsigned int uiArgSize_p, void *pArg_p) -{ - tEplKernel Ret; - u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE]; - tEplEventError *pEventError = (tEplEventError *) abBuffer; - tEplEvent EplEvent; - - Ret = kEplSuccessful; - - // create argument - pEventError->m_EventSource = EventSource_p; - pEventError->m_EplError = EplError_p; - EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p); - - // create event - EplEvent.m_EventType = kEplEventTypeError; - EplEvent.m_EventSink = kEplEventSinkApi; - EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime)); - EplEvent.m_uiSize = - (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p); - EplEvent.m_pArg = &abBuffer[0]; - - // post errorevent - Ret = EplEventuPost(&EplEvent); - - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEventuRxSignalHandlerCb() -// -// Description: Callback-function for evets from kernelspace -// -// -// -// Parameters: pShbRxInstance_p = Instance-pointer for buffer -// ulDataSize_p = size of data -// -// -// Returns: void -// -// -// State: -// -//--------------------------------------------------------------------------- -#ifndef EPL_NO_FIFO -static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p, - unsigned long ulDataSize_p) -{ - tEplEvent *pEplEvent; - tShbError ShbError; -//unsigned long ulBlockCount; -//unsigned long ulDataSize; - u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE]; - // d.k.: abDataBuffer contains the complete tEplEvent structure - // and behind this the argument - - TGT_DBG_SIGNAL_TRACE_POINT(21); - -// d.k. not needed because it is already done in SharedBuff -/* do - { - BENCHMARK_MOD_28_SET(1); // 4 µs until reset - // get messagesize - ShbError = ShbCirGetReadDataSize (pShbRxInstance_p, &ulDataSize); - if(ShbError != kShbOk) - { - // error goto exit - goto Exit; - } - - BENCHMARK_MOD_28_RESET(1); // 14 µs until set -*/ - // copy data from event queue - ShbError = ShbCirReadDataBlock(pShbRxInstance_p, - &abDataBuffer[0], - sizeof(abDataBuffer), &ulDataSize_p); - if (ShbError != kShbOk) { - // error goto exit - goto Exit; - } - // resolve the pointer to the event structure - pEplEvent = (tEplEvent *) abDataBuffer; - // set Datasize - pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent)); - if (pEplEvent->m_uiSize > 0) { - // set pointer to argument - pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)]; - } else { - //set pointer to NULL - pEplEvent->m_pArg = NULL; - } - - BENCHMARK_MOD_28_SET(1); - // call processfunction - EplEventuProcess(pEplEvent); - - BENCHMARK_MOD_28_RESET(1); - // read number of left messages to process -// d.k. not needed because it is already done in SharedBuff -/* ShbError = ShbCirGetReadBlockCount (pShbRxInstance_p, &ulBlockCount); - if (ShbError != kShbOk) - { - // error goto exit - goto Exit; - } - } while (ulBlockCount > 0); -*/ - Exit: - return; -} -#endif - -// EOF diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h deleted file mode 100644 index ba1ae9e9e90..00000000000 --- a/drivers/staging/epl/EplFrame.h +++ /dev/null @@ -1,344 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL frames - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplFrame.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/06/23 14:56:33 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_FRAME_H_ -#define _EPL_FRAME_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// defines for EplFrame.m_wFlag -#define EPL_FRAME_FLAG1_RD 0x01 // ready (PReq, PRes) -#define EPL_FRAME_FLAG1_ER 0x02 // exception reset (error signalling) (SoA) -#define EPL_FRAME_FLAG1_EA 0x04 // exception acknowledge (error signalling) (PReq, SoA) -#define EPL_FRAME_FLAG1_EC 0x08 // exception clear (error signalling) (StatusRes) -#define EPL_FRAME_FLAG1_EN 0x10 // exception new (error signalling) (PRes, StatusRes) -#define EPL_FRAME_FLAG1_MS 0x20 // multiplexed slot (PReq) -#define EPL_FRAME_FLAG1_PS 0x40 // prescaled slot (SoC) -#define EPL_FRAME_FLAG1_MC 0x80 // multiplexed cycle completed (SoC) -#define EPL_FRAME_FLAG2_RS 0x07 // number of pending requests to send (PRes, StatusRes, IdentRes) -#define EPL_FRAME_FLAG2_PR 0x38 // priority of requested asynch. frame (PRes, StatusRes, IdentRes) -#define EPL_FRAME_FLAG2_PR_SHIFT 3 // shift of priority of requested asynch. frame - -// error history/status entry types -#define EPL_ERR_ENTRYTYPE_STATUS 0x8000 -#define EPL_ERR_ENTRYTYPE_HISTORY 0x0000 -#define EPL_ERR_ENTRYTYPE_EMCY 0x4000 -#define EPL_ERR_ENTRYTYPE_MODE_ACTIVE 0x1000 -#define EPL_ERR_ENTRYTYPE_MODE_CLEARED 0x2000 -#define EPL_ERR_ENTRYTYPE_MODE_OCCURRED 0x3000 -#define EPL_ERR_ENTRYTYPE_MODE_MASK 0x3000 -#define EPL_ERR_ENTRYTYPE_PROF_VENDOR 0x0001 -#define EPL_ERR_ENTRYTYPE_PROF_EPL 0x0002 -#define EPL_ERR_ENTRYTYPE_PROF_MASK 0x0FFF - -// defines for EPL version / PDO version -#define EPL_VERSION_SUB 0x0F // sub version -#define EPL_VERSION_MAIN 0xF0 // main version - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -// $$$ d.k.: move this definition to global.h -// byte-align structures -#ifdef _MSC_VER -# pragma pack( push, packing ) -# pragma pack( 1 ) -# define PACK_STRUCT -#elif defined( __GNUC__ ) -# define PACK_STRUCT __attribute__((packed)) -#else -# error you must byte-align these structures with the appropriate compiler directives -#endif - -typedef struct { - // Offset 17 - u8 m_le_bRes1; // reserved - // Offset 18 - u8 m_le_bFlag1; // Flags: MC, PS - // Offset 19 - u8 m_le_bFlag2; // Flags: res - // Offset 20 - tEplNetTime m_le_NetTime; // supported if D_NMT_NetTimeIsRealTime_BOOL is set - // Offset 28 - u64 m_le_RelativeTime; // in us (supported if D_NMT_RelativeTime_BOOL is set) - -} PACK_STRUCT tEplSocFrame; - -typedef struct { - // Offset 17 - u8 m_le_bRes1; // reserved - // Offset 18 - u8 m_le_bFlag1; // Flags: MS, EA, RD - // Offset 19 - u8 m_le_bFlag2; // Flags: res - // Offset 20 - u8 m_le_bPdoVersion; - // Offset 21 - u8 m_le_bRes2; // reserved - // Offset 22 - u16 m_le_wSize; - // Offset 24 - u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ]; - -} PACK_STRUCT tEplPreqFrame; - -typedef struct { - // Offset 17 - u8 m_le_bNmtStatus; // NMT state - // Offset 18 - u8 m_le_bFlag1; // Flags: MS, EN, RD - // Offset 19 - u8 m_le_bFlag2; // Flags: PR, RS - // Offset 20 - u8 m_le_bPdoVersion; - // Offset 21 - u8 m_le_bRes2; // reserved - // Offset 22 - u16 m_le_wSize; - // Offset 24 - u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 - / D_NMT_IsochrTxMaxPayload_U16 */ ]; - -} PACK_STRUCT tEplPresFrame; - -typedef struct { - // Offset 17 - u8 m_le_bNmtStatus; // NMT state - // Offset 18 - u8 m_le_bFlag1; // Flags: EA, ER - // Offset 19 - u8 m_le_bFlag2; // Flags: res - // Offset 20 - u8 m_le_bReqServiceId; - // Offset 21 - u8 m_le_bReqServiceTarget; - // Offset 22 - u8 m_le_bEplVersion; - -} PACK_STRUCT tEplSoaFrame; - -typedef struct { - u16 m_wEntryType; - u16 m_wErrorCode; - tEplNetTime m_TimeStamp; - u8 m_abAddInfo[8]; - -} PACK_STRUCT tEplErrHistoryEntry; - -typedef struct { - // Offset 18 - u8 m_le_bFlag1; // Flags: EN, EC - u8 m_le_bFlag2; // Flags: PR, RS - u8 m_le_bNmtStatus; // NMT state - u8 m_le_bRes1[3]; - u64 m_le_qwStaticError; // static error bit field - tEplErrHistoryEntry m_le_aErrHistoryEntry[14]; - -} PACK_STRUCT tEplStatusResponse; - -typedef struct { - // Offset 18 - u8 m_le_bFlag1; // Flags: res - u8 m_le_bFlag2; // Flags: PR, RS - u8 m_le_bNmtStatus; // NMT state - u8 m_le_bIdentRespFlags; // Flags: FW - u8 m_le_bEplProfileVersion; - u8 m_le_bRes1; - u32 m_le_dwFeatureFlags; // NMT_FeatureFlags_U32 - u16 m_le_wMtu; // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU - u16 m_le_wPollInSize; // NMT_CycleTiming_REC.PReqActPayload_U16 - u16 m_le_wPollOutSize; // NMT_CycleTiming_REC.PResActPayload_U16 - u32 m_le_dwResponseTime; // NMT_CycleTiming_REC.PResMaxLatency_U32 - u16 m_le_wRes2; - u32 m_le_dwDeviceType; // NMT_DeviceType_U32 - u32 m_le_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32 - u32 m_le_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32 - u32 m_le_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32 - u32 m_le_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32 - u64 m_le_qwVendorSpecificExt1; - u32 m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32 - u32 m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32 - u32 m_le_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_le_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device - u32 m_le_dwIpAddress; - u32 m_le_dwSubnetMask; - u32 m_le_dwDefaultGateway; - u8 m_le_sHostname[32]; - u8 m_le_abVendorSpecificExt2[48]; - -} PACK_STRUCT tEplIdentResponse; - -typedef struct { - // Offset 18 - u8 m_le_bNmtCommandId; - u8 m_le_bRes1; - u8 m_le_abNmtCommandData[32]; - -} PACK_STRUCT tEplNmtCommandService; - -typedef struct { - u8 m_le_bReserved; - u8 m_le_bTransactionId; - u8 m_le_bFlags; - u8 m_le_bCommandId; - u16 m_le_wSegmentSize; - u16 m_le_wReserved; - u8 m_le_abCommandData[8]; // just reserve a minimum number of bytes as a placeholder - -} PACK_STRUCT tEplAsySdoCom; - -// asynchronous SDO Sequence Header -typedef struct { - u8 m_le_bRecSeqNumCon; - u8 m_le_bSendSeqNumCon; - u8 m_le_abReserved[2]; - tEplAsySdoCom m_le_abSdoSeqPayload; - -} PACK_STRUCT tEplAsySdoSeq; - -typedef struct { - // Offset 18 - u8 m_le_bNmtCommandId; - u8 m_le_bTargetNodeId; - u8 m_le_abNmtCommandData[32]; - -} PACK_STRUCT tEplNmtRequestService; - -typedef union { - // Offset 18 - tEplStatusResponse m_StatusResponse; - tEplIdentResponse m_IdentResponse; - tEplNmtCommandService m_NmtCommandService; - tEplNmtRequestService m_NmtRequestService; - tEplAsySdoSeq m_SdoSequenceFrame; - u8 m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16 - / D_NMT_ASndRxMaxPayload_U16 */ ]; - -} tEplAsndPayload; - -typedef struct { - // Offset 17 - u8 m_le_bServiceId; - // Offset 18 - tEplAsndPayload m_Payload; - -} PACK_STRUCT tEplAsndFrame; - -typedef union { - // Offset 17 - tEplSocFrame m_Soc; - tEplPreqFrame m_Preq; - tEplPresFrame m_Pres; - tEplSoaFrame m_Soa; - tEplAsndFrame m_Asnd; - -} tEplFrameData; - -typedef struct { - // Offset 0 - u8 m_be_abDstMac[6]; // MAC address of the addressed nodes - // Offset 6 - u8 m_be_abSrcMac[6]; // MAC address of the transmitting node - // Offset 12 - u16 m_be_wEtherType; // Ethernet message type (big endian) - // Offset 14 - u8 m_le_bMessageType; // EPL message type - // Offset 15 - u8 m_le_bDstNodeId; // EPL node ID of the addressed nodes - // Offset 16 - u8 m_le_bSrcNodeId; // EPL node ID of the transmitting node - // Offset 17 - tEplFrameData m_Data; - -} PACK_STRUCT tEplFrame; - -// un-byte-align structures -#ifdef _MSC_VER -# pragma pack( pop, packing ) -#endif - -typedef enum { - kEplMsgTypeNonEpl = 0x00, - kEplMsgTypeSoc = 0x01, - kEplMsgTypePreq = 0x03, - kEplMsgTypePres = 0x04, - kEplMsgTypeSoa = 0x05, - kEplMsgTypeAsnd = 0x06, - -} tEplMsgType; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_FRAME_H_ diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c deleted file mode 100644 index 93d5a40a2f7..00000000000 --- a/drivers/staging/epl/EplIdentu.c +++ /dev/null @@ -1,486 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Identu-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplIdentu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/21 09:00:38 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/11/15 d.k.: start of the implementation - -****************************************************************************/ - -#include "user/EplIdentu.h" -#include "user/EplDlluCal.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - tEplIdentResponse *m_apIdentResponse[254]; // the IdentResponse are managed dynamically - tEplIdentuCbResponse m_apfnCbResponse[254]; - -} tEplIdentuInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplIdentuInstance EplIdentuInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuInit -// -// Description: init first instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuInit(void) -{ - tEplKernel Ret; - - Ret = EplIdentuAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuAddInstance -// -// Description: init other instances of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof(EplIdentuInstance_g)); - - // register IdentResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndIdentResponse, - EplIdentuCbIdentResponse, - kEplDllAsndFilterAny); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuDelInstance -// -// Description: delete instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // deregister IdentResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndIdentResponse, NULL, - kEplDllAsndFilterNone); - - Ret = EplIdentuReset(); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuReset -// -// Description: resets this instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuReset(void) -{ - tEplKernel Ret; - int iIndex; - - Ret = kEplSuccessful; - - for (iIndex = 0; - iIndex < tabentries(EplIdentuInstance_g.m_apIdentResponse); - iIndex++) { - if (EplIdentuInstance_g.m_apIdentResponse[iIndex] != NULL) { // free memory - EPL_FREE(EplIdentuInstance_g.m_apIdentResponse[iIndex]); - } - } - - EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof(EplIdentuInstance_g)); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuGetIdentResponse -// -// Description: returns the IdentResponse for the specified node. -// -// Parameters: uiNodeId_p = IN: node ID -// ppIdentResponse_p = OUT: pointer to pointer of IdentResponse -// equals NULL, if no IdentResponse available -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p, - tEplIdentResponse **ppIdentResponse_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // decrement node ID, because array is zero based - uiNodeId_p--; - if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apIdentResponse)) { - *ppIdentResponse_p = - EplIdentuInstance_g.m_apIdentResponse[uiNodeId_p]; - } else { // invalid node ID specified - *ppIdentResponse_p = NULL; - Ret = kEplInvalidNodeId; - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuRequestIdentResponse -// -// Description: returns the IdentResponse for the specified node. -// -// Parameters: uiNodeId_p = IN: node ID -// pfnCbResponse_p = IN: function pointer to callback function -// which will be called if IdentResponse is received -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p, - tEplIdentuCbResponse pfnCbResponse_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // decrement node ID, because array is zero based - uiNodeId_p--; - if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL) { // request already issued (maybe by someone else) - Ret = kEplInvalidOperation; - } else { - EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] = - pfnCbResponse_p; - Ret = - EplDlluCalIssueRequest(kEplDllReqServiceIdent, - (uiNodeId_p + 1), 0xFF); - } -#else - Ret = kEplInvalidOperation; -#endif - } else { // invalid node ID specified - Ret = kEplInvalidNodeId; - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuGetRunningRequests -// -// Description: returns a bit field with the running requests for node-ID 1-32 -// just for debugging purposes -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -u32 EplIdentuGetRunningRequests(void) -{ - u32 dwReqs = 0; - unsigned int uiIndex; - - for (uiIndex = 0; uiIndex < 32; uiIndex++) { - if (EplIdentuInstance_g.m_apfnCbResponse[uiIndex] != NULL) { - dwReqs |= (1 << uiIndex); - } - } - - return dwReqs; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplIdentuCbIdentResponse -// -// Description: callback funktion for IdentResponse -// -// -// -// Parameters: pFrameInfo_p = Frame with the IdentResponse -// -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiNodeId; - unsigned int uiIndex; - tEplIdentuCbResponse pfnCbResponse; - - uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId); - - uiIndex = uiNodeId - 1; - - if (uiIndex < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) { - // memorize pointer to callback function - pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex]; - // reset callback function pointer so that caller may issue next request immediately - EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL; - - if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES) { // IdentResponse not received or it has invalid size - if (pfnCbResponse == NULL) { // response was not requested - goto Exit; - } - Ret = pfnCbResponse(uiNodeId, NULL); - } else { // IdentResponse received - if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) { // memory for IdentResponse must be allocated - EplIdentuInstance_g.m_apIdentResponse[uiIndex] = - EPL_MALLOC(sizeof(tEplIdentResponse)); - if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) { // malloc failed - if (pfnCbResponse == NULL) { // response was not requested - goto Exit; - } - Ret = - pfnCbResponse(uiNodeId, - &pFrameInfo_p-> - m_pFrame->m_Data. - m_Asnd.m_Payload. - m_IdentResponse); - goto Exit; - } - } - // copy IdentResponse to instance structure - EPL_MEMCPY(EplIdentuInstance_g. - m_apIdentResponse[uiIndex], - &pFrameInfo_p->m_pFrame->m_Data.m_Asnd. - m_Payload.m_IdentResponse, - sizeof(tEplIdentResponse)); - if (pfnCbResponse == NULL) { // response was not requested - goto Exit; - } - Ret = - pfnCbResponse(uiNodeId, - EplIdentuInstance_g. - m_apIdentResponse[uiIndex]); - } - } - - Exit: - return Ret; -} - -// EOF diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h deleted file mode 100644 index f91797a3687..00000000000 --- a/drivers/staging/epl/EplInc.h +++ /dev/null @@ -1,370 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: basic include file for internal EPL stack modules - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplInc.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_INC_H_ -#define _EPL_INC_H_ - -// ============================================================================ -// include files -// ============================================================================ -#if defined(WIN32) || defined(_WIN32) - -#ifdef UNDER_RTSS - // RTX header -#include -#include -#include - -#elif __BORLANDC__ - // borland C header -#include -#include - -#elif WINCE -#include - -#else - // MSVC needs to include windows.h at first - // the following defines ar necessary for function prototypes for waitable timers -#define _WIN32_WINDOWS 0x0401 -#define _WIN32_WINNT 0x0400 -#include -#include -#endif - -#endif - -// defines for module integration -// possible other include file needed -// These constants defines modules which can be included in the Epl application. -// Use this constants for define EPL_MODULE_INTEGRATION in file EplCfg.h. -#define EPL_MODULE_OBDK 0x00000001L // OBD kernel part module -#define EPL_MODULE_PDOK 0x00000002L // PDO kernel part module -#define EPL_MODULE_NMT_MN 0x00000004L // NMT MN module -#define EPL_MODULE_SDOS 0x00000008L // SDO Server module -#define EPL_MODULE_SDOC 0x00000010L // SDO Client module -#define EPL_MODULE_SDO_ASND 0x00000020L // SDO over Asnd module -#define EPL_MODULE_SDO_UDP 0x00000040L // SDO over UDP module -#define EPL_MODULE_SDO_PDO 0x00000080L // SDO in PDO module -#define EPL_MODULE_NMT_CN 0x00000100L // NMT CN module -#define EPL_MODULE_NMTU 0x00000200L // NMT user part module -#define EPL_MODULE_NMTK 0x00000400L // NMT kernel part module -#define EPL_MODULE_DLLK 0x00000800L // DLL kernel part module -#define EPL_MODULE_DLLU 0x00001000L // DLL user part module -#define EPL_MODULE_OBDU 0x00002000L // OBD user part module -#define EPL_MODULE_CFGMA 0x00004000L // Configuartioan Manager module -#define EPL_MODULE_VETH 0x00008000L // virtual ethernet driver module -#define EPL_MODULE_PDOU 0x00010000L // PDO user part module -#define EPL_MODULE_LEDU 0x00020000L // LED user part module - -#include "EplCfg.h" // EPL configuration file (configuration from application) - -#include "global.h" // global definitions - -#include "EplDef.h" // EPL configuration file (default configuration) -#include "EplInstDef.h" // defines macros for instance types and table -#include "Debug.h" // debug definitions - -#include "EplErrDef.h" // EPL error codes for API funtions - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -// IEEE 1588 conformant net time structure -typedef struct { - u32 m_dwSec; - u32 m_dwNanoSec; - -} tEplNetTime; - -#include "EplTarget.h" // target specific functions and definitions - -#include "EplAmi.h" - -// ------------------------------------------------------------------------- -// macros -// ------------------------------------------------------------------------- - -#define EPL_SPEC_VERSION 0x20 // ETHERNET Powerlink V. 2.0 -#define EPL_STACK_VERSION(ver,rev,rel) ((((u32)(ver)) & 0xFF)|((((u32)(rev))&0xFF)<<8)|(((u32)(rel))<<16)) -#define EPL_OBJ1018_VERSION(ver,rev,rel) ((((u32)(ver))<<16) |(((u32)(rev))&0xFFFF)) -#define EPL_STRING_VERSION(ver,rev,rel) "V" #ver "." #rev " r" #rel - -#include "EplVersion.h" - -// defines for EPL FeatureFlags -#define EPL_FEATURE_ISOCHR 0x00000001 -#define EPL_FEATURE_SDO_UDP 0x00000002 -#define EPL_FEATURE_SDO_ASND 0x00000004 -#define EPL_FEATURE_SDO_PDO 0x00000008 -#define EPL_FEATURE_NMT_INFO 0x00000010 -#define EPL_FEATURE_NMT_EXT 0x00000020 -#define EPL_FEATURE_PDO_DYN 0x00000040 -#define EPL_FEATURE_NMT_UDP 0x00000080 -#define EPL_FEATURE_CFGMA 0x00000100 -#define EPL_FEATURE_DLL_MULTIPLEX 0x00000200 -#define EPL_FEATURE_NODEID_SW 0x00000400 -#define EPL_FEATURE_NMT_BASICETH 0x00000800 -#define EPL_FEATURE_RT1 0x00001000 -#define EPL_FEATURE_RT2 0x00002000 - -// generate EPL NMT_FeatureFlags_U32 -#ifndef EPL_DEF_FEATURE_ISOCHR -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) -#define EPL_DEF_FEATURE_ISOCHR (EPL_FEATURE_ISOCHR) -#else -#define EPL_DEF_FEATURE_ISOCHR 0 -#endif -#endif - -#ifndef EPL_DEF_FEATURE_SDO_ASND -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) -#define EPL_DEF_FEATURE_SDO_ASND (EPL_FEATURE_SDO_ASND) -#else -#define EPL_DEF_FEATURE_SDO_ASND 0 -#endif -#endif - -#ifndef EPL_DEF_FEATURE_SDO_UDP -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) -#define EPL_DEF_FEATURE_SDO_UDP (EPL_FEATURE_SDO_UDP) -#else -#define EPL_DEF_FEATURE_SDO_UDP 0 -#endif -#endif - -#ifndef EPL_DEF_FEATURE_SDO_PDO -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_PDO)) != 0) -#define EPL_DEF_FEATURE_SDO_PDO (EPL_FEATURE_SDO_PDO) -#else -#define EPL_DEF_FEATURE_SDO_PDO 0 -#endif -#endif - -#ifndef EPL_DEF_FEATURE_PDO_DYN -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) -#define EPL_DEF_FEATURE_PDO_DYN (EPL_FEATURE_PDO_DYN) -#else -#define EPL_DEF_FEATURE_PDO_DYN 0 -#endif -#endif - -#ifndef EPL_DEF_FEATURE_CFGMA -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0) -#define EPL_DEF_FEATURE_CFGMA (EPL_FEATURE_CFGMA) -#else -#define EPL_DEF_FEATURE_CFGMA 0 -#endif -#endif - -#define EPL_DEF_FEATURE_FLAGS (EPL_DEF_FEATURE_ISOCHR \ - | EPL_DEF_FEATURE_SDO_ASND \ - | EPL_DEF_FEATURE_SDO_UDP \ - | EPL_DEF_FEATURE_SDO_PDO \ - | EPL_DEF_FEATURE_PDO_DYN \ - | EPL_DEF_FEATURE_CFGMA) - -#ifndef tabentries -#define tabentries(a) (sizeof(a)/sizeof(*(a))) -#endif - -// ============================================================================ -// common debug macros -// ============================================================================ -// for using macro DEBUG_TRACEx() -// -// Example: -// DEBUG_TRACE1 (EPL_DBGLVL_OBD, "Value is %d\n" , wObjectIndex); -// -// This message only will be printed if: -// - NDEBUG is not defined AND !!! -// - flag 0x00000004L is set in DEF_DEBUG_LVL (can be defined in copcfg.h) -// -// default level is defined in copdef.h - -// debug-level and TRACE-macros // standard-level // flags for DEF_DEBUG_LVL -#define EPL_DBGLVL_EDRV DEBUG_LVL_01 // 0x00000001L -#define EPL_DBGLVL_EDRV_TRACE0 DEBUG_LVL_01_TRACE0 -#define EPL_DBGLVL_EDRV_TRACE1 DEBUG_LVL_01_TRACE1 -#define EPL_DBGLVL_EDRV_TRACE2 DEBUG_LVL_01_TRACE2 -#define EPL_DBGLVL_EDRV_TRACE3 DEBUG_LVL_01_TRACE3 -#define EPL_DBGLVL_EDRV_TRACE4 DEBUG_LVL_01_TRACE4 - -#define EPL_DBGLVL_DLL DEBUG_LVL_02 // 0x00000002L -#define EPL_DBGLVL_DLL_TRACE0 DEBUG_LVL_02_TRACE0 -#define EPL_DBGLVL_DLL_TRACE1 DEBUG_LVL_02_TRACE1 -#define EPL_DBGLVL_DLL_TRACE2 DEBUG_LVL_02_TRACE2 -#define EPL_DBGLVL_DLL_TRACE3 DEBUG_LVL_02_TRACE3 -#define EPL_DBGLVL_DLL_TRACE4 DEBUG_LVL_02_TRACE4 - -#define EPL_DBGLVL_OBD DEBUG_LVL_03 // 0x00000004L -#define EPL_DBGLVL_OBD_TRACE0 DEBUG_LVL_03_TRACE0 -#define EPL_DBGLVL_OBD_TRACE1 DEBUG_LVL_03_TRACE1 -#define EPL_DBGLVL_OBD_TRACE2 DEBUG_LVL_03_TRACE2 -#define EPL_DBGLVL_OBD_TRACE3 DEBUG_LVL_03_TRACE3 -#define EPL_DBGLVL_OBD_TRACE4 DEBUG_LVL_03_TRACE4 - -#define EPL_DBGLVL_NMTK DEBUG_LVL_04 // 0x00000008L -#define EPL_DBGLVL_NMTK_TRACE0 DEBUG_LVL_04_TRACE0 -#define EPL_DBGLVL_NMTK_TRACE1 DEBUG_LVL_04_TRACE1 -#define EPL_DBGLVL_NMTK_TRACE2 DEBUG_LVL_04_TRACE2 -#define EPL_DBGLVL_NMTK_TRACE3 DEBUG_LVL_04_TRACE3 -#define EPL_DBGLVL_NMTK_TRACE4 DEBUG_LVL_04_TRACE4 - -#define EPL_DBGLVL_NMTCN DEBUG_LVL_05 // 0x00000010L -#define EPL_DBGLVL_NMTCN_TRACE0 DEBUG_LVL_05_TRACE0 -#define EPL_DBGLVL_NMTCN_TRACE1 DEBUG_LVL_05_TRACE1 -#define EPL_DBGLVL_NMTCN_TRACE2 DEBUG_LVL_05_TRACE2 -#define EPL_DBGLVL_NMTCN_TRACE3 DEBUG_LVL_05_TRACE3 -#define EPL_DBGLVL_NMTCN_TRACE4 DEBUG_LVL_05_TRACE4 - -#define EPL_DBGLVL_NMTU DEBUG_LVL_06 // 0x00000020L -#define EPL_DBGLVL_NMTU_TRACE0 DEBUG_LVL_06_TRACE0 -#define EPL_DBGLVL_NMTU_TRACE1 DEBUG_LVL_06_TRACE1 -#define EPL_DBGLVL_NMTU_TRACE2 DEBUG_LVL_06_TRACE2 -#define EPL_DBGLVL_NMTU_TRACE3 DEBUG_LVL_06_TRACE3 -#define EPL_DBGLVL_NMTU_TRACE4 DEBUG_LVL_06_TRACE4 - -#define EPL_DBGLVL_NMTMN DEBUG_LVL_07 // 0x00000040L -#define EPL_DBGLVL_NMTMN_TRACE0 DEBUG_LVL_07_TRACE0 -#define EPL_DBGLVL_NMTMN_TRACE1 DEBUG_LVL_07_TRACE1 -#define EPL_DBGLVL_NMTMN_TRACE2 DEBUG_LVL_07_TRACE2 -#define EPL_DBGLVL_NMTMN_TRACE3 DEBUG_LVL_07_TRACE3 -#define EPL_DBGLVL_NMTMN_TRACE4 DEBUG_LVL_07_TRACE4 - -//... - -#define EPL_DBGLVL_SDO DEBUG_LVL_25 // 0x01000000 -#define EPL_DBGLVL_SDO_TRACE0 DEBUG_LVL_25_TRACE0 -#define EPL_DBGLVL_SDO_TRACE1 DEBUG_LVL_25_TRACE1 -#define EPL_DBGLVL_SDO_TRACE2 DEBUG_LVL_25_TRACE2 -#define EPL_DBGLVL_SDO_TRACE3 DEBUG_LVL_25_TRACE3 -#define EPL_DBGLVL_SDO_TRACE4 DEBUG_LVL_25_TRACE4 - -#define EPL_DBGLVL_VETH DEBUG_LVL_26 // 0x02000000 -#define EPL_DBGLVL_VETH_TRACE0 DEBUG_LVL_26_TRACE0 -#define EPL_DBGLVL_VETH_TRACE1 DEBUG_LVL_26_TRACE1 -#define EPL_DBGLVL_VETH_TRACE2 DEBUG_LVL_26_TRACE2 -#define EPL_DBGLVL_VETH_TRACE3 DEBUG_LVL_26_TRACE3 -#define EPL_DBGLVL_VETH_TRACE4 DEBUG_LVL_26_TRACE4 - -#define EPL_DBGLVL_EVENTK DEBUG_LVL_27 // 0x04000000 -#define EPL_DBGLVL_EVENTK_TRACE0 DEBUG_LVL_27_TRACE0 -#define EPL_DBGLVL_EVENTK_TRACE1 DEBUG_LVL_27_TRACE1 -#define EPL_DBGLVL_EVENTK_TRACE2 DEBUG_LVL_27_TRACE2 -#define EPL_DBGLVL_EVENTK_TRACE3 DEBUG_LVL_27_TRACE3 -#define EPL_DBGLVL_EVENTK_TRACE4 DEBUG_LVL_27_TRACE4 - -#define EPL_DBGLVL_EVENTU DEBUG_LVL_28 // 0x08000000 -#define EPL_DBGLVL_EVENTU_TRACE0 DEBUG_LVL_28_TRACE0 -#define EPL_DBGLVL_EVENTU_TRACE1 DEBUG_LVL_28_TRACE1 -#define EPL_DBGLVL_EVENTU_TRACE2 DEBUG_LVL_28_TRACE2 -#define EPL_DBGLVL_EVENTU_TRACE3 DEBUG_LVL_28_TRACE3 -#define EPL_DBGLVL_EVENTU_TRACE4 DEBUG_LVL_28_TRACE4 - -// SharedBuff -#define EPL_DBGLVL_SHB DEBUG_LVL_29 // 0x10000000 -#define EPL_DBGLVL_SHB_TRACE0 DEBUG_LVL_29_TRACE0 -#define EPL_DBGLVL_SHB_TRACE1 DEBUG_LVL_29_TRACE1 -#define EPL_DBGLVL_SHB_TRACE2 DEBUG_LVL_29_TRACE2 -#define EPL_DBGLVL_SHB_TRACE3 DEBUG_LVL_29_TRACE3 -#define EPL_DBGLVL_SHB_TRACE4 DEBUG_LVL_29_TRACE4 - -#define EPL_DBGLVL_ASSERT DEBUG_LVL_ASSERT // 0x20000000L -#define EPL_DBGLVL_ASSERT_TRACE0 DEBUG_LVL_ASSERT_TRACE0 -#define EPL_DBGLVL_ASSERT_TRACE1 DEBUG_LVL_ASSERT_TRACE1 -#define EPL_DBGLVL_ASSERT_TRACE2 DEBUG_LVL_ASSERT_TRACE2 -#define EPL_DBGLVL_ASSERT_TRACE3 DEBUG_LVL_ASSERT_TRACE3 -#define EPL_DBGLVL_ASSERT_TRACE4 DEBUG_LVL_ASSERT_TRACE4 - -#define EPL_DBGLVL_ERROR DEBUG_LVL_ERROR // 0x40000000L -#define EPL_DBGLVL_ERROR_TRACE0 DEBUG_LVL_ERROR_TRACE0 -#define EPL_DBGLVL_ERROR_TRACE1 DEBUG_LVL_ERROR_TRACE1 -#define EPL_DBGLVL_ERROR_TRACE2 DEBUG_LVL_ERROR_TRACE2 -#define EPL_DBGLVL_ERROR_TRACE3 DEBUG_LVL_ERROR_TRACE3 -#define EPL_DBGLVL_ERROR_TRACE4 DEBUG_LVL_ERROR_TRACE4 - -#define EPL_DBGLVL_ALWAYS DEBUG_LVL_ALWAYS // 0x80000000L -#define EPL_DBGLVL_ALWAYS_TRACE0 DEBUG_LVL_ALWAYS_TRACE0 -#define EPL_DBGLVL_ALWAYS_TRACE1 DEBUG_LVL_ALWAYS_TRACE1 -#define EPL_DBGLVL_ALWAYS_TRACE2 DEBUG_LVL_ALWAYS_TRACE2 -#define EPL_DBGLVL_ALWAYS_TRACE3 DEBUG_LVL_ALWAYS_TRACE3 -#define EPL_DBGLVL_ALWAYS_TRACE4 DEBUG_LVL_ALWAYS_TRACE4 - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_INC_H_ diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h deleted file mode 100644 index 29ab7fb7888..00000000000 --- a/drivers/staging/epl/EplInstDef.h +++ /dev/null @@ -1,363 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: definitions for generating instances - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplInstDef.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - - r.d.: first implementation - -****************************************************************************/ - -#ifndef _EPLINSTDEF_H_ -#define _EPLINSTDEF_H_ - -#include - -// ========================================================================= -// types and macros for generating instances -// ========================================================================= - -typedef enum { - kStateUnused = 0, - kStateDeleted = 1, - kStateUsed = 0xFF -} tInstState; - -//------------------------------------------------------------------------------------------ - -typedef void *tEplPtrInstance; -typedef u8 tEplInstanceHdl; - -// define const for illegale values -#define CCM_ILLINSTANCE NULL -#define CCM_ILLINSTANCE_HDL 0xFF - -//------------------------------------------------------------------------------------------ -// if more than one instance then use this macros -#if (EPL_MAX_INSTANCES > 1) - - //-------------------------------------------------------------------------------------- - // macro definition for instance table definition - //-------------------------------------------------------------------------------------- - - // memory attributes for instance table -#define STATIC // prevent warnings for variables with same name - -#define INSTANCE_TYPE_BEGIN typedef struct { -#define INSTANCE_TYPE_END } tEplInstanceInfo; - - //-------------------------------------------------------------------------------------- - // macro definition for API interface - //-------------------------------------------------------------------------------------- - - // declaration: - - // macros for declaration within function header or prototype of API functions -#define CCM_DECL_INSTANCE_HDL tEplInstanceHdl InstanceHandle -#define CCM_DECL_INSTANCE_HDL_ tEplInstanceHdl InstanceHandle, - - // macros for declaration of pointer to instance handle within function header or prototype of API functions -#define CCM_DECL_PTR_INSTANCE_HDL tEplInstanceHdl *pInstanceHandle -#define CCM_DECL_PTR_INSTANCE_HDL_ tEplInstanceHdl *pInstanceHandle, - - // macros for declaration instance as lokacl variable within functions -#define CCM_DECL_INSTANCE_PTR_LOCAL tCcmInstanceInfo *pInstance; -#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL tEplInstanceHdl *pInstanceHandle; - - // reference: - - // macros for reference of instance handle for function parameters -#define CCM_INSTANCE_HDL InstanceHandle -#define CCM_INSTANCE_HDL_ InstanceHandle, - - // macros for reference of instance parameter for function parameters -#define CCM_INSTANCE_PARAM(par) par -#define CCM_INSTANCE_PARAM_(par) par, - - // macros for reference of instance parameter for writing or reading values -#define CCM_INST_ENTRY (*((tEplPtrInstance)pInstance)) - - // processing: - - // macros for process instance handle -#define CCM_CHECK_INSTANCE_HDL() if (InstanceHandle >= EPL_MAX_INSTANCES) \ - {return (kEplIllegalInstance);} - - // macros for process pointer to instance handle -#define CCM_CHECK_PTR_INSTANCE_HDL() if (pInstanceHandle == NULL) \ - {return (kEplInvalidInstanceParam);} - - // This macro returned the handle and pointer to next free instance. -#define CCM_GET_FREE_INSTANCE_AND_HDL() pInstance = CcmGetFreeInstanceAndHandle (pInstanceHandle); \ - ASSERT (*pInstanceHandle != CCM_ILLINSTANCE_HDL); - -#define CCM_CHECK_INSTANCE_PTR() if (pInstance == CCM_ILLINSTANCE) \ - {return (kEplNoFreeInstance);} - -#define CCM_GET_INSTANCE_PTR() pInstance = CcmGetInstancePtr (InstanceHandle); -#define CCM_GET_FREE_INSTANCE_PTR() pInstance = GetFreeInstance (); \ - ASSERT (pInstance != CCM_ILLINSTANCE); - - //-------------------------------------------------------------------------------------- - // macro definition for stack interface - //-------------------------------------------------------------------------------------- - - // macros for declaration within the function header, prototype or local var list - // Declaration of pointers within function paramater list must defined as void * - // pointer. -#define EPL_MCO_DECL_INSTANCE_PTR void *pInstance -#define EPL_MCO_DECL_INSTANCE_PTR_ void *pInstance, -#define EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplPtrInstance pInstance; - - // macros for reference of pointer to instance - // These macros are used for parameter passing to called function. -#define EPL_MCO_INSTANCE_PTR pInstance -#define EPL_MCO_INSTANCE_PTR_ pInstance, -#define EPL_MCO_ADDR_INSTANCE_PTR_ &pInstance, - - // macro for access of struct members of one instance - // An access to a member of instance table must be casted by the local - // defined type of instance table. -#define EPL_MCO_INST_ENTRY (*(tEplPtrInstance)pInstance) -#define EPL_MCO_GLB_VAR(var) (((tEplPtrInstance)pInstance)->var) - - // macros for process pointer to instance -#define EPL_MCO_GET_INSTANCE_PTR() pInstance = (tEplPtrInstance) GetInstancePtr (InstanceHandle); -#define EPL_MCO_GET_FREE_INSTANCE_PTR() pInstance = (tEplPtrInstance) GetFreeInstance (); \ - ASSERT (pInstance != CCM_ILLINSTANCE); - - // This macro should be used to check the passed pointer to an public function -#define EPL_MCO_CHECK_INSTANCE_STATE() ASSERT (pInstance != NULL); \ - ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed); - - // macros for declaration of pointer to instance pointer -#define EPL_MCO_DECL_PTR_INSTANCE_PTR void **pInstancePtr -#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ void **pInstancePtr, - - // macros for reference of pointer to instance pointer - // These macros are used for parameter passing to called function. -#define EPL_MCO_PTR_INSTANCE_PTR pInstancePtr -#define EPL_MCO_PTR_INSTANCE_PTR_ pInstancePtr, - - // macros for process pointer to instance pointer -#define EPL_MCO_CHECK_PTR_INSTANCE_PTR() ASSERT (pInstancePtr != NULL); -#define EPL_MCO_SET_PTR_INSTANCE_PTR() (*pInstancePtr = pInstance); - -#define EPL_MCO_INSTANCE_PARAM(a) (a) -#define EPL_MCO_INSTANCE_PARAM_(a) (a), -#define EPL_MCO_INSTANCE_PARAM_IDX_() EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex)) -#define EPL_MCO_INSTANCE_PARAM_IDX() EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex)) -#define EPL_MCO_WRITE_INSTANCE_STATE(a) EPL_MCO_GLB_VAR (m_InstState) = a; - - // this macro deletes all instance entries as unused -#define EPL_MCO_DELETE_INSTANCE_TABLE() \ - { \ - tEplInstanceInfo * pInstance = &aEplInstanceTable_g[0]; \ - tFastByte InstNumber = 0; \ - tFastByte i = EPL_MAX_INSTANCES; \ - do { \ - pInstance->m_InstState = (u8) kStateUnused; \ - pInstance->m_bInstIndex = (u8) InstNumber; \ - pInstance++; InstNumber++; i--; \ - } while (i != 0); \ - } - - // definition of functions which has to be defined in each module of CANopen stack -#define EPL_MCO_DEFINE_INSTANCE_FCT() \ - static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p); \ - static tEplPtrInstance GetFreeInstance (void); -#define EPL_MCO_DECL_INSTANCE_FCT() \ - static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \ - return &aEplInstanceTable_g[InstHandle_p]; } \ - static tEplPtrInstance GetFreeInstance (void) { \ - tEplInstanceInfo *pInstance = &aEplInstanceTable_g[0]; \ - tFastByte i = EPL_MAX_INSTANCES; \ - do { if (pInstance->m_InstState != kStateUsed) { \ - return (tEplPtrInstance) pInstance; } \ - pInstance++; i--; } \ - while (i != 0); \ - return CCM_ILLINSTANCE; } - - // this macro defines the instance table. Each entry is reserved for an instance of CANopen. -#define EPL_MCO_DECL_INSTANCE_VAR() \ - static tEplInstanceInfo aEplInstanceTable_g [EPL_MAX_INSTANCES]; - - // this macro defines member variables in instance table which are needed in - // all modules of Epl stack -#define EPL_MCO_DECL_INSTANCE_MEMBER() \ - STATIC u8 m_InstState; \ - STATIC u8 m_bInstIndex; - -#define EPL_MCO_INSTANCE_PARAM_IDX_() EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex)) -#define EPL_MCO_INSTANCE_PARAM_IDX() EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex)) - -#else // only one instance is used - - // Memory attributes for instance table. -#define STATIC static // prevent warnings for variables with same name - -#define INSTANCE_TYPE_BEGIN -#define INSTANCE_TYPE_END - -// macros for declaration, initializing and member access for instance handle -// This class of macros are used by API function to inform CCM-modul which -// instance is to be used. - - // macros for reference of instance handle - // These macros are used for parameter passing to CANopen API function. -#define CCM_INSTANCE_HDL -#define CCM_INSTANCE_HDL_ - -#define CCM_DECL_INSTANCE_PTR_LOCAL - - // macros for declaration within the function header or prototype -#define CCM_DECL_INSTANCE_HDL void -#define CCM_DECL_INSTANCE_HDL_ - - // macros for process instance handle -#define CCM_CHECK_INSTANCE_HDL() - - // macros for declaration of pointer to instance handle -#define CCM_DECL_PTR_INSTANCE_HDL void -#define CCM_DECL_PTR_INSTANCE_HDL_ - - // macros for process pointer to instance handle -#define CCM_CHECK_PTR_INSTANCE_HDL() - - // This macro returned the handle and pointer to next free instance. -#define CCM_GET_FREE_INSTANCE_AND_HDL() - -#define CCM_CHECK_INSTANCE_PTR() - -#define CCM_GET_INSTANCE_PTR() -#define CCM_GET_FREE_INSTANCE_PTR() - -#define CCM_INSTANCE_PARAM(par) -#define CCM_INSTANCE_PARAM_(par) - -#define CCM_INST_ENTRY aCcmInstanceTable_g[0] - -// macros for declaration, initializing and member access for instance pointer -// This class of macros are used by CANopen internal function to point to one instance. - - // macros for declaration within the function header, prototype or local var list -#define EPL_MCO_DECL_INSTANCE_PTR void -#define EPL_MCO_DECL_INSTANCE_PTR_ -#define EPL_MCO_DECL_INSTANCE_PTR_LOCAL - - // macros for reference of pointer to instance - // These macros are used for parameter passing to called function. -#define EPL_MCO_INSTANCE_PTR -#define EPL_MCO_INSTANCE_PTR_ -#define EPL_MCO_ADDR_INSTANCE_PTR_ - - // macros for process pointer to instance -#define EPL_MCO_GET_INSTANCE_PTR() -#define EPL_MCO_GET_FREE_INSTANCE_PTR() - - // This macro should be used to check the passed pointer to an public function -#define EPL_MCO_CHECK_INSTANCE_STATE() - - // macros for declaration of pointer to instance pointer -#define EPL_MCO_DECL_PTR_INSTANCE_PTR void -#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ - - // macros for reference of pointer to instance pointer - // These macros are used for parameter passing to called function. -#define EPL_MCO_PTR_INSTANCE_PTR -#define EPL_MCO_PTR_INSTANCE_PTR_ - - // macros for process pointer to instance pointer -#define EPL_MCO_CHECK_PTR_INSTANCE_PTR() -#define EPL_MCO_SET_PTR_INSTANCE_PTR() - -#define EPL_MCO_INSTANCE_PARAM(a) -#define EPL_MCO_INSTANCE_PARAM_(a) -#define EPL_MCO_INSTANCE_PARAM_IDX_() -#define EPL_MCO_INSTANCE_PARAM_IDX() - - // macro for access of struct members of one instance -#define EPL_MCO_INST_ENTRY aEplInstanceTable_g[0] -#define EPL_MCO_GLB_VAR(var) (var) -#define EPL_MCO_WRITE_INSTANCE_STATE(a) - - // this macro deletes all instance entries as unused -#define EPL_MCO_DELETE_INSTANCE_TABLE() - - // definition of functions which has to be defined in each module of CANopen stack -#define EPL_MCO_DEFINE_INSTANCE_FCT() -#define EPL_MCO_DECL_INSTANCE_FCT() - - // this macro defines the instance table. Each entry is reserved for an instance of CANopen. -#define EPL_MCO_DECL_INSTANCE_VAR() - - // this macro defines member variables in instance table which are needed in - // all modules of CANopen stack -#define EPL_MCO_DECL_INSTANCE_MEMBER() - -#endif - -#endif // _EPLINSTDEF_H_ - -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler -// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/EplLed.h b/drivers/staging/epl/EplLed.h deleted file mode 100644 index 6a29aed303a..00000000000 --- a/drivers/staging/epl/EplLed.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for status and error LED - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplLed.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.1 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2008/11/17 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLLED_H_ -#define _EPLLED_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef enum { - kEplLedTypeStatus = 0x00, - kEplLedTypeError = 0x01, - -} tEplLedType; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPLLED_H_ diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h deleted file mode 100644 index e351b55eea6..00000000000 --- a/drivers/staging/epl/EplNmt.h +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: global include file for EPL-NMT-Modules - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmt.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMT_H_ -#define _EPLNMT_H_ - -#include "EplInc.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// define super-states and masks to identify a super-state -#define EPL_NMT_GS_POWERED 0x0008 // super state -#define EPL_NMT_GS_INITIALISATION 0x0009 // super state -#define EPL_NMT_GS_COMMUNICATING 0x000C // super state -#define EPL_NMT_CS_EPLMODE 0x000D // super state -#define EPL_NMT_MS_EPLMODE 0x000D // super state - -#define EPL_NMT_SUPERSTATE_MASK 0x000F // mask to select state - -#define EPL_NMT_TYPE_UNDEFINED 0x0000 // type of NMT state is still undefined -#define EPL_NMT_TYPE_CS 0x0100 // CS type of NMT state -#define EPL_NMT_TYPE_MS 0x0200 // MS type of NMT state -#define EPL_NMT_TYPE_MASK 0x0300 // mask to select type of NMT state (i.e. CS or MS) - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -// the lower Byte of the NMT-State is encoded -// like the values in the EPL-Standard -// the higher byte is used to encode MN -// (Bit 1 of the higher byte = 1) or CN (Bit 0 of the -// higher byte = 1) -// the super-states are not mentioned in this -// enum because they are no real states -// --> there are masks defined to indentify the -// super-states - -typedef enum { - kEplNmtGsOff = 0x0000, - kEplNmtGsInitialising = 0x0019, - kEplNmtGsResetApplication = 0x0029, - kEplNmtGsResetCommunication = 0x0039, - kEplNmtGsResetConfiguration = 0x0079, - kEplNmtCsNotActive = 0x011C, - kEplNmtCsPreOperational1 = 0x011D, - kEplNmtCsStopped = 0x014D, - kEplNmtCsPreOperational2 = 0x015D, - kEplNmtCsReadyToOperate = 0x016D, - kEplNmtCsOperational = 0x01FD, - kEplNmtCsBasicEthernet = 0x011E, - kEplNmtMsNotActive = 0x021C, - kEplNmtMsPreOperational1 = 0x021D, - kEplNmtMsPreOperational2 = 0x025D, - kEplNmtMsReadyToOperate = 0x026D, - kEplNmtMsOperational = 0x02FD, - kEplNmtMsBasicEthernet = 0x021E -} tEplNmtState; - -// NMT-events -typedef enum { - // Events from DLL - // Events defined by EPL V2 specification - kEplNmtEventNoEvent = 0x00, -// kEplNmtEventDllMePres = 0x01, - kEplNmtEventDllMePresTimeout = 0x02, -// kEplNmtEventDllMeAsnd = 0x03, -// kEplNmtEventDllMeAsndTimeout = 0x04, - kEplNmtEventDllMeSoaSent = 0x04, - kEplNmtEventDllMeSocTrig = 0x05, - kEplNmtEventDllMeSoaTrig = 0x06, - kEplNmtEventDllCeSoc = 0x07, - kEplNmtEventDllCePreq = 0x08, - kEplNmtEventDllCePres = 0x09, - kEplNmtEventDllCeSoa = 0x0A, - kEplNmtEventDllCeAsnd = 0x0B, - kEplNmtEventDllCeFrameTimeout = 0x0C, - - // Events triggered by NMT-Commands - kEplNmtEventSwReset = 0x10, // NMT_GT1, NMT_GT2, NMT_GT8 - kEplNmtEventResetNode = 0x11, - kEplNmtEventResetCom = 0x12, - kEplNmtEventResetConfig = 0x13, - kEplNmtEventEnterPreOperational2 = 0x14, - kEplNmtEventEnableReadyToOperate = 0x15, - kEplNmtEventStartNode = 0x16, // NMT_CT7 - kEplNmtEventStopNode = 0x17, - - // Events triggered by higher layer - kEplNmtEventEnterResetApp = 0x20, - kEplNmtEventEnterResetCom = 0x21, - kEplNmtEventInternComError = 0x22, // NMT_GT6, internal communication error -> enter ResetCommunication - kEplNmtEventEnterResetConfig = 0x23, - kEplNmtEventEnterCsNotActive = 0x24, - kEplNmtEventEnterMsNotActive = 0x25, - kEplNmtEventTimerBasicEthernet = 0x26, // NMT_CT3; timer triggered state change (NotActive -> BasicEth) - kEplNmtEventTimerMsPreOp1 = 0x27, // enter PreOp1 on MN (NotActive -> MsPreOp1) - kEplNmtEventNmtCycleError = 0x28, // NMT_CT11, NMT_MT6; error during cycle -> enter PreOp1 - kEplNmtEventTimerMsPreOp2 = 0x29, // enter PreOp2 on MN (MsPreOp1 -> MsPreOp2 if kEplNmtEventAllMandatoryCNIdent) - kEplNmtEventAllMandatoryCNIdent = 0x2A, // enter PreOp2 on MN if kEplNmtEventTimerMsPreOp2 - kEplNmtEventEnterReadyToOperate = 0x2B, // application ready for the state ReadyToOp - kEplNmtEventEnterMsOperational = 0x2C, // enter Operational on MN - kEplNmtEventSwitchOff = 0x2D, // enter state Off - kEplNmtEventCriticalError = 0x2E, // enter state Off because of critical error - -} tEplNmtEvent; - -// type for argument of event kEplEventTypeNmtStateChange -typedef struct { - tEplNmtState m_NewNmtState; - tEplNmtEvent m_NmtEvent; - -} tEplEventNmtStateChange; - -// structure for kEplEventTypeHeartbeat -typedef struct { - unsigned int m_uiNodeId; // NodeId - tEplNmtState m_NmtState; // NMT state (remember distinguish between MN / CN) - u16 m_wErrorCode; // EPL error code in case of NMT state NotActive - -} tEplHeartbeatEvent; - -typedef enum { - kEplNmtNodeEventFound = 0x00, - kEplNmtNodeEventUpdateSw = 0x01, // application shall update software on CN - kEplNmtNodeEventCheckConf = 0x02, // application / Configuration Manager shall check and update configuration on CN - kEplNmtNodeEventUpdateConf = 0x03, // application / Configuration Manager shall update configuration on CN (check was done by NmtMn module) - kEplNmtNodeEventVerifyConf = 0x04, // application / Configuration Manager shall verify configuration of CN - kEplNmtNodeEventReadyToStart = 0x05, // issued if EPL_NMTST_NO_STARTNODE set - // application must call EplNmtMnuSendNmtCommand(kEplNmtCmdStartNode) manually - kEplNmtNodeEventNmtState = 0x06, - kEplNmtNodeEventError = 0x07, // NMT error of CN - -} tEplNmtNodeEvent; - -typedef enum { - kEplNmtNodeCommandBoot = 0x01, // if EPL_NODEASSIGN_START_CN not set it must be issued after kEplNmtNodeEventFound - kEplNmtNodeCommandSwOk = 0x02, // application updated software on CN successfully - kEplNmtNodeCommandSwUpdated = 0x03, // application updated software on CN successfully - kEplNmtNodeCommandConfOk = 0x04, // application / Configuration Manager has updated configuration on CN successfully - kEplNmtNodeCommandConfReset = 0x05, // application / Configuration Manager has updated configuration on CN successfully - // and CN needs ResetConf so that the configuration gets actived - kEplNmtNodeCommandConfErr = 0x06, // application / Configuration Manager failed on updating configuration on CN - kEplNmtNodeCommandStart = 0x07, // if EPL_NMTST_NO_STARTNODE set it must be issued after kEplNmtNodeEventReadyToStart - -} tEplNmtNodeCommand; - -typedef enum { - kEplNmtBootEventBootStep1Finish = 0x00, // PreOp2 is possible - kEplNmtBootEventBootStep2Finish = 0x01, // ReadyToOp is possible - kEplNmtBootEventCheckComFinish = 0x02, // Operational is possible - kEplNmtBootEventOperational = 0x03, // all mandatory CNs are Operational - kEplNmtBootEventError = 0x04, // boot process halted because of an error - -} tEplNmtBootEvent; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPLNMT_H_ diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c deleted file mode 100644 index c27ca8f8c2f..00000000000 --- a/drivers/staging/epl/EplNmtCnu.c +++ /dev/null @@ -1,701 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for NMT-CN-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtCnu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" -#include "user/EplNmtCnu.h" -#include "user/EplDlluCal.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - unsigned int m_uiNodeId; - tEplNmtuCheckEventCallback m_pfnCheckEventCb; - -} tEplNmtCnuInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplNmtCnuInstance EplNmtCnuInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p); - -static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p); - -static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuInit -// -// Description: init the first instance of the module -// -// -// -// Parameters: uiNodeId_p = NodeId of the local node -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p) -{ - tEplKernel Ret; - - Ret = EplNmtCnuAddInstance(uiNodeId_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuAddInstance -// -// Description: init the add new instance of the module -// -// -// -// Parameters: uiNodeId_p = NodeId of the local node -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof(EplNmtCnuInstance_g)); - - // save nodeid - EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p; - - // register callback-function for NMT-commands -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand, - EplNmtCnuCommandCb, - kEplDllAsndFilterLocal); -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuDelInstance -// -// Description: delte instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtCnuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - // deregister callback function from DLL - Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand, - NULL, kEplDllAsndFilterNone); -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuSendNmtRequest -// -// Description: Send an NMT-Request to the MN -// -// -// -// Parameters: uiNodeId_p = NodeId of the local node -// NmtCommand_p = requested NMT-Command -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, - tEplNmtCommand NmtCommand_p) -{ - tEplKernel Ret; - tEplFrameInfo NmtRequestFrameInfo; - tEplFrame NmtRequestFrame; - - Ret = kEplSuccessful; - - // build frame - EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac)); // set by DLL - EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL - AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType, - EPL_C_DLL_ETHERTYPE_EPL); - AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (u8) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN - AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType, - (u8) kEplMsgTypeAsnd); - AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId, - (u8) kEplDllAsndNmtRequest); - AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload. - m_NmtRequestService.m_le_bNmtCommandId, - (u8) NmtCommand_p); - AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (u8) uiNodeId_p); // target for the nmt command - EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService. - m_le_abNmtCommandData[0], 0x00, - sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload. - m_NmtRequestService.m_le_abNmtCommandData)); - - // build info-structure - NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0; - NmtRequestFrameInfo.m_NetTime.m_dwSec = 0; - NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame; - NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ; // sizeof(NmtRequestFrame); - - // send NMT-Request -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo, // pointer to frameinfo - kEplDllAsyncReqPrioNmt); // priority -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuRegisterStateChangeCb -// -// Description: register Callback-function go get informed about a -// NMT-Change-State-Event -// -// -// -// Parameters: pfnEplNmtStateChangeCb_p = functionpointer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // save callback-function in modul global var - EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p; - - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuCommandCb -// -// Description: callback funktion for NMT-Commands -// -// -// -// Parameters: pFrameInfo_p = Frame with the NMT-Commando -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtCommand NmtCommand; - BOOL fNodeIdInList; - tEplNmtEvent NmtEvent = kEplNmtEventNoEvent; - - if (pFrameInfo_p == NULL) { - Ret = kEplNmtInvalidFramePointer; - goto Exit; - } - - NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p); - - // check NMT-Command - switch (NmtCommand) { - - //------------------------------------------------------------------------ - // plain NMT state commands - case kEplNmtCmdStartNode: - { // send NMT-Event to state maschine kEplNmtEventStartNode - NmtEvent = kEplNmtEventStartNode; - break; - } - - case kEplNmtCmdStopNode: - { // send NMT-Event to state maschine kEplNmtEventStopNode - NmtEvent = kEplNmtEventStopNode; - break; - } - - case kEplNmtCmdEnterPreOperational2: - { // send NMT-Event to state maschine kEplNmtEventEnterPreOperational2 - NmtEvent = kEplNmtEventEnterPreOperational2; - break; - } - - case kEplNmtCmdEnableReadyToOperate: - { // send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate - NmtEvent = kEplNmtEventEnableReadyToOperate; - break; - } - - case kEplNmtCmdResetNode: - { // send NMT-Event to state maschine kEplNmtEventResetNode - NmtEvent = kEplNmtEventResetNode; - break; - } - - case kEplNmtCmdResetCommunication: - { // send NMT-Event to state maschine kEplNmtEventResetCom - NmtEvent = kEplNmtEventResetCom; - break; - } - - case kEplNmtCmdResetConfiguration: - { // send NMT-Event to state maschine kEplNmtEventResetConfig - NmtEvent = kEplNmtEventResetConfig; - break; - } - - case kEplNmtCmdSwReset: - { // send NMT-Event to state maschine kEplNmtEventSwReset - NmtEvent = kEplNmtEventSwReset; - break; - } - - //------------------------------------------------------------------------ - // extended NMT state commands - - case kEplNmtCmdStartNodeEx: - { - // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(& - (pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0])); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventStartNode; - } - break; - } - - case kEplNmtCmdStopNodeEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventStopNode; - } - break; - } - - case kEplNmtCmdEnterPreOperational2Ex: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventEnterPreOperational2; - } - break; - } - - case kEplNmtCmdEnableReadyToOperateEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventEnableReadyToOperate; - } - break; - } - - case kEplNmtCmdResetNodeEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventResetNode; - } - break; - } - - case kEplNmtCmdResetCommunicationEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventResetCom; - } - break; - } - - case kEplNmtCmdResetConfigurationEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventResetConfig; - } - break; - } - - case kEplNmtCmdSwResetEx: - { // check if own nodeid is in EPL node list - fNodeIdInList = - EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_abNmtCommandData[0]); - if (fNodeIdInList != FALSE) { // own nodeid in list - // send event to process command - NmtEvent = kEplNmtEventSwReset; - } - break; - } - - //------------------------------------------------------------------------ - // NMT managing commands - - // TODO: add functions to process managing command (optional) - - case kEplNmtCmdNetHostNameSet: - { - break; - } - - case kEplNmtCmdFlushArpEntry: - { - break; - } - - //------------------------------------------------------------------------ - // NMT info services - - // TODO: forward event with infos to the application (optional) - - case kEplNmtCmdPublishConfiguredCN: - { - break; - } - - case kEplNmtCmdPublishActiveCN: - { - break; - } - - case kEplNmtCmdPublishPreOperational1: - { - break; - } - - case kEplNmtCmdPublishPreOperational2: - { - break; - } - - case kEplNmtCmdPublishReadyToOperate: - { - break; - } - - case kEplNmtCmdPublishOperational: - { - break; - } - - case kEplNmtCmdPublishStopped: - { - break; - } - - case kEplNmtCmdPublishEmergencyNew: - { - break; - } - - case kEplNmtCmdPublishTime: - { - break; - } - - //----------------------------------------------------------------------- - // error from MN - // -> requested command not supported by MN - case kEplNmtCmdInvalidService: - { - - // TODO: errorevent to application - break; - } - - //------------------------------------------------------------------------ - // default - default: - { - Ret = kEplNmtUnknownCommand; - goto Exit; - } - - } // end of switch(NmtCommand) - - if (NmtEvent != kEplNmtEventNoEvent) { - if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL) { - Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent); - if (Ret == kEplReject) { - Ret = kEplSuccessful; - goto Exit; - } else if (Ret != kEplSuccessful) { - goto Exit; - } - } -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - Ret = EplNmtuNmtEvent(NmtEvent); -#endif - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuGetNmtCommand() -// -// Description: returns the NMT-Command from the frame -// -// -// -// Parameters: pFrameInfo_p = pointer to the Frame -// with the NMT-Command -// -// -// Returns: tEplNmtCommand = NMT-Command -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p) -{ - tEplNmtCommand NmtCommand; - tEplNmtCommandService *pNmtCommandService; - - pNmtCommandService = - &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload. - m_NmtCommandService; - - NmtCommand = - (tEplNmtCommand) AmiGetByteFromLe(&pNmtCommandService-> - m_le_bNmtCommandId); - - return NmtCommand; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtCnuNodeIdList() -// -// Description: check if the own nodeid is set in EPL Node List -// -// -// -// Parameters: pbNmtCommandDate_p = pointer to the data of the NMT Command -// -// -// Returns: BOOL = TRUE if nodeid is set in EPL Node List -// FALSE if nodeid not set in EPL Node List -// -// -// State: -// -//--------------------------------------------------------------------------- -static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p) -{ - BOOL fNodeIdInList; - unsigned int uiByteOffset; - u8 bBitOffset; - u8 bNodeListByte; - - // get byte-offset of the own nodeid in NodeIdList - // devide though 8 - uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3); - // get bitoffset - bBitOffset = (u8) EplNmtCnuInstance_g.m_uiNodeId % 8; - - bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]); - if ((bNodeListByte & bBitOffset) == 0) { - fNodeIdInList = FALSE; - } else { - fNodeIdInList = TRUE; - } - - return fNodeIdInList; -} - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c deleted file mode 100644 index d19434f5f6f..00000000000 --- a/drivers/staging/epl/EplNmtMnu.c +++ /dev/null @@ -1,2828 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for NMT-MN-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtMnu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.18 $ $Date: 2008/11/19 09:52:24 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplNmtMnu.h" -#include "user/EplTimeru.h" -#include "user/EplIdentu.h" -#include "user/EplStatusu.h" -#include "user/EplObdu.h" -#include "user/EplDlluCal.h" -#include "Benchmark.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE) -#error "EPL NmtMnu module needs EPL module OBDU or OBDK!" -#endif - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif -#define EPL_NMTMNU_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \ - TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtMnu << 28) | (Event_p << 24) \ - | (uiNodeId_p << 16) | wErrorCode_p) - -// defines for flags in node info structure -#define EPL_NMTMNU_NODE_FLAG_ISOCHRON 0x0001 // CN is being accessed isochronously -#define EPL_NMTMNU_NODE_FLAG_NOT_SCANNED 0x0002 // CN was not scanned once -> decrement SignalCounter and reset flag -#define EPL_NMTMNU_NODE_FLAG_HALTED 0x0004 // boot process for this CN is halted -#define EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED 0x0008 // NMT command was just issued, wrong NMT states will be tolerated -#define EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ 0x0300 // counter for StatusRequest timer handle -#define EPL_NMTMNU_NODE_FLAG_COUNT_LONGER 0x0C00 // counter for longer timeouts timer handle -#define EPL_NMTMNU_NODE_FLAG_INC_STATREQ 0x0100 // increment for StatusRequest timer handle -#define EPL_NMTMNU_NODE_FLAG_INC_LONGER 0x0400 // increment for longer timeouts timer handle - // These counters will be incremented at every timer start - // and copied to timerarg. When the timer event occures - // both will be compared and if unequal the timer event - // will be discarded, because it is an old one. - -// defines for timer arguments to draw a distinction between serveral events -#define EPL_NMTMNU_TIMERARG_NODE_MASK 0x000000FFL // mask that contains the node-ID -#define EPL_NMTMNU_TIMERARG_IDENTREQ 0x00010000L // timer event is for IdentRequest -#define EPL_NMTMNU_TIMERARG_STATREQ 0x00020000L // timer event is for StatusRequest -#define EPL_NMTMNU_TIMERARG_LONGER 0x00040000L // timer event is for longer timeouts -#define EPL_NMTMNU_TIMERARG_STATE_MON 0x00080000L // timer event for StatusRequest to monitor execution of NMT state changes -#define EPL_NMTMNU_TIMERARG_COUNT_SR 0x00000300L // counter for StatusRequest -#define EPL_NMTMNU_TIMERARG_COUNT_LO 0x00000C00L // counter for longer timeouts - // The counters must have the same position as in the node flags above. - -#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \ - pNodeInfo_p->m_wFlags = \ - ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \ - & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \ - | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p | \ - (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_EventSink = kEplEventSinkNmtMnu; - -#define EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \ - pNodeInfo_p->m_wFlags = \ - ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \ - & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \ - | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p | \ - (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_EventSink = kEplEventSinkNmtMnu; - -#define EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, TimerArg_p) \ - pNodeInfo_p->m_wFlags = \ - ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_LONGER) \ - & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) \ - | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \ - TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p | \ - (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \ - TimerArg_p.m_EventSink = kEplEventSinkNmtMnu; - -#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(pNodeInfo_p, uiNodeId_p, TimerArg_p) \ - pNodeInfo_p->m_wFlags = \ - ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \ - & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \ - | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATE_MON | uiNodeId_p | \ - (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \ - TimerArg_p.m_EventSink = kEplEventSinkNmtMnu; - -// defines for global flags -#define EPL_NMTMNU_FLAG_HALTED 0x0001 // boot process is halted -#define EPL_NMTMNU_FLAG_APP_INFORMED 0x0002 // application was informed about possible NMT state change - -// return pointer to node info structure for specified node ID -// d.k. may be replaced by special (hash) function if node ID array is smaller than 254 -#define EPL_NMTMNU_GET_NODEINFO(uiNodeId_p) (&EplNmtMnuInstance_g.m_aNodeInfo[uiNodeId_p - 1]) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef enum { - kEplNmtMnuIntNodeEventNoIdentResponse = 0x00, - kEplNmtMnuIntNodeEventIdentResponse = 0x01, - kEplNmtMnuIntNodeEventBoot = 0x02, - kEplNmtMnuIntNodeEventExecReset = 0x03, - kEplNmtMnuIntNodeEventConfigured = 0x04, - kEplNmtMnuIntNodeEventNoStatusResponse = 0x05, - kEplNmtMnuIntNodeEventStatusResponse = 0x06, - kEplNmtMnuIntNodeEventHeartbeat = 0x07, - kEplNmtMnuIntNodeEventNmtCmdSent = 0x08, - kEplNmtMnuIntNodeEventTimerIdentReq = 0x09, - kEplNmtMnuIntNodeEventTimerStatReq = 0x0A, - kEplNmtMnuIntNodeEventTimerStateMon = 0x0B, - kEplNmtMnuIntNodeEventTimerLonger = 0x0C, - kEplNmtMnuIntNodeEventError = 0x0D, - -} tEplNmtMnuIntNodeEvent; - -typedef enum { - kEplNmtMnuNodeStateUnknown = 0x00, - kEplNmtMnuNodeStateIdentified = 0x01, - kEplNmtMnuNodeStateResetConf = 0x02, // CN reset after configuration update - kEplNmtMnuNodeStateConfigured = 0x03, // BootStep1 completed - kEplNmtMnuNodeStateReadyToOp = 0x04, // BootStep2 completed - kEplNmtMnuNodeStateComChecked = 0x05, // Communication checked successfully - kEplNmtMnuNodeStateOperational = 0x06, // CN is in NMT state OPERATIONAL - -} tEplNmtMnuNodeState; - -typedef struct { - tEplTimerHdl m_TimerHdlStatReq; // timer to delay StatusRequests and IdentRequests - tEplTimerHdl m_TimerHdlLonger; // 2nd timer for NMT command EnableReadyToOp and CheckCommunication - tEplNmtMnuNodeState m_NodeState; // internal node state (kind of sub state of NMT state) - u32 m_dwNodeCfg; // subindex from 0x1F81 - u16 m_wFlags; // flags: CN is being accessed isochronously - -} tEplNmtMnuNodeInfo; - -typedef struct { - tEplNmtMnuNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID]; - tEplTimerHdl m_TimerHdlNmtState; // timeout for stay in NMT state - unsigned int m_uiMandatorySlaveCount; - unsigned int m_uiSignalSlaveCount; - unsigned long m_ulStatusRequestDelay; // in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE) - unsigned long m_ulTimeoutReadyToOp; // in [ms] (object 0x1F89/5) - unsigned long m_ulTimeoutCheckCom; // in [ms] (object 0x1006 * MultiplexedCycleCount) - u16 m_wFlags; // global flags - u32 m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32 - tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent; - tEplNmtMnuCbBootEvent m_pfnCbBootEvent; - -} tEplNmtMnuInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplNmtMnuInstance EplNmtMnuInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p); - -static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p, - tEplIdentResponse *pIdentResponse_p); - -static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p, - tEplStatusResponse *pStatusResponse_p); - -static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p, - tEplNmtState NodeNmtState_p, - u16 wErrorCode_p, - tEplNmtState LocalNmtState_p); - -static tEplKernel EplNmtMnuStartBootStep1(void); - -static tEplKernel EplNmtMnuStartBootStep2(void); - -static tEplKernel EplNmtMnuStartCheckCom(void); - -static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p); - -static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p); - -static tEplKernel EplNmtMnuStartNodes(void); - -static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p, - tEplNmtState NodeNmtState_p, - u16 wErrorCode_p, - tEplNmtMnuIntNodeEvent - NodeEvent_p); - -static tEplKernel EplNmtMnuReset(void); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuInit -// -// Description: init first instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p, - tEplNmtMnuCbBootEvent pfnCbBootEvent_p) -{ - tEplKernel Ret; - - Ret = EplNmtMnuAddInstance(pfnCbNodeEvent_p, pfnCbBootEvent_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuAddInstance -// -// Description: init other instances of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p, - tEplNmtMnuCbBootEvent pfnCbBootEvent_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplNmtMnuInstance_g, 0, sizeof(EplNmtMnuInstance_g)); - - if ((pfnCbNodeEvent_p == NULL) || (pfnCbBootEvent_p == NULL)) { - Ret = kEplNmtInvalidParam; - goto Exit; - } - EplNmtMnuInstance_g.m_pfnCbNodeEvent = pfnCbNodeEvent_p; - EplNmtMnuInstance_g.m_pfnCbBootEvent = pfnCbBootEvent_p; - - // initialize StatusRequest delay - EplNmtMnuInstance_g.m_ulStatusRequestDelay = 5000L; - - // register NmtMnResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndNmtRequest, - EplNmtMnuCbNmtRequest, - kEplDllAsndFilterLocal); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuDelInstance -// -// Description: delete instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // deregister NmtMnResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndNmtRequest, NULL, - kEplDllAsndFilterNone); - - Ret = EplNmtMnuReset(); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuSendNmtCommandEx -// -// Description: sends the specified NMT command to the specified node. -// -// Parameters: uiNodeId_p = node ID to which the NMT command will be sent -// NmtCommand_p = NMT command -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p, - tEplNmtCommand NmtCommand_p, - void *pNmtCommandData_p, - unsigned int uiDataSize_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrameInfo FrameInfo; - u8 abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT]; - tEplFrame *pFrame = (tEplFrame *) abBuffer; - BOOL fSoftDeleteNode = FALSE; - - if ((uiNodeId_p == 0) || (uiNodeId_p > EPL_C_ADR_BROADCAST)) { // invalid node ID specified - Ret = kEplInvalidNodeId; - goto Exit; - } - - if ((pNmtCommandData_p != NULL) - && (uiDataSize_p > - (EPL_C_DLL_MINSIZE_NMTCMDEXT - EPL_C_DLL_MINSIZE_NMTCMD))) { - Ret = kEplNmtInvalidParam; - goto Exit; - } - // $$$ d.k. may be check in future versions if the caller wants to perform prohibited state transitions - // the CN should not perform these transitions, but the expected NMT state will be changed and never fullfilled. - - // build frame - EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer)); - AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (u8) uiNodeId_p); - AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId, - (u8) kEplDllAsndNmtCommand); - AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService. - m_le_bNmtCommandId, (u8) NmtCommand_p); - if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) { // copy command data to frame - EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService. - m_le_abNmtCommandData[0], pNmtCommandData_p, - uiDataSize_p); - } - // build info structure - FrameInfo.m_NetTime.m_dwNanoSec = 0; - FrameInfo.m_NetTime.m_dwSec = 0; - FrameInfo.m_pFrame = pFrame; - FrameInfo.m_uiFrameSize = sizeof(abBuffer); - - // send NMT-Request -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalAsyncSend(&FrameInfo, // pointer to frameinfo - kEplDllAsyncReqPrioNmt); // priority -#endif - if (Ret != kEplSuccessful) { - goto Exit; - } - - EPL_DBGLVL_NMTMN_TRACE2("NMTCmd(%02X->%02X)\n", NmtCommand_p, - uiNodeId_p); - - switch (NmtCommand_p) { - case kEplNmtCmdStartNode: - case kEplNmtCmdEnterPreOperational2: - case kEplNmtCmdEnableReadyToOperate: - { - // nothing left to do, - // because any further processing is done - // when the NMT command is actually sent - goto Exit; - } - - case kEplNmtCmdStopNode: - { - fSoftDeleteNode = TRUE; - break; - } - - case kEplNmtCmdResetNode: - case kEplNmtCmdResetCommunication: - case kEplNmtCmdResetConfiguration: - case kEplNmtCmdSwReset: - { - break; - } - - default: - goto Exit; - } - - // remove CN from isochronous phase; - // This must be done here and not when NMT command is actually sent - // because it will be too late and may cause unwanted errors - if (uiNodeId_p != EPL_C_ADR_BROADCAST) { - if (fSoftDeleteNode == FALSE) { // remove CN immediately from isochronous phase - Ret = EplDlluCalDeleteNode(uiNodeId_p); - } else { // remove CN from isochronous phase softly - Ret = EplDlluCalSoftDeleteNode(uiNodeId_p); - } - } else { // do it for all active CNs - for (uiNodeId_p = 1; - uiNodeId_p <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); - uiNodeId_p++) { - if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId_p)-> - m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | - EPL_NODEASSIGN_NODE_EXISTS)) != 0) { - if (fSoftDeleteNode == FALSE) { // remove CN immediately from isochronous phase - Ret = EplDlluCalDeleteNode(uiNodeId_p); - } else { // remove CN from isochronous phase softly - Ret = - EplDlluCalSoftDeleteNode - (uiNodeId_p); - } - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuSendNmtCommand -// -// Description: sends the specified NMT command to the specified node. -// -// Parameters: uiNodeId_p = node ID to which the NMT command will be sent -// NmtCommand_p = NMT command -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p, - tEplNmtCommand NmtCommand_p) -{ - tEplKernel Ret = kEplSuccessful; - - Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, NmtCommand_p, NULL, 0); - -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuTriggerStateChange -// -// Description: triggers the specified node command for the specified node. -// -// Parameters: uiNodeId_p = node ID for which the node command will be executed -// NodeCommand_p = node command -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p, - tEplNmtNodeCommand NodeCommand_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtMnuIntNodeEvent NodeEvent; - tEplObdSize ObdSize; - u8 bNmtState; - u16 wErrorCode = EPL_E_NO_ERROR; - - if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) { - Ret = kEplInvalidNodeId; - goto Exit; - } - - switch (NodeCommand_p) { - case kEplNmtNodeCommandBoot: - { - NodeEvent = kEplNmtMnuIntNodeEventBoot; - break; - } - - case kEplNmtNodeCommandConfOk: - { - NodeEvent = kEplNmtMnuIntNodeEventConfigured; - break; - } - - case kEplNmtNodeCommandConfErr: - { - NodeEvent = kEplNmtMnuIntNodeEventError; - wErrorCode = EPL_E_NMT_BPO1_CF_VERIFY; - break; - } - - case kEplNmtNodeCommandConfReset: - { - NodeEvent = kEplNmtMnuIntNodeEventExecReset; - break; - } - - default: - { // invalid node command - goto Exit; - } - } - - // fetch current NMT state - ObdSize = 1; - Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtState, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - wErrorCode, NodeEvent); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCbNmtStateChange -// -// Description: callback function for NMT state changes -// -// Parameters: NmtStateChange_p = NMT state change event -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p) -{ - tEplKernel Ret = kEplSuccessful; - - // do work which must be done in that state - switch (NmtStateChange_p.m_NewNmtState) { - // EPL stack is not running -/* case kEplNmtGsOff: - break; - - // first init of the hardware - case kEplNmtGsInitialising: - break; - - // init of the manufacturer-specific profile area and the - // standardised device profile area - case kEplNmtGsResetApplication: - { - break; - } - - // init of the communication profile area - case kEplNmtGsResetCommunication: - { - break; - } -*/ - // build the configuration with infos from OD - case kEplNmtGsResetConfiguration: - { - u32 dwTimeout; - tEplObdSize ObdSize; - - // read object 0x1F80 NMT_StartUp_U32 - ObdSize = 4; - Ret = - EplObduReadEntry(0x1F80, 0, - &EplNmtMnuInstance_g. - m_dwNmtStartup, &ObdSize); - if (Ret != kEplSuccessful) { - break; - } - // compute StatusReqDelay = object 0x1006 * EPL_C_NMT_STATREQ_CYCLE - ObdSize = sizeof(dwTimeout); - Ret = EplObduReadEntry(0x1006, 0, &dwTimeout, &ObdSize); - if (Ret != kEplSuccessful) { - break; - } - if (dwTimeout != 0L) { - EplNmtMnuInstance_g.m_ulStatusRequestDelay = - dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L; - if (EplNmtMnuInstance_g. - m_ulStatusRequestDelay == 0L) { - EplNmtMnuInstance_g.m_ulStatusRequestDelay = 1L; // at least 1 ms - } - // $$$ fetch and use MultiplexedCycleCount from OD - EplNmtMnuInstance_g.m_ulTimeoutCheckCom = - dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L; - if (EplNmtMnuInstance_g.m_ulTimeoutCheckCom == - 0L) { - EplNmtMnuInstance_g.m_ulTimeoutCheckCom = 1L; // at least 1 ms - } - } - // fetch ReadyToOp Timeout from OD - ObdSize = sizeof(dwTimeout); - Ret = EplObduReadEntry(0x1F89, 5, &dwTimeout, &ObdSize); - if (Ret != kEplSuccessful) { - break; - } - if (dwTimeout != 0L) { - // convert [us] to [ms] - dwTimeout /= 1000L; - if (dwTimeout == 0L) { - dwTimeout = 1L; // at least 1 ms - } - EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = - dwTimeout; - } else { - EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = 0L; - } - break; - } -/* - //----------------------------------------------------------- - // CN part of the state machine - - // node liste for EPL-Frames and check timeout - case kEplNmtCsNotActive: - { - break; - } - - // node process only async frames - case kEplNmtCsPreOperational1: - { - break; - } - - // node process isochronus and asynchronus frames - case kEplNmtCsPreOperational2: - { - break; - } - - // node should be configured und application is ready - case kEplNmtCsReadyToOperate: - { - break; - } - - // normal work state - case kEplNmtCsOperational: - { - break; - } - - // node stopped by MN - // -> only process asynchronus frames - case kEplNmtCsStopped: - { - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtCsBasicEthernet: - { - break; - } -*/ - //----------------------------------------------------------- - // MN part of the state machine - - // node listens for EPL-Frames and check timeout - case kEplNmtMsNotActive: - { - break; - } - - // node processes only async frames - case kEplNmtMsPreOperational1: - { - u32 dwTimeout; - tEplTimerArg TimerArg; - tEplObdSize ObdSize; - tEplEvent Event; - - // clear global flags, e.g. reenable boot process - EplNmtMnuInstance_g.m_wFlags = 0; - - // reset IdentResponses and running IdentRequests and StatusRequests - Ret = EplIdentuReset(); - Ret = EplStatusuReset(); - - // reset timers - Ret = EplNmtMnuReset(); - - // 2008/11/18 d.k. reset internal node info is not necessary, - // because timer flags are important and other - // things are reset by EplNmtMnuStartBootStep1(). -/* - EPL_MEMSET(EplNmtMnuInstance_g.m_aNodeInfo, - 0, - sizeof (EplNmtMnuInstance_g.m_aNodeInfo)); -*/ - - // inform DLL about NMT state change, - // so that it can clear the asynchonous queues and start the reduced cycle - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkStartReducedCycle; - EPL_MEMSET(&Event.m_NetTime, 0x00, - sizeof(Event.m_NetTime)); - Event.m_pArg = NULL; - Event.m_uiSize = 0; - Ret = EplEventuPost(&Event); - if (Ret != kEplSuccessful) { - break; - } - // reset all nodes - // d.k.: skip this step if was just done before, e.g. because of a ResetNode command from a diagnostic node - if (NmtStateChange_p.m_NmtEvent == - kEplNmtEventTimerMsPreOp1) { - BENCHMARK_MOD_07_TOGGLE(9); - - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, - EPL_C_ADR_BROADCAST, - kEplNmtCmdResetNode); - - Ret = - EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST, - kEplNmtCmdResetNode); - if (Ret != kEplSuccessful) { - break; - } - } - // start network scan - Ret = EplNmtMnuStartBootStep1(); - - // start timer for 0x1F89/2 MNTimeoutPreOp1_U32 - ObdSize = sizeof(dwTimeout); - Ret = EplObduReadEntry(0x1F89, 2, &dwTimeout, &ObdSize); - if (Ret != kEplSuccessful) { - break; - } - if (dwTimeout != 0L) { - dwTimeout /= 1000L; - if (dwTimeout == 0L) { - dwTimeout = 1L; // at least 1 ms - } - TimerArg.m_EventSink = kEplEventSinkNmtMnu; - TimerArg.m_ulArg = 0; - Ret = - EplTimeruModifyTimerMs(&EplNmtMnuInstance_g. - m_TimerHdlNmtState, - dwTimeout, TimerArg); - } - break; - } - - // node processes isochronous and asynchronous frames - case kEplNmtMsPreOperational2: - { - // add identified CNs to isochronous phase - // send EnableReadyToOp to all identified CNs - Ret = EplNmtMnuStartBootStep2(); - - // wait for NMT state change of CNs - break; - } - - // node should be configured und application is ready - case kEplNmtMsReadyToOperate: - { - // check if PRes of CNs are OK - // d.k. that means wait CycleLength * MultiplexCycleCount (i.e. start timer) - // because Dllk checks PRes of CNs automatically in ReadyToOp - Ret = EplNmtMnuStartCheckCom(); - break; - } - - // normal work state - case kEplNmtMsOperational: - { - // send StartNode to CNs - // wait for NMT state change of CNs - Ret = EplNmtMnuStartNodes(); - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtMsBasicEthernet: - { - break; - } - - default: - { -// TRACE0("EplNmtMnuCbNmtStateChange(): unhandled NMT state\n"); - } - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCbCheckEvent -// -// Description: callback funktion for NMT events before they are actually executed. -// The EPL API layer must forward NMT events from NmtCnu module. -// This module will reject some NMT commands while MN. -// -// Parameters: NmtEvent_p = outstanding NMT event for approval -// -// Returns: tEplKernel = error code -// kEplReject = reject the NMT event -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuProcessEvent -// -// Description: processes events from event queue -// -// Parameters: pEvent_p = pointer to event -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // process event - switch (pEvent_p->m_EventType) { - // timer event - case kEplEventTypeTimer: - { - tEplTimerEventArg *pTimerEventArg = - (tEplTimerEventArg *) pEvent_p->m_pArg; - unsigned int uiNodeId; - - uiNodeId = - (unsigned int)(pTimerEventArg-> - m_ulArg & - EPL_NMTMNU_TIMERARG_NODE_MASK); - if (uiNodeId != 0) { - tEplObdSize ObdSize; - u8 bNmtState; - tEplNmtMnuNodeInfo *pNodeInfo; - - pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId); - - ObdSize = 1; - Ret = - EplObduReadEntry(0x1F8E, uiNodeId, - &bNmtState, &ObdSize); - if (Ret != kEplSuccessful) { - break; - } - - if ((pTimerEventArg-> - m_ulArg & EPL_NMTMNU_TIMERARG_IDENTREQ) != - 0L) { - if ((pNodeInfo-> - m_wFlags & - EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) - != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer - // but not the current timer - // so discard it - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventTimerIdentReq, - uiNodeId, - ((pNodeInfo-> - m_NodeState << 8) - | 0xFF)); - - break; - } -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq, - uiNodeId, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6) - | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8))); -*/ - Ret = - EplNmtMnuProcessInternalEvent - (uiNodeId, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - EPL_E_NO_ERROR, - kEplNmtMnuIntNodeEventTimerIdentReq); - } - - else if ((pTimerEventArg-> - m_ulArg & EPL_NMTMNU_TIMERARG_STATREQ) - != 0L) { - if ((pNodeInfo-> - m_wFlags & - EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) - != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer - // but not the current timer - // so discard it - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventTimerStatReq, - uiNodeId, - ((pNodeInfo-> - m_NodeState << 8) - | 0xFF)); - - break; - } -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq, - uiNodeId, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6) - | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8))); -*/ - Ret = - EplNmtMnuProcessInternalEvent - (uiNodeId, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - EPL_E_NO_ERROR, - kEplNmtMnuIntNodeEventTimerStatReq); - } - - else if ((pTimerEventArg-> - m_ulArg & - EPL_NMTMNU_TIMERARG_STATE_MON) != - 0L) { - if ((pNodeInfo-> - m_wFlags & - EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) - != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer - // but not the current timer - // so discard it - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventTimerStateMon, - uiNodeId, - ((pNodeInfo-> - m_NodeState << 8) - | 0xFF)); - - break; - } -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq, - uiNodeId, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6) - | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8))); -*/ - Ret = - EplNmtMnuProcessInternalEvent - (uiNodeId, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - EPL_E_NO_ERROR, - kEplNmtMnuIntNodeEventTimerStateMon); - } - - else if ((pTimerEventArg-> - m_ulArg & EPL_NMTMNU_TIMERARG_LONGER) - != 0L) { - if ((pNodeInfo-> - m_wFlags & - EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) - != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO)) { // this is an old (already deleted or modified) timer - // but not the current timer - // so discard it - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventTimerLonger, - uiNodeId, - ((pNodeInfo-> - m_NodeState << 8) - | 0xFF)); - - break; - } -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger, - uiNodeId, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) >> 6) - | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO) >> 8))); -*/ - Ret = - EplNmtMnuProcessInternalEvent - (uiNodeId, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - EPL_E_NO_ERROR, - kEplNmtMnuIntNodeEventTimerLonger); - } - - } else { // global timer event - } - break; - } - - case kEplEventTypeHeartbeat: - { - tEplHeartbeatEvent *pHeartbeatEvent = - (tEplHeartbeatEvent *) pEvent_p->m_pArg; - - Ret = - EplNmtMnuProcessInternalEvent(pHeartbeatEvent-> - m_uiNodeId, - pHeartbeatEvent-> - m_NmtState, - pHeartbeatEvent-> - m_wErrorCode, - kEplNmtMnuIntNodeEventHeartbeat); - break; - } - - case kEplEventTypeNmtMnuNmtCmdSent: - { - tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg; - unsigned int uiNodeId; - tEplNmtCommand NmtCommand; - u8 bNmtState; - - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId); - NmtCommand = - (tEplNmtCommand) AmiGetByteFromLe(&pFrame->m_Data. - m_Asnd.m_Payload. - m_NmtCommandService. - m_le_bNmtCommandId); - - switch (NmtCommand) { - case kEplNmtCmdStartNode: - bNmtState = - (u8) (kEplNmtCsOperational & 0xFF); - break; - - case kEplNmtCmdStopNode: - bNmtState = (u8) (kEplNmtCsStopped & 0xFF); - break; - - case kEplNmtCmdEnterPreOperational2: - bNmtState = - (u8) (kEplNmtCsPreOperational2 & 0xFF); - break; - - case kEplNmtCmdEnableReadyToOperate: - // d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command - // and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE - bNmtState = - (u8) (kEplNmtCsPreOperational2 & 0xFF); - break; - - case kEplNmtCmdResetNode: - case kEplNmtCmdResetCommunication: - case kEplNmtCmdResetConfiguration: - case kEplNmtCmdSwReset: - bNmtState = (u8) (kEplNmtCsNotActive & 0xFF); - // EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown - // after next unresponded IdentRequest/StatusRequest - break; - - default: - goto Exit; - } - - // process as internal event which update expected NMT state in OD - if (uiNodeId != EPL_C_ADR_BROADCAST) { - Ret = EplNmtMnuProcessInternalEvent(uiNodeId, - (tEplNmtState) - (bNmtState | - EPL_NMT_TYPE_CS), - 0, - kEplNmtMnuIntNodeEventNmtCmdSent); - - } else { // process internal event for all active nodes (except myself) - - for (uiNodeId = 1; - uiNodeId <= - tabentries(EplNmtMnuInstance_g. - m_aNodeInfo); uiNodeId++) { - if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId)-> - m_dwNodeCfg & - (EPL_NODEASSIGN_NODE_IS_CN | - EPL_NODEASSIGN_NODE_EXISTS)) != - 0) { - Ret = - EplNmtMnuProcessInternalEvent - (uiNodeId, - (tEplNmtState) (bNmtState | - EPL_NMT_TYPE_CS), - 0, - kEplNmtMnuIntNodeEventNmtCmdSent); - - if (Ret != kEplSuccessful) { - goto Exit; - } - } - } - } - - break; - } - - default: - { - Ret = kEplNmtInvalidEvent; - } - - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuGetRunningTimerStatReq -// -// Description: returns a bit field with running StatReq timers -// just for debugging purposes -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int *puiMandatorySlaveCount_p, - unsigned int *puiSignalSlaveCount_p, - u16 *pwFlags_p) -{ - tEplKernel Ret = kEplSuccessful; - - if ((puiMandatorySlaveCount_p == NULL) - || (puiSignalSlaveCount_p == NULL) - || (pwFlags_p == NULL)) { - Ret = kEplNmtInvalidParam; - goto Exit; - } - - *puiMandatorySlaveCount_p = EplNmtMnuInstance_g.m_uiMandatorySlaveCount; - *puiSignalSlaveCount_p = EplNmtMnuInstance_g.m_uiSignalSlaveCount; - *pwFlags_p = EplNmtMnuInstance_g.m_wFlags; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuGetRunningTimerStatReq -// -// Description: returns a bit field with running StatReq timers -// just for debugging purposes -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- -/* -u32 EplNmtMnuGetRunningTimerStatReq(void) -{ -tEplKernel Ret = kEplSuccessful; -unsigned int uiIndex; -tEplNmtMnuNodeInfo* pNodeInfo; - - pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo; - for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++) - { - if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured) - { - // reset flag "scanned once" - pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_SCANNED; - - Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo); - if (Ret != kEplSuccessful) - { - goto Exit; - } - EplNmtMnuInstance_g.m_uiSignalSlaveCount++; - // signal slave counter shall be decremented if StatusRequest was sent once to a CN - // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp - } - } - -Exit: - return Ret; -} -*/ - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCbNmtRequest -// -// Description: callback funktion for NmtRequest -// -// Parameters: pFrameInfo_p = Frame with the NmtRequest -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - - // $$$ perform NMTRequest - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCbIdentResponse -// -// Description: callback funktion for IdentResponse -// -// Parameters: uiNodeId_p = node ID for which IdentReponse was received -// pIdentResponse_p = pointer to IdentResponse -// is NULL if node did not answer -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p, - tEplIdentResponse *pIdentResponse_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (pIdentResponse_p == NULL) { // node did not answer - Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_IDENT_RES, // was EPL_E_NO_ERROR - kEplNmtMnuIntNodeEventNoIdentResponse); - } else { // node answered IdentRequest - tEplObdSize ObdSize; - u32 dwDevType; - u16 wErrorCode = EPL_E_NO_ERROR; - tEplNmtState NmtState = - (tEplNmtState) (AmiGetByteFromLe - (&pIdentResponse_p-> - m_le_bNmtStatus) | EPL_NMT_TYPE_CS); - - // check IdentResponse $$$ move to ProcessIntern, because this function may be called also if CN - - // check DeviceType (0x1F84) - ObdSize = 4; - Ret = - EplObduReadEntry(0x1F84, uiNodeId_p, &dwDevType, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - if (dwDevType != 0L) { // actually compare it with DeviceType from IdentResponse - if (AmiGetDwordFromLe(&pIdentResponse_p->m_le_dwDeviceType) != dwDevType) { // wrong DeviceType - NmtState = kEplNmtCsNotActive; - wErrorCode = EPL_E_NMT_BPO1_DEVICE_TYPE; - } - } - - Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, - NmtState, - wErrorCode, - kEplNmtMnuIntNodeEventIdentResponse); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCbStatusResponse -// -// Description: callback funktion for StatusResponse -// -// Parameters: uiNodeId_p = node ID for which IdentReponse was received -// pIdentResponse_p = pointer to IdentResponse -// is NULL if node did not answer -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p, - tEplStatusResponse *pStatusResponse_p) -{ - tEplKernel Ret = kEplSuccessful; - - if (pStatusResponse_p == NULL) { // node did not answer - Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_STATUS_RES, // was EPL_E_NO_ERROR - kEplNmtMnuIntNodeEventNoStatusResponse); - } else { // node answered StatusRequest - Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, - (tEplNmtState) - (AmiGetByteFromLe - (&pStatusResponse_p-> - m_le_bNmtStatus) | - EPL_NMT_TYPE_CS), - EPL_E_NO_ERROR, - kEplNmtMnuIntNodeEventStatusResponse); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuStartBootStep1 -// -// Description: starts BootStep1 -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuStartBootStep1(void) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiSubIndex; - unsigned int uiLocalNodeId; - u32 dwNodeCfg; - tEplObdSize ObdSize; - - // $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32 - - // start network scan - EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0; - EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0; - // check 0x1F81 - uiLocalNodeId = EplObduGetNodeId(); - for (uiSubIndex = 1; uiSubIndex <= 254; uiSubIndex++) { - ObdSize = 4; - Ret = - EplObduReadEntry(0x1F81, uiSubIndex, &dwNodeCfg, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - if (uiSubIndex != uiLocalNodeId) { - // reset flags "not scanned" and "isochronous" - EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags &= - ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON | - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED); - - if (uiSubIndex == EPL_C_ADR_DIAG_DEF_NODE_ID) { // diagnostic node must be scanned by MN in any case - dwNodeCfg |= - (EPL_NODEASSIGN_NODE_IS_CN | - EPL_NODEASSIGN_NODE_EXISTS); - // and it must be isochronously accessed - dwNodeCfg &= ~EPL_NODEASSIGN_ASYNCONLY_NODE; - } - // save node config in local node info structure - EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_dwNodeCfg = - dwNodeCfg; - EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_NodeState = - kEplNmtMnuNodeStateUnknown; - - if ((dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0) { // node is configured as CN - // identify the node - Ret = - EplIdentuRequestIdentResponse(uiSubIndex, - EplNmtMnuCbIdentResponse); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set flag "not scanned" - EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags |= - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - EplNmtMnuInstance_g.m_uiSignalSlaveCount++; - // signal slave counter shall be decremented if IdentRequest was sent once to a CN - - if ((dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount++; - // mandatory slave counter shall be decremented if mandatory CN was configured successfully - } - } - } else { // subindex of MN - if ((dwNodeCfg & (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS)) != 0) { // MN shall send PRes - tEplDllNodeInfo DllNodeInfo; - - EPL_MEMSET(&DllNodeInfo, 0, - sizeof(DllNodeInfo)); - DllNodeInfo.m_uiNodeId = uiLocalNodeId; - - Ret = EplDlluCalAddNode(&DllNodeInfo); - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuStartBootStep2 -// -// Description: starts BootStep2. -// That means add nodes to isochronous phase and send -// NMT EnableReadyToOp. -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuStartBootStep2(void) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEplNmtMnuNodeInfo *pNodeInfo; - - if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted - // add nodes to isochronous phase and send NMT EnableReadyToOp - EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0; - EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0; - // reset flag that application was informed about possible state change - EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED; - - pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo; - for (uiIndex = 1; - uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); - uiIndex++, pNodeInfo++) { - if (pNodeInfo->m_NodeState == - kEplNmtMnuNodeStateConfigured) { - Ret = - EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set flag "not scanned" - pNodeInfo->m_wFlags |= - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - - EplNmtMnuInstance_g.m_uiSignalSlaveCount++; - // signal slave counter shall be decremented if StatusRequest was sent once to a CN - - if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount++; - } - // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuNodeBootStep2 -// -// Description: starts BootStep2 for the specified node. -// This means the CN is added to isochronous phase if not -// async-only and it gets the NMT command EnableReadyToOp. -// The CN must be in node state Configured, when it enters -// BootStep2. When BootStep2 finishes, the CN is in node state -// ReadyToOp. -// If TimeoutReadyToOp in object 0x1F89/5 is configured, -// TimerHdlLonger will be started with this timeout. -// -// Parameters: uiNodeId_p = node ID -// pNodeInfo_p = pointer to internal node info structure -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplDllNodeInfo DllNodeInfo; - u32 dwNodeCfg; - tEplObdSize ObdSize; - tEplTimerArg TimerArg; - - dwNodeCfg = pNodeInfo_p->m_dwNodeCfg; - if ((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0) { // add node to isochronous phase - DllNodeInfo.m_uiNodeId = uiNodeId_p; - ObdSize = 4; - Ret = - EplObduReadEntry(0x1F92, uiNodeId_p, - &DllNodeInfo.m_dwPresTimeout, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - ObdSize = 2; - Ret = - EplObduReadEntry(0x1F8B, uiNodeId_p, - &DllNodeInfo.m_wPreqPayloadLimit, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - ObdSize = 2; - Ret = - EplObduReadEntry(0x1F8D, uiNodeId_p, - &DllNodeInfo.m_wPresPayloadLimit, - &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - pNodeInfo_p->m_wFlags |= EPL_NMTMNU_NODE_FLAG_ISOCHRON; - - Ret = EplDlluCalAddNode(&DllNodeInfo); - if (Ret != kEplSuccessful) { - goto Exit; - } - - } - - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, - uiNodeId_p, - kEplNmtCmdEnableReadyToOperate); - - Ret = - EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdEnableReadyToOperate); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if (EplNmtMnuInstance_g.m_ulTimeoutReadyToOp != 0L) { // start timer - // when the timer expires the CN must be ReadyToOp - EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, - TimerArg); -// TimerArg.m_EventSink = kEplEventSinkNmtMnu; -// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p; - Ret = - EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger, - EplNmtMnuInstance_g. - m_ulTimeoutReadyToOp, TimerArg); - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuStartCheckCom -// -// Description: starts CheckCommunication -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuStartCheckCom(void) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEplNmtMnuNodeInfo *pNodeInfo; - - if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted - // wait some time and check that no communication error occurs - EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0; - EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0; - // reset flag that application was informed about possible state change - EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED; - - pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo; - for (uiIndex = 1; - uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); - uiIndex++, pNodeInfo++) { - if (pNodeInfo->m_NodeState == - kEplNmtMnuNodeStateReadyToOp) { - Ret = EplNmtMnuNodeCheckCom(uiIndex, pNodeInfo); - if (Ret == kEplReject) { // timer was started - // wait until it expires - if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount++; - } - } else if (Ret != kEplSuccessful) { - goto Exit; - } - // set flag "not scanned" - pNodeInfo->m_wFlags |= - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - - EplNmtMnuInstance_g.m_uiSignalSlaveCount++; - // signal slave counter shall be decremented if timeout elapsed and regardless of an error - // mandatory slave counter shall be decremented if timeout elapsed and no error occured - } - } - } - - Ret = kEplSuccessful; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuNodeCheckCom -// -// Description: checks communication of the specified node. -// That means wait some time and if no error occured everything -// is OK. -// -// Parameters: uiNodeId_p = node ID -// pNodeInfo_p = pointer to internal node info structure -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 dwNodeCfg; - tEplTimerArg TimerArg; - - dwNodeCfg = pNodeInfo_p->m_dwNodeCfg; - if (((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0) - && (EplNmtMnuInstance_g.m_ulTimeoutCheckCom != 0L)) { // CN is not async-only and timeout for CheckCom was set - - // check communication, - // that means wait some time and if no error occured everything is OK; - - // start timer (when the timer expires the CN must be still ReadyToOp) - EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, - TimerArg); -// TimerArg.m_EventSink = kEplEventSinkNmtMnu; -// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p; - Ret = - EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger, - EplNmtMnuInstance_g. - m_ulTimeoutCheckCom, TimerArg); - - // update mandatory slave counter, because timer was started - if (Ret == kEplSuccessful) { - Ret = kEplReject; - } - } else { // timer was not started - // assume everything is OK - pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateComChecked; - } - -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuStartNodes -// -// Description: really starts all nodes which are ReadyToOp and CheckCom did not fail -// -// Parameters: (none) -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuStartNodes(void) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEplNmtMnuNodeInfo *pNodeInfo; - - if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted - // send NMT command Start Node - EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0; - EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0; - // reset flag that application was informed about possible state change - EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED; - - pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo; - for (uiIndex = 1; - uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); - uiIndex++, pNodeInfo++) { - if (pNodeInfo->m_NodeState == - kEplNmtMnuNodeStateComChecked) { - if ((EplNmtMnuInstance_g. - m_dwNmtStartup & EPL_NMTST_STARTALLNODES) - == 0) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, - uiIndex, - kEplNmtCmdStartNode); - - Ret = - EplNmtMnuSendNmtCommand(uiIndex, - kEplNmtCmdStartNode); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - - if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount++; - } - // set flag "not scanned" - pNodeInfo->m_wFlags |= - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - - EplNmtMnuInstance_g.m_uiSignalSlaveCount++; - // signal slave counter shall be decremented if StatusRequest was sent once to a CN - // mandatory slave counter shall be decremented if mandatory CN is OPERATIONAL - } - } - - // $$$ inform application if EPL_NMTST_NO_STARTNODE is set - - if ((EplNmtMnuInstance_g. - m_dwNmtStartup & EPL_NMTST_STARTALLNODES) != 0) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, EPL_C_ADR_BROADCAST, - kEplNmtCmdStartNode); - - Ret = - EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST, - kEplNmtCmdStartNode); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuProcessInternalEvent -// -// Description: processes internal node events -// -// Parameters: uiNodeId_p = node ID -// NodeNmtState_p = NMT state of CN -// NodeEvent_p = occured events -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p, - tEplNmtState NodeNmtState_p, - u16 wErrorCode_p, - tEplNmtMnuIntNodeEvent - NodeEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplNmtState NmtState; - tEplNmtMnuNodeInfo *pNodeInfo; - tEplTimerArg TimerArg; - - pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId_p); - NmtState = EplNmtuGetNmtState(); - if (NmtState <= kEplNmtMsNotActive) { // MN is not active - goto Exit; - } - - switch (NodeEvent_p) { - case kEplNmtMnuIntNodeEventIdentResponse: - { - u8 bNmtState; - - EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p, - uiNodeId_p, - pNodeInfo->m_NodeState); - - if (pNodeInfo->m_NodeState != - kEplNmtMnuNodeStateResetConf) { - pNodeInfo->m_NodeState = - kEplNmtMnuNodeStateIdentified; - } - // reset flags ISOCHRON and NMT_CMD_ISSUED - pNodeInfo->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON - | - EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED); - - if ((NmtState == kEplNmtMsPreOperational1) - && - ((pNodeInfo-> - m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != - 0)) { - // decrement only signal slave count - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } - // update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2) - bNmtState = (u8) (kEplNmtCsPreOperational1 & 0xFF); - Ret = - EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, - 1); - - // check NMT state of CN - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, - NodeNmtState_p, wErrorCode_p, - NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - // request StatusResponse immediately, - // because we want a fast boot-up of CNs - Ret = - EplStatusuRequestStatusResponse(uiNodeId_p, - EplNmtMnuCbStatusResponse); - if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p, - uiNodeId_p, - Ret); - - if (Ret == kEplInvalidOperation) { // the only situation when this should happen is, when - // StatusResponse was already requested from within - // the StatReq timer event. - // so ignore this error. - Ret = kEplSuccessful; - } else { - break; - } - } - - if (pNodeInfo->m_NodeState != - kEplNmtMnuNodeStateResetConf) { - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbNodeEvent(uiNodeId_p, - kEplNmtNodeEventFound, - NodeNmtState_p, - EPL_E_NO_ERROR, - (pNodeInfo-> - m_dwNodeCfg & - EPL_NODEASSIGN_MANDATORY_CN) - != 0); - if (Ret == kEplReject) { // interrupt boot process on user request - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (NodeEvent_p, uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | Ret)); - - Ret = kEplSuccessful; - break; - } else if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (NodeEvent_p, uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | Ret)); - - break; - } - } - // continue BootStep1 - } - - case kEplNmtMnuIntNodeEventBoot: - { - - // $$$ check identification (vendor ID, product code, revision no, serial no) - - if (pNodeInfo->m_NodeState == - kEplNmtMnuNodeStateIdentified) { - // $$$ check software - - // check/start configuration - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbNodeEvent(uiNodeId_p, - kEplNmtNodeEventCheckConf, - NodeNmtState_p, - EPL_E_NO_ERROR, - (pNodeInfo-> - m_dwNodeCfg & - EPL_NODEASSIGN_MANDATORY_CN) - != 0); - if (Ret == kEplReject) { // interrupt boot process on user request - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventBoot, - uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | Ret)); - - Ret = kEplSuccessful; - break; - } else if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (kEplNmtMnuIntNodeEventBoot, - uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | Ret)); - - break; - } - } else if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf) { // wrong CN state - // ignore event - break; - } - // $$$ d.k.: currently we assume configuration is OK - - // continue BootStep1 - } - - case kEplNmtMnuIntNodeEventConfigured: - { - if ((pNodeInfo->m_NodeState != - kEplNmtMnuNodeStateIdentified) - && (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)) { // wrong CN state - // ignore event - break; - } - - pNodeInfo->m_NodeState = kEplNmtMnuNodeStateConfigured; - - if (NmtState == kEplNmtMsPreOperational1) { - if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // decrement mandatory CN counter - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount--; - } - } else { - // put optional node to next step (BootStep2) - Ret = - EplNmtMnuNodeBootStep2(uiNodeId_p, - pNodeInfo); - } - break; - } - - case kEplNmtMnuIntNodeEventNoIdentResponse: - { - if ((NmtState == kEplNmtMsPreOperational1) - && - ((pNodeInfo-> - m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != - 0)) { - // decrement only signal slave count - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } - - if (pNodeInfo->m_NodeState != - kEplNmtMnuNodeStateResetConf) { - pNodeInfo->m_NodeState = - kEplNmtMnuNodeStateUnknown; - } - // $$$ d.k. check start time for 0x1F89/2 MNTimeoutPreOp1_U32 - // $$$ d.k. check individual timeout 0x1F89/6 MNIdentificationTimeout_U32 - // if mandatory node and timeout elapsed -> halt boot procedure - // trigger IdentRequest again (if >= PreOp2, after delay) - if (NmtState >= kEplNmtMsPreOperational2) { // start timer - EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ - (pNodeInfo, uiNodeId_p, TimerArg); -// TimerArg.m_EventSink = kEplEventSinkNmtMnu; -// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p; -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventNoIdentResponse, - uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6) - | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8))); -*/ - Ret = - EplTimeruModifyTimerMs(&pNodeInfo-> - m_TimerHdlStatReq, - EplNmtMnuInstance_g. - m_ulStatusRequestDelay, - TimerArg); - } else { // trigger IdentRequest immediately - Ret = - EplIdentuRequestIdentResponse(uiNodeId_p, - EplNmtMnuCbIdentResponse); - } - break; - } - - case kEplNmtMnuIntNodeEventStatusResponse: - { - if ((NmtState >= kEplNmtMsPreOperational2) - && - ((pNodeInfo-> - m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != - 0)) { - // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } - // check NMT state of CN - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, - NodeNmtState_p, wErrorCode_p, - NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - - if (NmtState == kEplNmtMsPreOperational1) { - // request next StatusResponse immediately - Ret = - EplStatusuRequestStatusResponse(uiNodeId_p, - EplNmtMnuCbStatusResponse); - if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (NodeEvent_p, uiNodeId_p, Ret); - } - - } else if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_ISOCHRON) == 0) { // start timer - // not isochronously accessed CN (e.g. async-only or stopped CN) - EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo, - uiNodeId_p, - TimerArg); -// TimerArg.m_EventSink = kEplEventSinkNmtMnu; -// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p; -/* - EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventStatusResponse, - uiNodeId_p, - ((pNodeInfo->m_NodeState << 8) - | 0x80 - | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6) - | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8))); -*/ - Ret = - EplTimeruModifyTimerMs(&pNodeInfo-> - m_TimerHdlStatReq, - EplNmtMnuInstance_g. - m_ulStatusRequestDelay, - TimerArg); - } - - break; - } - - case kEplNmtMnuIntNodeEventNoStatusResponse: - { - // function CheckNmtState sets node state to unknown if necessary -/* - if ((NmtState >= kEplNmtMsPreOperational2) - && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0)) - { - // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } -*/ - // check NMT state of CN - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, - NodeNmtState_p, wErrorCode_p, - NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - - break; - } - - case kEplNmtMnuIntNodeEventError: - { // currently only issued on kEplNmtNodeCommandConfErr - - if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) { // wrong CN state - // ignore event - break; - } - // check NMT state of CN - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, - kEplNmtCsNotActive, - wErrorCode_p, NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - - break; - } - - case kEplNmtMnuIntNodeEventExecReset: - { - if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) { // wrong CN state - // ignore event - break; - } - - pNodeInfo->m_NodeState = kEplNmtMnuNodeStateResetConf; - - EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p, - uiNodeId_p, - (((NodeNmtState_p & - 0xFF) << 8) - | - kEplNmtCmdResetConfiguration)); - - // send NMT reset configuration to CN for activation of configuration - Ret = - EplNmtMnuSendNmtCommand(uiNodeId_p, - kEplNmtCmdResetConfiguration); - - break; - } - - case kEplNmtMnuIntNodeEventHeartbeat: - { -/* - if ((NmtState >= kEplNmtMsPreOperational2) - && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0)) - { - // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } -*/ - // check NMT state of CN - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, - NodeNmtState_p, wErrorCode_p, - NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - - break; - } - - case kEplNmtMnuIntNodeEventTimerIdentReq: - { - EPL_DBGLVL_NMTMN_TRACE1 - ("TimerStatReq->IdentReq(%02X)\n", uiNodeId_p); - // trigger IdentRequest again - Ret = - EplIdentuRequestIdentResponse(uiNodeId_p, - EplNmtMnuCbIdentResponse); - if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p, - uiNodeId_p, - (((NodeNmtState_p & 0xFF) << 8) - | Ret)); - if (Ret == kEplInvalidOperation) { // this can happen because of a bug in EplTimeruLinuxKernel.c - // so ignore this error. - Ret = kEplSuccessful; - } - } - - break; - } - - case kEplNmtMnuIntNodeEventTimerStateMon: - { - // reset NMT state change flag - // because from now on the CN must have the correct NMT state - pNodeInfo->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED; - - // continue with normal StatReq processing - } - - case kEplNmtMnuIntNodeEventTimerStatReq: - { - EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->StatReq(%02X)\n", - uiNodeId_p); - // request next StatusResponse - Ret = - EplStatusuRequestStatusResponse(uiNodeId_p, - EplNmtMnuCbStatusResponse); - if (Ret != kEplSuccessful) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p, - uiNodeId_p, - (((NodeNmtState_p & 0xFF) << 8) - | Ret)); - if (Ret == kEplInvalidOperation) { // the only situation when this should happen is, when - // StatusResponse was already requested while processing - // event IdentResponse. - // so ignore this error. - Ret = kEplSuccessful; - } - } - - break; - } - - case kEplNmtMnuIntNodeEventTimerLonger: - { - switch (pNodeInfo->m_NodeState) { - case kEplNmtMnuNodeStateConfigured: - { // node should be ReadyToOp but it is not - - // check NMT state which shall be intentionally wrong, so that ERROR_TREATMENT will be started - Ret = - EplNmtMnuCheckNmtState(uiNodeId_p, - pNodeInfo, - kEplNmtCsNotActive, - EPL_E_NMT_BPO2, - NmtState); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - Ret = kEplSuccessful; - } - break; - } - - break; - } - - case kEplNmtMnuNodeStateReadyToOp: - { // CheckCom finished successfully - - pNodeInfo->m_NodeState = - kEplNmtMnuNodeStateComChecked; - - if ((pNodeInfo-> - m_wFlags & - EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) - != 0) { - // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational - EplNmtMnuInstance_g. - m_uiSignalSlaveCount--; - pNodeInfo->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } - - if ((pNodeInfo-> - m_dwNodeCfg & - EPL_NODEASSIGN_MANDATORY_CN) != - 0) { - // decrement mandatory slave counter - EplNmtMnuInstance_g. - m_uiMandatorySlaveCount--; - } - if (NmtState != kEplNmtMsReadyToOperate) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE - (NodeEvent_p, uiNodeId_p, - (((NodeNmtState_p & 0xFF) - << 8) - | kEplNmtCmdStartNode)); - - // start optional CN - Ret = - EplNmtMnuSendNmtCommand - (uiNodeId_p, - kEplNmtCmdStartNode); - } - break; - } - - default: - { - break; - } - } - break; - } - - case kEplNmtMnuIntNodeEventNmtCmdSent: - { - u8 bNmtState; - - // update expected NMT state with the one that results - // from the sent NMT command - bNmtState = (u8) (NodeNmtState_p & 0xFF); - - // write object 0x1F8F NMT_MNNodeExpState_AU8 - Ret = - EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, - 1); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if (NodeNmtState_p == kEplNmtCsNotActive) { // restart processing with IdentRequest - EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ - (pNodeInfo, uiNodeId_p, TimerArg); - } else { // monitor NMT state change with StatusRequest after - // the corresponding delay; - // until then wrong NMT states will be ignored - EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON - (pNodeInfo, uiNodeId_p, TimerArg); - - // set NMT state change flag - pNodeInfo->m_wFlags |= - EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED; - } - - Ret = - EplTimeruModifyTimerMs(&pNodeInfo-> - m_TimerHdlStatReq, - EplNmtMnuInstance_g. - m_ulStatusRequestDelay, - TimerArg); - - // finish processing, because NmtState_p is the expected and not the current state - goto Exit; - } - - default: - { - break; - } - } - - // check if network is ready to change local NMT state and this was not done before - if ((EplNmtMnuInstance_g.m_wFlags & (EPL_NMTMNU_FLAG_HALTED | EPL_NMTMNU_FLAG_APP_INFORMED)) == 0) { // boot process is not halted - switch (NmtState) { - case kEplNmtMsPreOperational1: - { - if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == - 0) - && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs scanned once and all mandatory CNs configured successfully - EplNmtMnuInstance_g.m_wFlags |= - EPL_NMTMNU_FLAG_APP_INFORMED; - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbBootEvent - (kEplNmtBootEventBootStep1Finish, - NmtState, EPL_E_NO_ERROR); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - // wait for application - Ret = kEplSuccessful; - } - break; - } - // enter PreOp2 - Ret = - EplNmtuNmtEvent - (kEplNmtEventAllMandatoryCNIdent); - } - break; - } - - case kEplNmtMsPreOperational2: - { - if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == - 0) - && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs checked once for ReadyToOp and all mandatory CNs are ReadyToOp - EplNmtMnuInstance_g.m_wFlags |= - EPL_NMTMNU_FLAG_APP_INFORMED; - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbBootEvent - (kEplNmtBootEventBootStep2Finish, - NmtState, EPL_E_NO_ERROR); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - // wait for application - Ret = kEplSuccessful; - } - break; - } - // enter ReadyToOp - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterReadyToOperate); - } - break; - } - - case kEplNmtMsReadyToOperate: - { - if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == - 0) - && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all CNs checked for errorless communication - EplNmtMnuInstance_g.m_wFlags |= - EPL_NMTMNU_FLAG_APP_INFORMED; - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbBootEvent - (kEplNmtBootEventCheckComFinish, - NmtState, EPL_E_NO_ERROR); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - // wait for application - Ret = kEplSuccessful; - } - break; - } - // enter Operational - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterMsOperational); - } - break; - } - - case kEplNmtMsOperational: - { - if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == - 0) - && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs scanned once and all mandatory CNs are OPERATIONAL - EplNmtMnuInstance_g.m_wFlags |= - EPL_NMTMNU_FLAG_APP_INFORMED; - // inform application - Ret = - EplNmtMnuInstance_g. - m_pfnCbBootEvent - (kEplNmtBootEventOperational, - NmtState, EPL_E_NO_ERROR); - if (Ret != kEplSuccessful) { - if (Ret == kEplReject) { - // ignore error code - Ret = kEplSuccessful; - } - break; - } - } - break; - } - - default: - { - break; - } - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuCheckNmtState -// -// Description: checks the NMT state, i.e. evaluates it with object 0x1F8F -// NMT_MNNodeExpState_AU8 and updates object 0x1F8E -// NMT_MNNodeCurrState_AU8. -// It manipulates m_NodeState in internal node info structure. -// -// Parameters: uiNodeId_p = node ID -// NodeNmtState_p = NMT state of CN -// -// Returns: tEplKernel = error code -// kEplReject = CN was in wrong state and has been reset -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p, - tEplNmtMnuNodeInfo * pNodeInfo_p, - tEplNmtState NodeNmtState_p, - u16 wErrorCode_p, - tEplNmtState LocalNmtState_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplObdSize ObdSize; - u8 bNmtState; - u8 bNmtStatePrev; - tEplNmtState ExpNmtState; - - ObdSize = 1; - // read object 0x1F8F NMT_MNNodeExpState_AU8 - Ret = EplObduReadEntry(0x1F8F, uiNodeId_p, &bNmtState, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // compute expected NMT state - ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS); - // compute u8 of current NMT state - bNmtState = ((u8) NodeNmtState_p & 0xFF); - - if (ExpNmtState == kEplNmtCsNotActive) { // ignore the current state, because the CN shall be not active - Ret = kEplReject; - goto Exit; - } else if ((ExpNmtState == kEplNmtCsPreOperational2) - && (NodeNmtState_p == kEplNmtCsReadyToOperate)) { // CN switched to ReadyToOp - // delete timer for timeout handling - Ret = EplTimeruDeleteTimer(&pNodeInfo_p->m_TimerHdlLonger); - if (Ret != kEplSuccessful) { - goto Exit; - } - pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateReadyToOp; - - // update object 0x1F8F NMT_MNNodeExpState_AU8 to ReadyToOp - Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN -> decrement counter - EplNmtMnuInstance_g.m_uiMandatorySlaveCount--; - } - if (LocalNmtState_p >= kEplNmtMsReadyToOperate) { // start procedure CheckCommunication for this node - Ret = EplNmtMnuNodeCheckCom(uiNodeId_p, pNodeInfo_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((LocalNmtState_p == kEplNmtMsOperational) - && (pNodeInfo_p->m_NodeState == - kEplNmtMnuNodeStateComChecked)) { - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, uiNodeId_p, - (((NodeNmtState_p & 0xFF) << 8) - | - kEplNmtCmdStartNode)); - - // immediately start optional CN, because communication is always OK (e.g. async-only CN) - Ret = - EplNmtMnuSendNmtCommand(uiNodeId_p, - kEplNmtCmdStartNode); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - } - - } else if ((ExpNmtState == kEplNmtCsReadyToOperate) - && (NodeNmtState_p == kEplNmtCsOperational)) { // CN switched to OPERATIONAL - pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateOperational; - - if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN -> decrement counter - EplNmtMnuInstance_g.m_uiMandatorySlaveCount--; - } - - } else if ((ExpNmtState != NodeNmtState_p) - && !((ExpNmtState == kEplNmtCsPreOperational1) - && (NodeNmtState_p == kEplNmtCsPreOperational2))) { // CN is not in expected NMT state (without the exceptions above) - u16 wbeErrorCode; - - if ((pNodeInfo_p-> - m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) { - // decrement only signal slave count if checked once - EplNmtMnuInstance_g.m_uiSignalSlaveCount--; - pNodeInfo_p->m_wFlags &= - ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED; - } - - if (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateUnknown) { // CN is already in state unknown, which means that it got - // NMT reset command earlier - goto Exit; - } - // -> CN is in wrong NMT state - pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateUnknown; - - if (wErrorCode_p == 0) { // assume wrong NMT state error - if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED) != 0) { // NMT command has been just issued; - // ignore wrong NMT state until timer expires; - // other errors like LOSS_PRES_TH are still processed - goto Exit; - } - - wErrorCode_p = EPL_E_NMT_WRONG_STATE; - } - - BENCHMARK_MOD_07_TOGGLE(9); - - // $$$ start ERROR_TREATMENT and inform application - Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p, - kEplNmtNodeEventError, - NodeNmtState_p, - wErrorCode_p, - (pNodeInfo_p-> - m_dwNodeCfg & - EPL_NODEASSIGN_MANDATORY_CN) - != 0); - if (Ret != kEplSuccessful) { - goto Exit; - } - - EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, - uiNodeId_p, - (((NodeNmtState_p & 0xFF) << 8) - | kEplNmtCmdResetNode)); - - // reset CN - // store error code in NMT command data for diagnostic purpose - AmiSetWordToLe(&wbeErrorCode, wErrorCode_p); - Ret = - EplNmtMnuSendNmtCommandEx(uiNodeId_p, kEplNmtCmdResetNode, - &wbeErrorCode, - sizeof(wbeErrorCode)); - if (Ret == kEplSuccessful) { - Ret = kEplReject; - } - - goto Exit; - } - // check if NMT_MNNodeCurrState_AU8 has to be changed - ObdSize = 1; - Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtStatePrev, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - if (bNmtState != bNmtStatePrev) { - // update object 0x1F8E NMT_MNNodeCurrState_AU8 - Ret = EplObduWriteEntry(0x1F8E, uiNodeId_p, &bNmtState, 1); - if (Ret != kEplSuccessful) { - goto Exit; - } - Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p, - kEplNmtNodeEventNmtState, - NodeNmtState_p, - wErrorCode_p, - (pNodeInfo_p-> - m_dwNodeCfg & - EPL_NODEASSIGN_MANDATORY_CN) - != 0); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtMnuReset -// -// Description: reset internal structures, e.g. timers -// -// Parameters: void -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplNmtMnuReset(void) -{ - tEplKernel Ret; - int iIndex; - - Ret = EplTimeruDeleteTimer(&EplNmtMnuInstance_g.m_TimerHdlNmtState); - - for (iIndex = 1; iIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); - iIndex++) { - // delete timer handles - Ret = - EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)-> - m_TimerHdlStatReq); - Ret = - EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)-> - m_TimerHdlLonger); - } - - return Ret; -} - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c deleted file mode 100644 index 609d5c02bde..00000000000 --- a/drivers/staging/epl/EplNmtk.c +++ /dev/null @@ -1,1840 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for NMT-Kernelspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtk.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.12 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#include "kernel/EplNmtk.h" -#include "kernel/EplTimerk.h" - -#include "kernel/EplDllk.h" // for EplDllkProcess() - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif -#define EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent_p, OldNmtState_p, NewNmtState_p) \ - TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtk << 28) | (NmtEvent_p << 16) \ - | ((OldNmtState_p & 0xFF) << 8) \ - | (NewNmtState_p & 0xFF)) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- -// struct for instance table -INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER() - -STATIC volatile tEplNmtState m_NmtState; -STATIC volatile BOOL m_fEnableReadyToOperate; -STATIC volatile BOOL m_fAppReadyToOperate; -STATIC volatile BOOL m_fTimerMsPreOp2; -STATIC volatile BOOL m_fAllMandatoryCNIdent; -STATIC volatile BOOL m_fFrozen; - -INSTANCE_TYPE_END -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -// This macro replace the unspecific pointer to an instance through -// the modul specific type for the local instance table. This macro -// must defined in each modul. -//#define tEplPtrInstance tEplInstanceInfo* -EPL_MCO_DECL_INSTANCE_VAR() -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- -EPL_MCO_DEFINE_INSTANCE_FCT() - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: This module realize the NMT-State-Machine of the EPL-Stack -// -// -/***************************************************************************/ -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// -//--------------------------------------------------------------------------- -// -// Function: EplNmtkInit -// -// Description: initializes the first instance -// -// -// -// Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer -// uiNodeId_p = Node Id of the lokal node -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR) -{ - tEplKernel Ret; - - Ret = EplNmtkAddInstance(EPL_MCO_PTR_INSTANCE_PTR); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtkAddInstance -// -// Description: adds a new instance -// -// -// -// Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR) -{ - EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret; -//tEplEvent Event; -//tEplEventNmtStateChange NmtStateChange; - - // check if pointer to instance pointer valid - // get free instance and set the globale instance pointer - // set also the instance addr to parameterlist - EPL_MCO_CHECK_PTR_INSTANCE_PTR(); - EPL_MCO_GET_FREE_INSTANCE_PTR(); - EPL_MCO_SET_PTR_INSTANCE_PTR(); - - // sign instance as used - EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed); - - Ret = kEplSuccessful; - - // initialize intern vaiables - // 2006/07/31 d.k.: set NMT-State to kEplNmtGsOff - EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; - // set NMT-State to kEplNmtGsInitialising - //EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising; - - // set flags to FALSE - EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE; - EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE; - EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) = FALSE; - EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) = FALSE; - EPL_MCO_GLB_VAR(m_fFrozen) = FALSE; - -// EPL_MCO_GLB_VAR(m_TimerHdl) = 0; - - // inform higher layer about state change - // 2006/07/31 d.k.: The EPL API layer/application has to start NMT state - // machine via NmtEventSwReset after initialisation of - // all modules has been completed. DLL has to be initialised - // after NMTk because NMT state shall not be uninitialised - // at that time. -/* NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState); - NmtStateChange.m_NmtEvent = kEplNmtEventNoEvent; - Event.m_EventSink = kEplEventSinkNmtu; - Event.m_EventType = kEplEventTypeNmtStateChange; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &NmtStateChange; - Event.m_uiSize = sizeof(NmtStateChange); - Ret = EplEventkPost(&Event); -*/ - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtkDelInstance -// -// Description: delete instance -// -// -// -// Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if (EPL_USE_DELETEINST_FUNC != FALSE) -tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR) -{ - tEplKernel Ret = kEplSuccessful; - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - // set NMT-State to kEplNmtGsOff - EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff; - - // sign instance as unused - EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused); - - // delete timer -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - - return Ret; -} -#endif // (EPL_USE_DELETEINST_FUNC != FALSE) - -//--------------------------------------------------------------------------- -// -// Function: EplNmtkProcess -// -// Description: main process function -// -> process NMT-State-Maschine und read NMT-Events from Queue -// -// -// -// Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instance pointer -// pEvent_p = Epl-Event with NMT-event to process -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p) -{ - tEplKernel Ret; - tEplNmtState OldNmtState; - tEplNmtEvent NmtEvent; - tEplEvent Event; - tEplEventNmtStateChange NmtStateChange; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - Ret = kEplSuccessful; - - switch (pEvent_p->m_EventType) { - case kEplEventTypeNmtEvent: - { - NmtEvent = *((tEplNmtEvent *) pEvent_p->m_pArg); - break; - } - - case kEplEventTypeTimer: - { - NmtEvent = - (tEplNmtEvent) ((tEplTimerEventArg *) pEvent_p-> - m_pArg)->m_ulArg; - break; - } - default: - { - Ret = kEplNmtInvalidEvent; - goto Exit; - } - } - - // save NMT-State - // needed for later comparison to - // inform hgher layer about state change - OldNmtState = EPL_MCO_GLB_VAR(m_NmtState); - - // NMT-State-Maschine - switch (EPL_MCO_GLB_VAR(m_NmtState)) { - //----------------------------------------------------------- - // general part of the statemaschine - - // first init of the hardware - case kEplNmtGsOff: - { - // leave this state only if higher layer says so - if (NmtEvent == kEplNmtEventSwReset) { // new state kEplNmtGsInitialising - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - } - break; - } - - // first init of the hardware - case kEplNmtGsInitialising: - { - // leave this state only if higher layer says so - - // check events - switch (NmtEvent) { - // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // new state kEplNmtGsResetApplication - case kEplNmtEventEnterResetApp: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - default: - { - break; - } - } - break; - } - - // init of the manufacturer-specific profile area and the - // standardised device profile area - case kEplNmtGsResetApplication: - { - // check events - switch (NmtEvent) { - // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // leave this state only if higher layer - // say so - case kEplNmtEventEnterResetCom: - { - // new state kEplNmtGsResetCommunication - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - default: - { - break; - } - } - break; - } - - // init of the communication profile area - case kEplNmtGsResetCommunication: - { - // check events - switch (NmtEvent) { - // 2006/07/31 d.k.: react also on NMT reset commands in ResetComm state - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // leave this state only if higher layer - // say so - case kEplNmtEventEnterResetConfig: - { - // new state kEplNmtGsResetCommunication - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - default: - { - break; - } - } - break; - } - - // build the configuration with infos from OD - case kEplNmtGsResetConfiguration: - { - // reset flags - EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE; - EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE; - EPL_MCO_GLB_VAR(m_fFrozen) = FALSE; - - // check events - switch (NmtEvent) { - // 2006/07/31 d.k.: react also on NMT reset commands in ResetConf state - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - case kEplNmtEventResetCom: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // leave this state only if higher layer says so - case kEplNmtEventEnterCsNotActive: - { // Node should be CN - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsNotActive; - break; - - } - - case kEplNmtEventEnterMsNotActive: - { // Node should be CN -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) - // no MN functionality - // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT - EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; -#else - - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsNotActive; -#endif - break; - - } - - default: - { - break; - } - } - break; - } - - //----------------------------------------------------------- - // CN part of the statemaschine - - // node liste for EPL-Frames and check timeout - case kEplNmtCsNotActive: - { - - // check events - switch (NmtEvent) { - // 2006/07/31 d.k.: react also on NMT reset commands in NotActive state - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - break; - } - - // NMT Command Reset Configuration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - break; - } - - // see if SoA or SoC received - // k.t. 20.07.2006: only SoA forces change of state - // see EPL V2 DS 1.0.0 p.267 - // case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // new state PRE_OPERATIONAL1 - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; -// Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl)); - break; - } - // timeout for SoA and Soc - case kEplNmtEventTimerBasicEthernet: - { - // new state BASIC_ETHERNET - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsBasicEthernet; - break; - } - - default: - { - break; - } - } // end of switch(NmtEvent) - - break; - } - - // node processes only async frames - case kEplNmtCsPreOperational1: - { - - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command Reset Configuration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // NMT Command StopNode - case kEplNmtEventStopNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsStopped; - break; - } - - // check if SoC received - case kEplNmtEventDllCeSoc: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational2; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - - break; - } - - // node processes isochronous and asynchronous frames - case kEplNmtCsPreOperational2: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command Reset Configuration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // NMT Command StopNode - case kEplNmtEventStopNode: - { - // reset flags - EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) - = FALSE; - EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = - FALSE; - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsStopped; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - // reset flags - EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) - = FALSE; - EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = - FALSE; - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; - break; - } - - // check if application is ready to operate - case kEplNmtEventEnterReadyToOperate: - { - // check if command NMTEnableReadyToOperate from MN was received - if (EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) == TRUE) { // reset flags - EPL_MCO_GLB_VAR - (m_fEnableReadyToOperate) = - FALSE; - EPL_MCO_GLB_VAR - (m_fAppReadyToOperate) = - FALSE; - // change state - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsReadyToOperate; - } else { // set Flag - EPL_MCO_GLB_VAR - (m_fAppReadyToOperate) = - TRUE; - } - break; - } - - // NMT Commando EnableReadyToOperate - case kEplNmtEventEnableReadyToOperate: - { - // check if application is ready - if (EPL_MCO_GLB_VAR(m_fAppReadyToOperate) == TRUE) { // reset flags - EPL_MCO_GLB_VAR - (m_fEnableReadyToOperate) = - FALSE; - EPL_MCO_GLB_VAR - (m_fAppReadyToOperate) = - FALSE; - // change state - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsReadyToOperate; - } else { // set Flag - EPL_MCO_GLB_VAR - (m_fEnableReadyToOperate) = - TRUE; - } - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // node should be configured und application is ready - case kEplNmtCsReadyToOperate: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // NMT Command StopNode - case kEplNmtEventStopNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsStopped; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; - break; - } - - // NMT Command StartNode - case kEplNmtEventStartNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsOperational; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // normal work state - case kEplNmtCsOperational: - { - - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // NMT Command StopNode - case kEplNmtEventStopNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsStopped; - break; - } - - // NMT Command EnterPreOperational2 - case kEplNmtEventEnterPreOperational2: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational2; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // node stopped by MN - // -> only process asynchronous frames - case kEplNmtCsStopped: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // NMT Command EnterPreOperational2 - case kEplNmtEventEnterPreOperational2: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational2; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // no epl cycle - // -> normal ethernet communication - case kEplNmtCsBasicEthernet: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // error occured - // d.k.: how does this error occur? on CRC errors -/* case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; - break; - } -*/ - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCePreq: - case kEplNmtEventDllCePres: - case kEplNmtEventDllCeSoa: - { // Epl-Frame on net -> stop any communication - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtCsPreOperational1; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - - break; - } - - //----------------------------------------------------------- - // MN part of the statemaschine - - // MN listen to network - // -> if no EPL traffic go to next state - case kEplNmtMsNotActive: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) - // no MN functionality - // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT - EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; -#else - - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_fFrozen) = TRUE; - break; - } - - // timeout event - case kEplNmtEventTimerBasicEthernet: - { - if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) { // new state BasicEthernet - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsBasicEthernet; - } - break; - } - - // timeout event - case kEplNmtEventTimerMsPreOp1: - { - if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) { // new state PreOp1 - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational1; - EPL_MCO_GLB_VAR - (m_fTimerMsPreOp2) = FALSE; - EPL_MCO_GLB_VAR - (m_fAllMandatoryCNIdent) = - FALSE; - - } - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - -#endif // ((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0) - - break; - } -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // MN process reduces epl cycle - case kEplNmtMsPreOperational1: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // error occured - // d.k. MSPreOp1->CSPreOp1: nonsense -> keep state - /* - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; - break; - } - */ - - case kEplNmtEventAllMandatoryCNIdent: - { // all mandatory CN identified - if (EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) != - FALSE) { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational2; - } else { - EPL_MCO_GLB_VAR - (m_fAllMandatoryCNIdent) = - TRUE; - } - break; - } - - case kEplNmtEventTimerMsPreOp2: - { // residence time for PreOp1 is elapsed - if (EPL_MCO_GLB_VAR - (m_fAllMandatoryCNIdent) != FALSE) { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational2; - } else { - EPL_MCO_GLB_VAR - (m_fTimerMsPreOp2) = TRUE; - } - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // MN process full epl cycle - case kEplNmtMsPreOperational2: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational1; - break; - } - - case kEplNmtEventEnterReadyToOperate: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsReadyToOperate; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - - break; - } - - // all madatory nodes ready to operate - // -> MN process full epl cycle - case kEplNmtMsReadyToOperate: - { - - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational1; - break; - } - - case kEplNmtEventEnterMsOperational: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsOperational; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - - break; - } - - // normal eplcycle processing - case kEplNmtMsOperational: - { - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // error occured - case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtMsPreOperational1; - break; - } - - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } - - // normal ethernet traffic - case kEplNmtMsBasicEthernet: - { - - // check events - switch (NmtEvent) { - // NMT Command SwitchOff - case kEplNmtEventCriticalError: - case kEplNmtEventSwitchOff: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsOff; - break; - } - - // NMT Command SwReset - case kEplNmtEventSwReset: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsInitialising; - break; - } - - // NMT Command ResetNode - case kEplNmtEventResetNode: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetApplication; - break; - } - - // NMT Command ResetCommunication - // or internal Communication error - case kEplNmtEventResetCom: - case kEplNmtEventInternComError: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // NMT Command ResetConfiguration - case kEplNmtEventResetConfig: - { - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetConfiguration; - break; - } - - // EPL frames received - case kEplNmtEventDllCeSoc: - case kEplNmtEventDllCeSoa: - { // other MN in network - // $$$ d.k.: generate error history entry - EPL_MCO_GLB_VAR(m_NmtState) = - kEplNmtGsResetCommunication; - break; - } - - // error occured - // d.k. BE->PreOp1 on cycle error? No -/* case kEplNmtEventNmtCycleError: - { - EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1; - break; - } -*/ - default: - { - break; - } - - } // end of switch(NmtEvent) - break; - } -#endif //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - default: - { - //DEBUG_EPL_DBGLVL_NMTK_TRACE0(EPL_DBGLVL_NMT ,"Error in EplNmtProcess: Unknown NMT-State"); - //EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication; - Ret = kEplNmtInvalidState; - goto Exit; - } - - } // end of switch(NmtEvent) - - // inform higher layer about State-Change if needed - if (OldNmtState != EPL_MCO_GLB_VAR(m_NmtState)) { - EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent, OldNmtState, - EPL_MCO_GLB_VAR(m_NmtState)); - - // d.k.: memorize NMT state before posting any events - NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState); - - // inform DLL - if ((OldNmtState > kEplNmtGsResetConfiguration) - && (EPL_MCO_GLB_VAR(m_NmtState) <= - kEplNmtGsResetConfiguration)) { - // send DLL DEINIT - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkDestroy; - EPL_MEMSET(&Event.m_NetTime, 0x00, - sizeof(Event.m_NetTime)); - Event.m_pArg = &OldNmtState; - Event.m_uiSize = sizeof(OldNmtState); - // d.k.: directly call DLLk process function, because - // 1. execution of process function is still synchonized and serialized, - // 2. it is the same as without event queues (i.e. well tested), - // 3. DLLk will get those necessary events even if event queue is full, - // 4. event queue is very inefficient -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkProcess(&Event); -#else - Ret = EplEventkPost(&Event); -#endif - } else if ((OldNmtState <= kEplNmtGsResetConfiguration) - && (EPL_MCO_GLB_VAR(m_NmtState) > - kEplNmtGsResetConfiguration)) { - // send DLL INIT - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkCreate; - EPL_MEMSET(&Event.m_NetTime, 0x00, - sizeof(Event.m_NetTime)); - Event.m_pArg = &NmtStateChange.m_NewNmtState; - Event.m_uiSize = sizeof(NmtStateChange.m_NewNmtState); - // d.k.: directly call DLLk process function, because - // 1. execution of process function is still synchonized and serialized, - // 2. it is the same as without event queues (i.e. well tested), - // 3. DLLk will get those necessary events even if event queue is full - // 4. event queue is very inefficient -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkProcess(&Event); -#else - Ret = EplEventkPost(&Event); -#endif - } else - if ((EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtCsBasicEthernet) - || (EPL_MCO_GLB_VAR(m_NmtState) == - kEplNmtMsBasicEthernet)) { - tEplDllAsyncReqPriority AsyncReqPriority; - - // send DLL Fill Async Tx Buffer, because state BasicEthernet was entered - Event.m_EventSink = kEplEventSinkDllk; - Event.m_EventType = kEplEventTypeDllkFillTx; - EPL_MEMSET(&Event.m_NetTime, 0x00, - sizeof(Event.m_NetTime)); - AsyncReqPriority = kEplDllAsyncReqPrioGeneric; - Event.m_pArg = &AsyncReqPriority; - Event.m_uiSize = sizeof(AsyncReqPriority); - // d.k.: directly call DLLk process function, because - // 1. execution of process function is still synchonized and serialized, - // 2. it is the same as without event queues (i.e. well tested), - // 3. DLLk will get those necessary events even if event queue is full - // 4. event queue is very inefficient -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - Ret = EplDllkProcess(&Event); -#else - Ret = EplEventkPost(&Event); -#endif - } - // inform higher layer about state change - NmtStateChange.m_NmtEvent = NmtEvent; - Event.m_EventSink = kEplEventSinkNmtu; - Event.m_EventType = kEplEventTypeNmtStateChange; - EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime)); - Event.m_pArg = &NmtStateChange; - Event.m_uiSize = sizeof(NmtStateChange); - Ret = EplEventkPost(&Event); - EPL_DBGLVL_NMTK_TRACE2 - ("EplNmtkProcess(NMT-Event = 0x%04X): New NMT-State = 0x%03X\n", - NmtEvent, NmtStateChange.m_NewNmtState); - - } - - Exit: - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtkGetNmtState -// -// Description: return the actuell NMT-State and the bits -// to for MN- or CN-mode -// -// -// -// Parameters: EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instancepointer -// -// -// Returns: tEplNmtState = NMT-State -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR) -{ - tEplNmtState NmtState; - - NmtState = EPL_MCO_GLB_VAR(m_NmtState); - - return NmtState; - -} - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// -EPL_MCO_DECL_INSTANCE_FCT() -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) -// EOF diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c deleted file mode 100644 index 4453c09838c..00000000000 --- a/drivers/staging/epl/EplNmtkCal.c +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for communication abstraction layer of the - NMT-Kernel-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtkCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/16 -k.t.: start of the implementation - -****************************************************************************/ - -// TODO: init function needed to prepare EplNmtkGetNmtState for -// io-controll-call from EplNmtuCal-Modul - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -// EOF diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c deleted file mode 100644 index 9ac2e8e4845..00000000000 --- a/drivers/staging/epl/EplNmtu.c +++ /dev/null @@ -1,706 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for NMT-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/10 17:17:42 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" -#include "user/EplNmtu.h" -#include "user/EplObdu.h" -#include "user/EplTimeru.h" -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) -#include "kernel/EplNmtk.h" -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - tEplNmtuStateChangeCallback m_pfnNmtChangeCb; - tEplTimerHdl m_TimerHdl; - -} tEplNmtuInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplNmtuInstance EplNmtuInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuInit -// -// Description: init first instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuInit(void) -{ - tEplKernel Ret; - - Ret = EplNmtuAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuAddInstance -// -// Description: init other instances of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - EplNmtuInstance_g.m_pfnNmtChangeCb = NULL; - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuDelInstance -// -// Description: delete instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - EplNmtuInstance_g.m_pfnNmtChangeCb = NULL; - - // delete timer - Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuNmtEvent -// -// Description: sends the NMT-Event to the NMT-State-Maschine -// -// -// -// Parameters: NmtEvent_p = NMT-Event to send -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p) -{ - tEplKernel Ret; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkNmtk; - Event.m_NetTime.m_dwNanoSec = 0; - Event.m_NetTime.m_dwSec = 0; - Event.m_EventType = kEplEventTypeNmtEvent; - Event.m_pArg = &NmtEvent_p; - Event.m_uiSize = sizeof(NmtEvent_p); - - Ret = EplEventuPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuGetNmtState -// -// Description: returns the actuell NMT-State -// -// -// -// Parameters: -// -// -// Returns: tEplNmtState = NMT-State -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplNmtState EplNmtuGetNmtState(void) -{ - tEplNmtState NmtState; - - // $$$ call function of communication abstraction layer -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - NmtState = EplNmtkGetNmtState(); -#else - NmtState = 0; -#endif - - return NmtState; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuProcessEvent -// -// Description: processes events from event queue -// -// -// -// Parameters: pEplEvent_p = pointer to event -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // process event - switch (pEplEvent_p->m_EventType) { - // state change of NMT-Module - case kEplEventTypeNmtStateChange: - { - tEplEventNmtStateChange *pNmtStateChange; - - // delete timer - Ret = - EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl); - - pNmtStateChange = - (tEplEventNmtStateChange *) pEplEvent_p->m_pArg; - - // call cb-functions to inform higher layer - if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) { - Ret = - EplNmtuInstance_g. - m_pfnNmtChangeCb(*pNmtStateChange); - } - - if (Ret == kEplSuccessful) { // everything is OK, so switch to next state if necessary - switch (pNmtStateChange->m_NewNmtState) { - // EPL stack is not running - case kEplNmtGsOff: - break; - - // first init of the hardware - case kEplNmtGsInitialising: - { - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterResetApp); - break; - } - - // init of the manufacturer-specific profile area and the - // standardised device profile area - case kEplNmtGsResetApplication: - { - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterResetCom); - break; - } - - // init of the communication profile area - case kEplNmtGsResetCommunication: - { - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterResetConfig); - break; - } - - // build the configuration with infos from OD - case kEplNmtGsResetConfiguration: - { - unsigned int uiNodeId; - - // get node ID from OD -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE) - uiNodeId = - EplObduGetNodeId - (EPL_MCO_PTR_INSTANCE_PTR); -#else - uiNodeId = 0; -#endif - //check node ID if not should be master or slave - if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID) { // node shall be MN -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterMsNotActive); -#else - TRACE0 - ("EplNmtuProcess(): no MN functionality implemented\n"); -#endif - } else { // node shall be CN - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterCsNotActive); - } - break; - } - - //----------------------------------------------------------- - // CN part of the state machine - - // node listens for EPL-Frames and check timeout - case kEplNmtCsNotActive: - { - u32 dwBuffer; - tEplObdSize ObdSize; - tEplTimerArg TimerArg; - - // create timer to switch automatically to BasicEthernet if no MN available in network - - // read NMT_CNBasicEthernetTimerout_U32 from OD - ObdSize = sizeof(dwBuffer); -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE) - Ret = - EplObduReadEntry - (EPL_MCO_PTR_INSTANCE_PTR_ - 0x1F99, 0x00, &dwBuffer, - &ObdSize); -#else - Ret = kEplObdIndexNotExist; -#endif - if (Ret != kEplSuccessful) { - break; - } - if (dwBuffer != 0) { // BasicEthernet is enabled - // convert us into ms - dwBuffer = - dwBuffer / 1000; - if (dwBuffer == 0) { // timer was below one ms - // set one ms - dwBuffer = 1; - } - TimerArg.m_EventSink = - kEplEventSinkNmtk; - TimerArg.m_ulArg = - (unsigned long) - kEplNmtEventTimerBasicEthernet; - Ret = - EplTimeruModifyTimerMs - (&EplNmtuInstance_g. - m_TimerHdl, - (unsigned long) - dwBuffer, - TimerArg); - // potential error is forwarded to event queue which generates error event - } - break; - } - - // node processes only async frames - case kEplNmtCsPreOperational1: - { - break; - } - - // node processes isochronous and asynchronous frames - case kEplNmtCsPreOperational2: - { - Ret = - EplNmtuNmtEvent - (kEplNmtEventEnterReadyToOperate); - break; - } - - // node should be configured und application is ready - case kEplNmtCsReadyToOperate: - { - break; - } - - // normal work state - case kEplNmtCsOperational: - { - break; - } - - // node stopped by MN - // -> only process asynchronous frames - case kEplNmtCsStopped: - { - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtCsBasicEthernet: - { - break; - } - - //----------------------------------------------------------- - // MN part of the state machine - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // node listens for EPL-Frames and check timeout - case kEplNmtMsNotActive: - { - u32 dwBuffer; - tEplObdSize ObdSize; - tEplTimerArg TimerArg; - - // create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network - - // check NMT_StartUp_U32.Bit13 - // read NMT_StartUp_U32 from OD - ObdSize = sizeof(dwBuffer); -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE) - Ret = - EplObduReadEntry - (EPL_MCO_PTR_INSTANCE_PTR_ - 0x1F80, 0x00, &dwBuffer, - &ObdSize); -#else - Ret = kEplObdIndexNotExist; -#endif - if (Ret != kEplSuccessful) { - break; - } - - if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) { // NMT_StartUp_U32.Bit13 == 0 - // new state PreOperational1 - TimerArg.m_ulArg = - (unsigned long) - kEplNmtEventTimerMsPreOp1; - } else { // NMT_StartUp_U32.Bit13 == 1 - // new state BasicEthernet - TimerArg.m_ulArg = - (unsigned long) - kEplNmtEventTimerBasicEthernet; - } - - // read NMT_BootTime_REC.MNWaitNotAct_U32 from OD - ObdSize = sizeof(dwBuffer); -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE) - Ret = - EplObduReadEntry - (EPL_MCO_PTR_INSTANCE_PTR_ - 0x1F89, 0x01, &dwBuffer, - &ObdSize); -#else - Ret = kEplObdIndexNotExist; -#endif - if (Ret != kEplSuccessful) { - break; - } - // convert us into ms - dwBuffer = dwBuffer / 1000; - if (dwBuffer == 0) { // timer was below one ms - // set one ms - dwBuffer = 1; - } - TimerArg.m_EventSink = - kEplEventSinkNmtk; - Ret = - EplTimeruModifyTimerMs - (&EplNmtuInstance_g. - m_TimerHdl, - (unsigned long)dwBuffer, - TimerArg); - // potential error is forwarded to event queue which generates error event - break; - } - - // node processes only async frames - case kEplNmtMsPreOperational1: - { - u32 dwBuffer = 0; - tEplObdSize ObdSize; - tEplTimerArg TimerArg; - - // create timer to switch automatically to PreOp2 if MN identified all mandatory CNs - - // read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD - ObdSize = sizeof(dwBuffer); -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE) - Ret = - EplObduReadEntry - (EPL_MCO_PTR_INSTANCE_PTR_ - 0x1F89, 0x03, &dwBuffer, - &ObdSize); - if (Ret != kEplSuccessful) { - // ignore error, because this timeout is optional - dwBuffer = 0; - } -#endif - if (dwBuffer == 0) { // delay is deactivated - // immediately post timer event - Ret = - EplNmtuNmtEvent - (kEplNmtEventTimerMsPreOp2); - break; - } - // convert us into ms - dwBuffer = dwBuffer / 1000; - if (dwBuffer == 0) { // timer was below one ms - // set one ms - dwBuffer = 1; - } - TimerArg.m_EventSink = - kEplEventSinkNmtk; - TimerArg.m_ulArg = - (unsigned long) - kEplNmtEventTimerMsPreOp2; - Ret = - EplTimeruModifyTimerMs - (&EplNmtuInstance_g. - m_TimerHdl, - (unsigned long)dwBuffer, - TimerArg); - // potential error is forwarded to event queue which generates error event - break; - } - - // node processes isochronous and asynchronous frames - case kEplNmtMsPreOperational2: - { - break; - } - - // node should be configured und application is ready - case kEplNmtMsReadyToOperate: - { - break; - } - - // normal work state - case kEplNmtMsOperational: - { - break; - } - - // no EPL cycle - // -> normal ethernet communication - case kEplNmtMsBasicEthernet: - { - break; - } -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - - default: - { - TRACE1 - ("EplNmtuProcess(): unhandled NMT state 0x%X\n", - pNmtStateChange-> - m_NewNmtState); - } - } - } else if (Ret == kEplReject) { // application wants to change NMT state itself - // it's OK - Ret = kEplSuccessful; - } - - EPL_DBGLVL_NMTU_TRACE0 - ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n"); - break; - } - - default: - { - Ret = kEplNmtInvalidEvent; - } - - } - -//Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplNmtuRegisterStateChangeCb -// -// Description: register Callback-function go get informed about a -// NMT-Change-State-Event -// -// -// -// Parameters: pfnEplNmtStateChangeCb_p = functionpointer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // save callback-function in modul global var - EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p; - - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c deleted file mode 100644 index 92164c57ea1..00000000000 --- a/drivers/staging/epl/EplNmtuCal.c +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for communication abstraction layer of the - NMT-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtuCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/16 -k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplNmtuCal.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplNmtkCalGetNmtState -// -// Description: return current NMT-State -// -> encapsulate access to kernelspace -// -// -// -// Parameters: -// -// -// Returns: tEplNmtState = current NMT-State -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplNmtState EplNmtkCalGetNmtState(void) -{ - tEplNmtState NmtState; - // for test direkt call for EplNmtkGetNmtState() -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - NmtState = EplNmtkGetNmtState(); -#else - NmtState = 0; -#endif - return NmtState; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -// EOF diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c deleted file mode 100644 index 1e463234d81..00000000000 --- a/drivers/staging/epl/EplObd.c +++ /dev/null @@ -1,3192 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for api function of EplOBD-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObd.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.12 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - Microsoft VC7 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/02 k.t.: start of the implementation, version 1.00 - ->based on CANopen OBD-Modul - -****************************************************************************/ - -#include "EplInc.h" -#include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// float definitions and macros -#define _SHIFTED_EXPONENT_MASK_SP 0xff -#define _BIAS_SP 126 -#define T_SP 23 -#define EXPONENT_DENORM_SP (-_BIAS_SP) -#define BASE_TO_THE_T_SP ((float) 8388608.0) -#define GET_EXPONENT_SP(x) ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -// struct for instance table -INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER() - -STATIC tEplObdInitParam m_ObdInitParam; -STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback; - -INSTANCE_TYPE_END -// decomposition of float -typedef union { - tEplObdReal32 m_flRealPart; - int m_nIntegerPart; - -} tEplObdRealParts; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -// This macro replace the unspecific pointer to an instance through -// the modul specific type for the local instance table. This macro -// must defined in each modul. -//#define tEplPtrInstance tEplInstanceInfo * - -EPL_MCO_DECL_INSTANCE_VAR() - -u8 abEplObdTrashObject_g[8]; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -EPL_MCO_DEFINE_INSTANCE_FCT() - -static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_ - tEplObdCallback fpCallback_p, - tEplObdCbParam *pCbParam_p); - -static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p); - -static tEplObdSize EplObdGetStrLen(void *pObjData_p, - tEplObdSize ObjLen_p, tEplObdType ObjType_p); - -#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) -static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p, - void *pData_p); -#endif - -static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p, - tEplObdVarEntry **ppVarEntry_p); - -static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_ - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdEntryPtr * ppObdEntry_p, - tEplObdSubEntryPtr * ppObdSubEntry_p); - -static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p); - -static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p, - unsigned int uiIndex_p, - tEplObdEntryPtr * ppObdEntry_p); - -static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p, - unsigned int uiSubIndex_p, - tEplObdSubEntryPtr * ppObdSubEntry_p); - -static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_ - tEplObdPart CurrentOdPart_p, - tEplObdEntryPtr pObdEnty_p, - tEplObdDir Direction_p); - -static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p); -static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p); - -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) - -static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p); - -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) - -static void EplObdCopyObjectData(void *pDstData_p, - void *pSrcData_p, - tEplObdSize ObjSize_p, tEplObdType ObjType_p); - -void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p); - -static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, - BOOL * pfEntryNumerical_p); - -static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - void **ppDstData_p, - tEplObdSize Size_p, - tEplObdEntryPtr *ppObdEntry_p, - tEplObdSubEntryPtr *ppSubEntry_p, - tEplObdCbParam *pCbParam_p, - tEplObdSize *pObdSize_p); - -static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p, - tEplObdSubEntryPtr pSubEntry_p, - tEplObdCbParam *pCbParam_p, - void *pSrcData_p, - void *pDstData_p, - tEplObdSize ObdSize_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplObdInit() -// -// Description: initializes the first instance -// -// Parameters: pInitParam_p = init parameter -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p) -{ - - tEplKernel Ret; - EPL_MCO_DELETE_INSTANCE_TABLE(); - - if (pInitParam_p == NULL) { - Ret = kEplSuccessful; - goto Exit; - } - - Ret = EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdAddInstance() -// -// Description: adds a new instance -// -// Parameters: pInitParam_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p) -{ - - EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret; - - // check if pointer to instance pointer valid - // get free instance and set the globale instance pointer - // set also the instance addr to parameterlist - EPL_MCO_CHECK_PTR_INSTANCE_PTR(); - EPL_MCO_GET_FREE_INSTANCE_PTR(); - EPL_MCO_SET_PTR_INSTANCE_PTR(); - - // save init parameters - EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam), pInitParam_p, - sizeof(tEplObdInitParam)); - - // clear callback function for command LOAD and STORE - EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = NULL; - - // sign instance as used - EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed); - - // initialize object dictionary - // so all all VarEntries will be initialized to trash object and default values will be set to current data - Ret = EplObdAccessOdPart(EPL_MCO_INSTANCE_PTR_ - kEplObdPartAll, kEplObdDirInit); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdDeleteInstance() -// -// Description: delete instance -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -#if (EPL_USE_DELETEINST_FUNC != FALSE) -tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR) -{ - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - // sign instance as unused - EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused); - - return kEplSuccessful; - -} -#endif // (EPL_USE_DELETEINST_FUNC != FALSE) - -//--------------------------------------------------------------------------- -// -// Function: EplObdWriteEntry() -// -// Description: Function writes data to an OBD entry. Strings -// are stored with added '\0' character. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p) -{ - - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pSubEntry; - tEplObdCbParam CbParam; - void *pDstData; - tEplObdSize ObdSize; - - Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, - uiSubIndex_p, - pSrcData_p, - &pDstData, - Size_p, - &pObdEntry, &pSubEntry, &CbParam, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_ - pObdEntry, - pSubEntry, - &CbParam, pSrcData_p, pDstData, ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdReadEntry() -// -// Description: The function reads an object entry. The application -// can always read the data even if attrib kEplObdAccRead -// is not set. The attrib is only checked up for SDO transfer. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index oof the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p) -{ - - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pSubEntry; - tEplObdCbParam CbParam; - void *pSrcData; - tEplObdSize ObdSize; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - ASSERT(pDstData_p != NULL); - ASSERT(pSize_p != NULL); - - // get address of index and subindex entry - Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get pointer to object data - pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry); - - // check source pointer - if (pSrcData == NULL) { - Ret = kEplObdReadViolation; - goto Exit; - } - //------------------------------------------------------------------------ - // address of source data to structure of callback parameters - // so callback function can change this data before reading - CbParam.m_uiIndex = uiIndex_p; - CbParam.m_uiSubIndex = uiSubIndex_p; - CbParam.m_pArg = pSrcData; - CbParam.m_ObdEvent = kEplObdEvPreRead; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, &CbParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get size of data and check if application has reserved enough memory - ObdSize = EplObdGetDataSizeIntern(pSubEntry); - // check if offset given and calc correct number of bytes to read - if (*pSize_p < ObdSize) { - Ret = kEplObdValueLengthError; - goto Exit; - } - // read value from object - EPL_MEMCPY(pDstData_p, pSrcData, ObdSize); - *pSize_p = ObdSize; - - // write address of destination data to structure of callback parameters - // so callback function can change this data after reading - CbParam.m_pArg = pDstData_p; - CbParam.m_ObdEvent = kEplObdEvPostRead; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, &CbParam); - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdAccessOdPart() -// -// Description: restores default values of one part of OD -// -// Parameters: ObdPart_p -// Direction_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p, - tEplObdDir Direction_p) -{ - - tEplKernel Ret = kEplSuccessful; - BOOL fPartFount; - tEplObdEntryPtr pObdEntry; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - // part always has to be unequal to NULL - pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pPart); - ASSERTMSG(pObdEntry != NULL, - "EplObdAccessOdPart(): no OD part is defined!\n"); - - // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart - fPartFount = FALSE; - - // access to part - if ((ObdPart_p & kEplObdPartGen) != 0) { - fPartFount = TRUE; - - Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ - kEplObdPartGen, pObdEntry, - Direction_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - // access to manufacturer part - pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pManufacturerPart); - - if (((ObdPart_p & kEplObdPartMan) != 0) && (pObdEntry != NULL)) { - fPartFount = TRUE; - - Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ - kEplObdPartMan, pObdEntry, - Direction_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - // access to device part - pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pDevicePart); - - if (((ObdPart_p & kEplObdPartDev) != 0) && (pObdEntry != NULL)) { - fPartFount = TRUE; - - Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ - kEplObdPartDev, pObdEntry, - Direction_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - { - // access to user part - pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart); - - if (((ObdPart_p & kEplObdPartUsr) != 0) && (pObdEntry != NULL)) { - fPartFount = TRUE; - - Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ - kEplObdPartUsr, - pObdEntry, Direction_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } - } -#endif - - // no access to an OD part was done? illegal OD part was specified! - if (fPartFount == FALSE) { - Ret = kEplObdIllegalPart; - } - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdDefineVar() -// -// Description: defines a variable in OD -// -// Parameters: pEplVarParam_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p) -{ - - tEplKernel Ret; - tEplObdVarEntry *pVarEntry; - tEplVarParamValid VarValid; - tEplObdSubEntryPtr pSubindexEntry; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - ASSERT(pVarParam_p != NULL); // is not allowed to be NULL - - // get address of subindex entry - Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ - pVarParam_p->m_uiIndex, - pVarParam_p->m_uiSubindex, NULL, &pSubindexEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get var entry - Ret = EplObdGetVarEntry(pSubindexEntry, &pVarEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - - VarValid = pVarParam_p->m_ValidFlag; - - // copy only this values, which valid flag is set - if ((VarValid & kVarValidSize) != 0) { - if (pSubindexEntry->m_Type != kEplObdTypDomain) { - tEplObdSize DataSize; - - // check passed size parameter - DataSize = EplObdGetObjectSize(pSubindexEntry); - if (DataSize != pVarParam_p->m_Size) { // size of variable does not match - Ret = kEplObdValueLengthError; - goto Exit; - } - } else { // size can be set only for objects of type DOMAIN - pVarEntry->m_Size = pVarParam_p->m_Size; - } - } - - if ((VarValid & kVarValidData) != 0) { - pVarEntry->m_pData = pVarParam_p->m_pData; - } -/* - #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) - { - if ((VarValid & kVarValidCallback) != 0) - { - pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback; - } - - if ((VarValid & kVarValidArg) != 0) - { - pVarEntry->m_pArg = pVarParam_p->m_pArg; - } - } - #endif -*/ - // Ret is already set to kEplSuccessful from ObdGetVarIntern() - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetObjectDataPtr() -// -// Description: It returnes the current data pointer. But if object is an -// constant object it returnes the default pointer. -// -// Parameters: uiIndex_p = Index of the entry -// uiSubindex_p = Subindex of the entry -// -// Return: void * = pointer to object data -// -// State: -// -//--------------------------------------------------------------------------- - -void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p) -{ - tEplKernel Ret; - void *pData; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pObdSubEntry; - - // get pointer to index structure - Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), - uiIndex_p, &pObdEntry); - if (Ret != kEplSuccessful) { - pData = NULL; - goto Exit; - } - // get pointer to subindex structure - Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); - if (Ret != kEplSuccessful) { - pData = NULL; - goto Exit; - } - // get Datapointer - pData = EplObdGetObjectDataPtrIntern(pObdSubEntry); - - Exit: - return pData; - -} - -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - -//--------------------------------------------------------------------------- -// -// Function: EplObdRegisterUserOd() -// -// Description: function registers the user OD -// -// Parameters: pUserOd_p =pointer to user ODd -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p) -{ - - EPL_MCO_CHECK_INSTANCE_STATE(); - - EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart) = pUserOd_p; - - return kEplSuccessful; - -} - -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplObdInitVarEntry() -// -// Description: function to initialize VarEntry dependened on object type -// -// Parameters: pVarEntry_p = pointer to var entry structure -// Type_p = object type -// ObdSize_p = size of object data -// -// Returns: none -// -// State: -// -//--------------------------------------------------------------------------- - -void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p, - tEplObdType Type_p, tEplObdSize ObdSize_p) -{ -/* - #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) - { - // reset pointer to VAR callback and argument - pVarEntry_p->m_fpCallback = NULL; - pVarEntry_p->m_pArg = NULL; - } - #endif -*/ - -// 10-dec-2004 r.d.: this function will not be used for strings - if ((Type_p == kEplObdTypDomain)) -// (bType_p == kEplObdTypVString) /* || -// (bType_p == kEplObdTypOString) || -// (bType_p == kEplObdTypUString) */ ) - { - // variables which are defined as DOMAIN or VSTRING should not point to - // trash object, because this trash object contains only 8 bytes. DOMAINS or - // STRINGS can be longer. - pVarEntry_p->m_pData = NULL; - pVarEntry_p->m_Size = 0; - } else { - // set address to variable data to trash object - // This prevents an access violation if user forgets to call EplObdDefineVar() - // for this variable but mappes it in a PDO. - pVarEntry_p->m_pData = &abEplObdTrashObject_g[0]; - pVarEntry_p->m_Size = ObdSize_p; - } - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetDataSize() -// -// Description: function to initialize VarEntry dependened on object type -// -// gets the data size of an object -// for string objects it returnes the string length -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer -// uiIndex_p = Index -// uiSubIndex_p= Subindex -// -// Return: tEplObdSize -// -// State: -// -//--------------------------------------------------------------------------- -tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p) -{ - tEplKernel Ret; - tEplObdSize ObdSize; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pObdSubEntry; - - // get pointer to index structure - Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), - uiIndex_p, &pObdEntry); - if (Ret != kEplSuccessful) { - ObdSize = 0; - goto Exit; - } - // get pointer to subindex structure - Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); - if (Ret != kEplSuccessful) { - ObdSize = 0; - goto Exit; - } - // get size - ObdSize = EplObdGetDataSizeIntern(pObdSubEntry); - Exit: - return ObdSize; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetNodeId() -// -// Description: function returns nodeid from entry 0x1F93 -// -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer -// -// Return: unsigned int = Node Id -// -// State: -// -//--------------------------------------------------------------------------- -unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR) -{ - tEplKernel Ret; - tEplObdSize ObdSize; - u8 bNodeId; - - bNodeId = 0; - ObdSize = sizeof(bNodeId); - Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_ - EPL_OBD_NODE_ID_INDEX, - EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, &ObdSize); - if (Ret != kEplSuccessful) { - bNodeId = EPL_C_ADR_INVALID; - goto Exit; - } - - Exit: - return (unsigned int)bNodeId; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdSetNodeId() -// -// Description: function sets nodeid in entry 0x1F93 -// -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer -// uiNodeId_p = Node Id to set -// NodeIdType_p= Type on which way the Node Id was set -// -// Return: tEplKernel = Errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p, - tEplObdNodeIdType NodeIdType_p) -{ - tEplKernel Ret; - tEplObdSize ObdSize; - u8 fHwBool; - u8 bNodeId; - - // check Node Id - if (uiNodeId_p == EPL_C_ADR_INVALID) { - Ret = kEplInvalidNodeId; - goto Exit; - } - bNodeId = (u8) uiNodeId_p; - ObdSize = sizeof(u8); - // write NodeId to OD entry - Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_ - EPL_OBD_NODE_ID_INDEX, - EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX - switch (NodeIdType_p) { - // type unknown - case kEplObdNodeIdUnknown: - { - fHwBool = OBD_FALSE; - break; - } - - case kEplObdNodeIdSoftware: - { - fHwBool = OBD_FALSE; - break; - } - - case kEplObdNodeIdHardware: - { - fHwBool = OBD_TRUE; - break; - } - - default: - { - fHwBool = OBD_FALSE; - } - - } // end of switch (NodeIdType_p) - - // write flag - ObdSize = sizeof(fHwBool); - Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR - EPL_OBD_NODE_ID_INDEX, - EPL_OBD_NODE_ID_HWBOOL_SUBINDEX, - &fHwBool, ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdIsNumerical() -// -// Description: function checks if a entry is numerical or not -// -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer -// uiIndex_p = Index -// uiSubIndex_p = Subindex -// pfEntryNumerical_p = pointer to BOOL for returnvalue -// -> TRUE if entry a numerical value -// -> FALSE if entry not a numerical value -// -// Return: tEplKernel = Errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - BOOL *pfEntryNumerical_p) -{ - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pObdSubEntry; - - // get pointer to index structure - Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), - uiIndex_p, &pObdEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get pointer to subindex structure - Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdReadEntryToLe() -// -// Description: The function reads an object entry from the byteoder -// of the system to the little endian byteorder for numerical values. -// For other types a normal read will be processed. This is usefull for -// the PDO and SDO module. The application -// can always read the data even if attrib kEplObdAccRead -// is not set. The attrib is only checked up for SDO transfer. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p) -{ - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pSubEntry; - tEplObdCbParam CbParam; - void *pSrcData; - tEplObdSize ObdSize; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - ASSERT(pDstData_p != NULL); - ASSERT(pSize_p != NULL); - - // get address of index and subindex entry - Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get pointer to object data - pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry); - - // check source pointer - if (pSrcData == NULL) { - Ret = kEplObdReadViolation; - goto Exit; - } - //------------------------------------------------------------------------ - // address of source data to structure of callback parameters - // so callback function can change this data before reading - CbParam.m_uiIndex = uiIndex_p; - CbParam.m_uiSubIndex = uiSubIndex_p; - CbParam.m_pArg = pSrcData; - CbParam.m_ObdEvent = kEplObdEvPreRead; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, &CbParam); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get size of data and check if application has reserved enough memory - ObdSize = EplObdGetDataSizeIntern(pSubEntry); - // check if offset given and calc correct number of bytes to read - if (*pSize_p < ObdSize) { - Ret = kEplObdValueLengthError; - goto Exit; - } - // check if numerical type - switch (pSubEntry->m_Type) { - //----------------------------------------------- - // types without ami - case kEplObdTypVString: - case kEplObdTypOString: - case kEplObdTypDomain: - default: - { - // read value from object - EPL_MEMCPY(pDstData_p, pSrcData, ObdSize); - break; - } - - //----------------------------------------------- - // numerical type which needs ami-write - // 8 bit or smaller values - case kEplObdTypBool: - case kEplObdTypInt8: - case kEplObdTypUInt8: - { - AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData)); - break; - } - - // 16 bit values - case kEplObdTypInt16: - case kEplObdTypUInt16: - { - AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData)); - break; - } - - // 24 bit values - case kEplObdTypInt24: - case kEplObdTypUInt24: - { - AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData)); - break; - } - - // 32 bit values - case kEplObdTypInt32: - case kEplObdTypUInt32: - case kEplObdTypReal32: - { - AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData)); - break; - } - - // 40 bit values - case kEplObdTypInt40: - case kEplObdTypUInt40: - { - AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData)); - break; - } - - // 48 bit values - case kEplObdTypInt48: - case kEplObdTypUInt48: - { - AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData)); - break; - } - - // 56 bit values - case kEplObdTypInt56: - case kEplObdTypUInt56: - { - AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData)); - break; - } - - // 64 bit values - case kEplObdTypInt64: - case kEplObdTypUInt64: - case kEplObdTypReal64: - { - AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData)); - break; - } - - // time of day - case kEplObdTypTimeOfDay: - case kEplObdTypTimeDiff: - { - AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay *) pSrcData)); - break; - } - - } // end of switch(pSubEntry->m_Type) - - *pSize_p = ObdSize; - - // write address of destination data to structure of callback parameters - // so callback function can change this data after reading - CbParam.m_pArg = pDstData_p; - CbParam.m_ObdEvent = kEplObdEvPostRead; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, &CbParam); - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdWriteEntryFromLe() -// -// Description: Function writes data to an OBD entry from a source with -// little endian byteorder to the od with system specuific -// byteorder. Not numerical values will only by copied. Strings -// are stored with added '\0' character. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p) -{ - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pSubEntry; - tEplObdCbParam CbParam; - void *pDstData; - tEplObdSize ObdSize; - u64 qwBuffer; - void *pBuffer = &qwBuffer; - - Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, - uiSubIndex_p, - pSrcData_p, - &pDstData, - Size_p, - &pObdEntry, &pSubEntry, &CbParam, &ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - // check if numerical type - switch (pSubEntry->m_Type) { - //----------------------------------------------- - // types without ami - default: - { // do nothing, i.e. use the given source pointer - pBuffer = pSrcData_p; - break; - } - - //----------------------------------------------- - // numerical type which needs ami-write - // 8 bit or smaller values - case kEplObdTypBool: - case kEplObdTypInt8: - case kEplObdTypUInt8: - { - *((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p); - break; - } - - // 16 bit values - case kEplObdTypInt16: - case kEplObdTypUInt16: - { - *((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p); - break; - } - - // 24 bit values - case kEplObdTypInt24: - case kEplObdTypUInt24: - { - *((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p); - break; - } - - // 32 bit values - case kEplObdTypInt32: - case kEplObdTypUInt32: - case kEplObdTypReal32: - { - *((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p); - break; - } - - // 40 bit values - case kEplObdTypInt40: - case kEplObdTypUInt40: - { - *((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p); - break; - } - - // 48 bit values - case kEplObdTypInt48: - case kEplObdTypUInt48: - { - *((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p); - break; - } - - // 56 bit values - case kEplObdTypInt56: - case kEplObdTypUInt56: - { - *((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p); - break; - } - - // 64 bit values - case kEplObdTypInt64: - case kEplObdTypUInt64: - case kEplObdTypReal64: - { - *((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p); - break; - } - - // time of day - case kEplObdTypTimeOfDay: - case kEplObdTypTimeDiff: - { - AmiGetTimeOfDay(pBuffer, ((tTimeOfDay *) pSrcData_p)); - break; - } - - } // end of switch(pSubEntry->m_Type) - - Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_ - pObdEntry, - pSubEntry, - &CbParam, pBuffer, pDstData, ObdSize); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetAccessType() -// -// Description: Function returns accesstype of the entry -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pAccessTyp_p = pointer to buffer to store accesstype -// -// Return: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p) -{ - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pObdSubEntry; - - // get pointer to index structure - Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), - uiIndex_p, &pObdEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get pointer to subindex structure - Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get accessType - *pAccessTyp_p = pObdSubEntry->m_Access; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdSearchVarEntry() -// -// Description: gets variable from OD -// -// Parameters: uiIndex_p = index of the var entry to search -// uiSubindex_p = subindex of var entry to search -// ppVarEntry_p = pointer to the pointer to the varentry -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p) -{ - - tEplKernel Ret; - tEplObdSubEntryPtr pSubindexEntry; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - // get address of subindex entry - Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry); - if (Ret == kEplSuccessful) { - // get var entry - Ret = EplObdGetVarEntry(pSubindexEntry, ppVarEntry_p); - } - - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -EPL_MCO_DECL_INSTANCE_FCT() -//--------------------------------------------------------------------------- -// -// Function: EplObdCallObjectCallback() -// -// Description: calls callback function of an object or of a variable -// -// Parameters: fpCallback_p -// pCbParam_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_ - tEplObdCallback fpCallback_p, - tEplObdCbParam *pCbParam_p) -{ - - tEplKernel Ret; - tEplObdCallback fpCallback; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - ASSERT(pCbParam_p != NULL); - - Ret = kEplSuccessful; - - // check address of callback function before calling it - if (fpCallback_p != NULL) { - // KEIL C51 V6.01 has a bug. - // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback. - fpCallback = fpCallback_p; - - // call callback function for this object - Ret = fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_() - pCbParam_p); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetDataSizeIntern() -// -// Description: gets the data size of an object -// for string objects it returnes the string length -// -// Parameters: pSubIndexEntry_p -// -// Return: tEplObdSize -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p) -{ - - tEplObdSize DataSize; - void *pData; - - // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING - // then the current pointer is always NULL. The function - // returns the length of default string. - DataSize = EplObdGetObjectSize(pSubIndexEntry_p); - - if (pSubIndexEntry_p->m_Type == kEplObdTypVString) { - // The pointer to current value can be received from EplObdGetObjectCurrentPtr() - pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p)); - if (pData != NULL) { - DataSize = - EplObdGetStrLen((void *)pData, DataSize, - pSubIndexEntry_p->m_Type); - } - - } - - return DataSize; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetStrLen() -// -// Description: The function calculates the length of string. The '\0' -// character is included!! -// -// Parameters: pObjData_p = pointer to string -// ObjLen_p = max. length of objectr entry -// bObjType_p = object type (VSTRING, ...) -// -// Returns: string length + 1 -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplObdSize EplObdGetStrLen(void *pObjData_p, - tEplObdSize ObjLen_p, tEplObdType ObjType_p) -{ - - tEplObdSize StrLen = 0; - u8 *pbString; - - if (pObjData_p == NULL) { - goto Exit; - } - //---------------------------------------- - // Visible String: data format byte - if (ObjType_p == kEplObdTypVString) { - pbString = pObjData_p; - - for (StrLen = 0; StrLen < ObjLen_p; StrLen++) { - if (*pbString == '\0') { - StrLen++; - break; - } - - pbString++; - } - } - //---------------------------------------- - // other string types ... - - Exit: - return (StrLen); - -} - -#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) - -//--------------------------------------------------------------------------- -// -// Function: EplObdCheckObjectRange() -// -// Description: function to check value range of object data -// -// NOTICE: The pointer of data (pData_p) must point out to an even address, -// if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is -// always realiced because pointer m_pDefault points always to an -// array of the SPECIFIED type. -// -// Parameters: pSubindexEntry_p -// pData_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p, - void *pData_p) -{ - - tEplKernel Ret; - void *pRangeData; - - ASSERTMSG(pSubindexEntry_p != NULL, - "EplObdCheckObjectRange(): no address to subindex struct!\n"); - - Ret = kEplSuccessful; - - // check if data range has to be checked - if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) { - goto Exit; - } - // get address of default data - pRangeData = pSubindexEntry_p->m_pDefault; - - // jump to called object type - switch ((tEplObdType) pSubindexEntry_p->m_Type) { - // ----------------------------------------------------------------- - // ObdType kEplObdTypBool will not be checked because there are only - // two possible values 0 or 1. - - // ----------------------------------------------------------------- - // ObdTypes which has to be check up because numerical values - case kEplObdTypInt8: - - // switch to lower limit - pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdInteger8 *) pData_p) < - *((tEplObdInteger8 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdInteger8 *) pData_p) > - *((tEplObdInteger8 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypUInt8: - - // switch to lower limit - pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdUnsigned8 *) pData_p) < - *((tEplObdUnsigned8 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdUnsigned8 *) pData_p) > - *((tEplObdUnsigned8 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypInt16: - - // switch to lower limit - pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdInteger16 *) pData_p) < - *((tEplObdInteger16 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdInteger16 *) pData_p) > - *((tEplObdInteger16 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypUInt16: - - // switch to lower limit - pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdUnsigned16 *) pData_p) < - *((tEplObdUnsigned16 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdUnsigned16 *) pData_p) > - *((tEplObdUnsigned16 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypInt32: - - // switch to lower limit - pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdInteger32 *) pData_p) < - *((tEplObdInteger32 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdInteger32 *) pData_p) > - *((tEplObdInteger32 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypUInt32: - - // switch to lower limit - pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdUnsigned32 *) pData_p) < - *((tEplObdUnsigned32 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdUnsigned32 *) pData_p) > - *((tEplObdUnsigned32 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - case kEplObdTypReal32: - - // switch to lower limit - pRangeData = ((tEplObdReal32 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdReal32 *) pData_p) < - *((tEplObdReal32 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdReal32 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdReal32 *) pData_p) > - *((tEplObdReal32 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt40: - case kEplObdTypInt48: - case kEplObdTypInt56: - case kEplObdTypInt64: - - // switch to lower limit - pRangeData = ((signed u64 *)pRangeData) + 1; - - // check if value is to low - if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((signed u64 *)pRangeData) + 1; - - // check if value is to high - if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - // ----------------------------------------------------------------- - case kEplObdTypUInt40: - case kEplObdTypUInt48: - case kEplObdTypUInt56: - case kEplObdTypUInt64: - - // switch to lower limit - pRangeData = ((unsigned u64 *)pRangeData) + 1; - - // check if value is to low - if (*((unsigned u64 *)pData_p) < - *((unsigned u64 *)pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((unsigned u64 *)pRangeData) + 1; - - // check if value is to high - if (*((unsigned u64 *)pData_p) > - *((unsigned u64 *)pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - // ----------------------------------------------------------------- - case kEplObdTypReal64: - - // switch to lower limit - pRangeData = ((tEplObdReal64 *) pRangeData) + 1; - - // check if value is to low - if (*((tEplObdReal64 *) pData_p) < - *((tEplObdReal64 *) pRangeData)) { - Ret = kEplObdValueTooLow; - break; - } - // switch to higher limit - pRangeData = ((tEplObdReal64 *) pRangeData) + 1; - - // check if value is to high - if (*((tEplObdReal64 *) pData_p) > - *((tEplObdReal64 *) pRangeData)) { - Ret = kEplObdValueTooHigh; - } - - break; - - // ----------------------------------------------------------------- - case kEplObdTypTimeOfDay: - case kEplObdTypTimeDiff: - break; - - // ----------------------------------------------------------------- - // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because - // they have no numerical value. - default: - - Ret = kEplObdUnknownObjectType; - break; - } - - Exit: - - return Ret; - -} -#endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) - -//--------------------------------------------------------------------------- -// -// Function: EplObdWriteEntryPre() -// -// Description: Function prepares write of data to an OBD entry. Strings -// are stored with added '\0' character. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - void **ppDstData_p, - tEplObdSize Size_p, - tEplObdEntryPtr *ppObdEntry_p, - tEplObdSubEntryPtr *ppSubEntry_p, - tEplObdCbParam *pCbParam_p, - tEplObdSize *pObdSize_p) -{ - - tEplKernel Ret; - tEplObdEntryPtr pObdEntry; - tEplObdSubEntryPtr pSubEntry; - tEplObdAccess Access; - void *pDstData; - tEplObdSize ObdSize; - BOOL fEntryNumerical; - -#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) - tEplObdVStringDomain MemVStringDomain; - void *pCurrData; -#endif - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - ASSERT(pSrcData_p != NULL); // should never be NULL - - //------------------------------------------------------------------------ - // get address of index and subindex entry - Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ - uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - // get pointer to object data - pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry); - - Access = (tEplObdAccess) pSubEntry->m_Access; - - // check access for write - // access violation if adress to current value is NULL - if (((Access & kEplObdAccConst) != 0) || (pDstData == NULL)) { - Ret = kEplObdAccessViolation; - goto Exit; - } - //------------------------------------------------------------------------ - // get size of object - // -as ObdSize = ObdGetObjectSize (pSubEntry); - - //------------------------------------------------------------------------ - // To use the same callback function for ObdWriteEntry as well as for - // an SDO download call at first (kEplObdEvPre...) the callback function - // with the argument pointer to object size. - pCbParam_p->m_uiIndex = uiIndex_p; - pCbParam_p->m_uiSubIndex = uiSubIndex_p; - - // Because object size and object pointer are - // adapted by user callback function, re-read - // this values. - ObdSize = EplObdGetObjectSize(pSubEntry); - pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry); - - // 09-dec-2004 r.d.: - // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain - // for String or Domain which lets called module directly change - // the data pointer or size. This prevents a recursive call to - // the callback function if it calls EplObdGetEntry(). -#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) - if ((pSubEntry->m_Type == kEplObdTypVString) || - (pSubEntry->m_Type == kEplObdTypDomain) || - (pSubEntry->m_Type == kEplObdTypOString)) { - if (pSubEntry->m_Type == kEplObdTypVString) { - // reserve one byte for 0-termination - // -as ObdSize -= 1; - Size_p += 1; - } - // fill out new arg-struct - MemVStringDomain.m_DownloadSize = Size_p; - MemVStringDomain.m_ObjSize = ObdSize; - MemVStringDomain.m_pData = pDstData; - - pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain; - pCbParam_p->m_pArg = &MemVStringDomain; - // call user callback - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, - pCbParam_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - // write back new settings - pCurrData = pSubEntry->m_pCurrent; - if ((pSubEntry->m_Type == kEplObdTypVString) - || (pSubEntry->m_Type == kEplObdTypOString)) { - ((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize; - ((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData; - } else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain) - { - ((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize; - ((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData; - } - - // Because object size and object pointer are - // adapted by user callback function, re-read - // this values. - ObdSize = MemVStringDomain.m_ObjSize; - pDstData = (void *)MemVStringDomain.m_pData; - } -#endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) - - // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size - // -as 16.11.04 CbParam.m_pArg = &ObdSize; - // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p; - pCbParam_p->m_pArg = &ObdSize; - pCbParam_p->m_ObdEvent = kEplObdEvInitWrite; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, pCbParam_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if (Size_p > ObdSize) { - Ret = kEplObdValueLengthError; - goto Exit; - } - - if (pSubEntry->m_Type == kEplObdTypVString) { - if (((char *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character - - // reserve one byte in destination for 0-termination - Size_p -= 1; - } else if (Size_p >= ObdSize) { // source string is not 0-terminated - // and destination buffer is too short - Ret = kEplObdValueLengthError; - goto Exit; - } - } - - Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((fEntryNumerical != FALSE) - && (Size_p != ObdSize)) { - // type is numerical, therefor size has to fit, but it does not. - Ret = kEplObdValueLengthError; - goto Exit; - } - // use given size, because non-numerical objects can be written with shorter values - ObdSize = Size_p; - - // set output parameters - *pObdSize_p = ObdSize; - *ppObdEntry_p = pObdEntry; - *ppSubEntry_p = pSubEntry; - *ppDstData_p = pDstData; - - // all checks are done - // the caller may now convert the numerial source value to platform byte order in a temporary buffer - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdWriteEntryPost() -// -// Description: Function finishes write of data to an OBD entry. Strings -// are stored with added '\0' character. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p, - tEplObdSubEntryPtr pSubEntry_p, - tEplObdCbParam *pCbParam_p, - void *pSrcData_p, - void *pDstData_p, - tEplObdSize ObdSize_p) -{ - - tEplKernel Ret; - - // caller converted the source value to platform byte order - // now the range of the value may be checked - -#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) - { - // check data range - Ret = EplObdCheckObjectRange(pSubEntry_p, pSrcData_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - } -#endif - - // now call user callback function to check value - // write address of source data to structure of callback parameters - // so callback function can check this data - pCbParam_p->m_pArg = pSrcData_p; - pCbParam_p->m_ObdEvent = kEplObdEvPreWrite; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry_p->m_fpCallback, pCbParam_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - // copy object data to OBD - EPL_MEMCPY(pDstData_p, pSrcData_p, ObdSize_p); - - // terminate string with 0 - if (pSubEntry_p->m_Type == kEplObdTypVString) { - ((char *)pDstData_p)[ObdSize_p] = '\0'; - } - // write address of destination to structure of callback parameters - // so callback function can change data subsequently - pCbParam_p->m_pArg = pDstData_p; - pCbParam_p->m_ObdEvent = kEplObdEvPostWrite; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry_p->m_fpCallback, pCbParam_p); - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetObjectSize() -// -// Description: function to get size of object -// The function determines if an object type an fixed data type (u8, u16, ...) -// or non fixed object (string, domain). This information is used to decide -// if download data are stored temporary or not. For objects with fixed data length -// and types a value range checking can process. -// For strings the function returns the whole object size not the -// length of string. -// -// Parameters: pSubIndexEntry_p -// -// Return: tEplObdSize -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p) -{ - - tEplObdSize DataSize = 0; - void *pData; - - switch (pSubIndexEntry_p->m_Type) { - // ----------------------------------------------------------------- - case kEplObdTypBool: - - DataSize = 1; - break; - - // ----------------------------------------------------------------- - // ObdTypes which has to be check because numerical values - case kEplObdTypInt8: - DataSize = sizeof(tEplObdInteger8); - break; - - // ----------------------------------------------------------------- - case kEplObdTypUInt8: - DataSize = sizeof(tEplObdUnsigned8); - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt16: - DataSize = sizeof(tEplObdInteger16); - break; - - // ----------------------------------------------------------------- - case kEplObdTypUInt16: - DataSize = sizeof(tEplObdUnsigned16); - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt32: - DataSize = sizeof(tEplObdInteger32); - break; - - // ----------------------------------------------------------------- - case kEplObdTypUInt32: - DataSize = sizeof(tEplObdUnsigned32); - break; - - // ----------------------------------------------------------------- - case kEplObdTypReal32: - DataSize = sizeof(tEplObdReal32); - break; - - // ----------------------------------------------------------------- - // ObdTypes which has to be not checked because not NUM values - case kEplObdTypDomain: - - pData = (void *)pSubIndexEntry_p->m_pCurrent; - if ((void *)pData != (void *)NULL) { - DataSize = ((tEplObdVarEntry *) pData)->m_Size; - } - break; - - // ----------------------------------------------------------------- - case kEplObdTypVString: - //case kEplObdTypUString: - - // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING - // then the current pointer is always NULL. The function - // returns the length of default string. - pData = (void *)pSubIndexEntry_p->m_pCurrent; - if ((void *)pData != (void *)NULL) { - // The max. size of strings defined by STRING-Macro is stored in - // tEplObdVString of current value. - // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) - DataSize = ((tEplObdVString *) pData)->m_Size; - } else { - // The current position is not decleared. The string - // is located in ROM, therefor use default pointer. - pData = (void *)pSubIndexEntry_p->m_pDefault; - if ((const void *)pData != (const void *)NULL) { - // The max. size of strings defined by STRING-Macro is stored in - // tEplObdVString of default value. - DataSize = ((const tEplObdVString *)pData)->m_Size; - } - } - - break; - - // ----------------------------------------------------------------- - case kEplObdTypOString: - - pData = (void *)pSubIndexEntry_p->m_pCurrent; - if ((void *)pData != (void *)NULL) { - // The max. size of strings defined by STRING-Macro is stored in - // tEplObdVString of current value. - // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) - DataSize = ((tEplObdOString *) pData)->m_Size; - } else { - // The current position is not decleared. The string - // is located in ROM, therefor use default pointer. - pData = (void *)pSubIndexEntry_p->m_pDefault; - if ((const void *)pData != (const void *)NULL) { - // The max. size of strings defined by STRING-Macro is stored in - // tEplObdVString of default value. - DataSize = ((const tEplObdOString *)pData)->m_Size; - } - } - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt24: - case kEplObdTypUInt24: - - DataSize = 3; - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt40: - case kEplObdTypUInt40: - - DataSize = 5; - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt48: - case kEplObdTypUInt48: - - DataSize = 6; - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt56: - case kEplObdTypUInt56: - - DataSize = 7; - break; - - // ----------------------------------------------------------------- - case kEplObdTypInt64: - case kEplObdTypUInt64: - case kEplObdTypReal64: - - DataSize = 8; - break; - - // ----------------------------------------------------------------- - case kEplObdTypTimeOfDay: - case kEplObdTypTimeDiff: - - DataSize = 6; - break; - - // ----------------------------------------------------------------- - default: - break; - } - - return DataSize; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetObjectDefaultPtr() -// -// Description: function to get the default pointer (type specific) -// -// Parameters: pSubIndexEntry_p = pointer to subindex structure -// -// Returns: (void *) = pointer to default value -// -// State: -// -//--------------------------------------------------------------------------- - -static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p) -{ - - void *pDefault; - tEplObdType Type; - - ASSERTMSG(pSubIndexEntry_p != NULL, - "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n"); - - // get address to default data from default pointer - pDefault = pSubIndexEntry_p->m_pDefault; - if (pDefault != NULL) { - // there are some special types, whose default pointer always is NULL or has to get from other structure - // get type from subindex structure - Type = pSubIndexEntry_p->m_Type; - - // check if object type is a string value - if ((Type == kEplObdTypVString) /* || - (Type == kEplObdTypUString) */ ) { - - // EPL_OBD_SUBINDEX_RAM_VSTRING - // tEplObdSize m_Size; --> size of default string - // char * m_pDefString; --> pointer to default string - // char * m_pString; --> pointer to string in RAM - // - pDefault = - (void *)((tEplObdVString *) pDefault)->m_pString; - } else if (Type == kEplObdTypOString) { - pDefault = - (void *)((tEplObdOString *) pDefault)->m_pString; - } - } - - return pDefault; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetVarEntry() -// -// Description: gets a variable entry of an object -// -// Parameters: pSubindexEntry_p -// ppVarEntry_p -// -// Return: tCopKernel -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p, - tEplObdVarEntry **ppVarEntry_p) -{ - - tEplKernel Ret = kEplObdVarEntryNotExist; - - ASSERT(ppVarEntry_p != NULL); // is not allowed to be NULL - ASSERT(pSubindexEntry_p != NULL); - - // check VAR-Flag - only this object points to variables - if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) { - // check if object is an array - if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) { - *ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1]; - } else { - *ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent; - } - - Ret = kEplSuccessful; - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetEntry() -// -// Description: gets a index entry from OD -// -// Parameters: uiIndex_p = Index number -// uiSubindex_p = Subindex number -// ppObdEntry_p = pointer to the pointer to the entry -// ppObdSubEntry_p = pointer to the pointer to the subentry -// -// Return: tEplKernel - -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_ - unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdEntryPtr * ppObdEntry_p, - tEplObdSubEntryPtr * ppObdSubEntry_p) -{ - - tEplObdEntryPtr pObdEntry; - tEplObdCbParam CbParam; - tEplKernel Ret; - - // check for all API function if instance is valid - EPL_MCO_CHECK_INSTANCE_STATE(); - - //------------------------------------------------------------------------ - // get address of entry of index - Ret = - EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), uiIndex_p, - &pObdEntry); - if (Ret != kEplSuccessful) { - goto Exit; - } - //------------------------------------------------------------------------ - // get address of entry of subindex - Ret = EplObdGetSubindexIntern(pObdEntry, uiSubindex_p, ppObdSubEntry_p); - if (Ret != kEplSuccessful) { - goto Exit; - } - //------------------------------------------------------------------------ - // call callback function to inform user/stack that an object will be searched - // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist - CbParam.m_uiIndex = uiIndex_p; - CbParam.m_uiSubIndex = uiSubindex_p; - CbParam.m_pArg = NULL; - CbParam.m_ObdEvent = kEplObdEvCheckExist; - Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ - pObdEntry->m_fpCallback, &CbParam); - if (Ret != kEplSuccessful) { - Ret = kEplObdIndexNotExist; - goto Exit; - } - //------------------------------------------------------------------------ - // it is allowed to set ppObdEntry_p to NULL - // if so, no address will be written to calling function - if (ppObdEntry_p != NULL) { - *ppObdEntry_p = pObdEntry; - } - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetObjectCurrentPtr() -// -// Description: function to get Current pointer (type specific) -// -// Parameters: pSubIndexEntry_p -// -// Return: void * -// -// State: -// -//--------------------------------------------------------------------------- - -static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p) -{ - - void *pData; - unsigned int uiArrayIndex; - tEplObdSize Size; - - pData = pSubIndexEntry_p->m_pCurrent; - - // check if constant object - if (pData != NULL) { - // check if object is an array - if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) { - // calculate correct data pointer - uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1; - if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) { - Size = sizeof(tEplObdVarEntry); - } else { - Size = EplObdGetObjectSize(pSubIndexEntry_p); - } - pData = ((u8 *) pData) + (Size * uiArrayIndex); - } - // check if VarEntry - if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) { - // The data pointer is stored in VarEntry->pData - pData = ((tEplObdVarEntry *) pData)->m_pData; - } - // the default pointer is stored for strings in tEplObdVString - else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* || - (pSubIndexEntry_p->m_Type == kEplObdTypUString) */ - ) { - pData = (void *)((tEplObdVString *)pData)->m_pString; - } else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) { - pData = - (void *)((tEplObdOString *)pData)->m_pString; - } - } - - return pData; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetIndexIntern() -// -// Description: gets a index entry from OD -// -// Parameters: pInitParam_p -// uiIndex_p -// ppObdEntry_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p, - unsigned int uiIndex_p, - tEplObdEntryPtr * ppObdEntry_p) -{ - - tEplObdEntryPtr pObdEntry; - tEplKernel Ret; - unsigned int uiIndex; - -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - - unsigned int nLoop; - - // if user OD is used then objekts also has to be searched in user OD - // there is less code need if we do this in a loop - nLoop = 2; - -#endif - - ASSERTMSG(ppObdEntry_p != NULL, - "EplObdGetIndexIntern(): pointer to index entry is NULL!\n"); - - Ret = kEplObdIndexNotExist; - - // get start address of OD part - // start address depends on object index because - // object dictionary is divided in 3 parts - if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) { - pObdEntry = pInitParam_p->m_pPart; - } else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) { - pObdEntry = pInitParam_p->m_pManufacturerPart; - } - // index range 0xA000 to 0xFFFF is reserved for DSP-405 - // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3. - // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE. - // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000... - // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE. - -#if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE) - else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF)) -#else - else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF)) -#endif - { - pObdEntry = pInitParam_p->m_pDevicePart; - } - -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - - // if index does not match in static OD then index only has to be searched in user OD - else { - // begin from first entry of user OD part - pObdEntry = pInitParam_p->m_pUserPart; - - // no user OD is available - if (pObdEntry == NULL) { - goto Exit; - } - // loop must only run once - nLoop = 1; - } - - do { - -#else - - // no user OD is available - // so other object can be found in OD - else { - Ret = kEplObdIllegalPart; - goto Exit; - } - -#endif - - // note: - // The end of Index table is marked with m_uiIndex = 0xFFFF. - // If this function will be called with wIndex_p = 0xFFFF, entry - // should not be found. Therefor it is important to use - // while{} instead of do{}while !!! - - // get first index of index table - uiIndex = pObdEntry->m_uiIndex; - - // search Index in OD part - while (uiIndex != EPL_OBD_TABLE_INDEX_END) { - // go to the end of this function if index is found - if (uiIndex_p == uiIndex) { - // write address of OD entry to calling function - *ppObdEntry_p = pObdEntry; - Ret = kEplSuccessful; - goto Exit; - } - // objects are sorted in OD - // if the current index in OD is greater than the index which is to search then break loop - // in this case user OD has to be search too - if (uiIndex_p < uiIndex) { - break; - } - // next entry in index table - pObdEntry++; - - // get next index of index table - uiIndex = pObdEntry->m_uiIndex; - } - -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - - // begin from first entry of user OD part - pObdEntry = pInitParam_p->m_pUserPart; - - // no user OD is available - if (pObdEntry == NULL) { - goto Exit; - } - // switch next loop for user OD - nLoop--; - -} - -while (nLoop > 0) ; - -#endif - - // in this line Index was not found - -Exit: - -return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdGetSubindexIntern() -// -// Description: gets a subindex entry from a index entry -// -// Parameters: pObdEntry_p -// bSubIndex_p -// ppObdSubEntry_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p, - unsigned int uiSubIndex_p, - tEplObdSubEntryPtr * ppObdSubEntry_p) -{ - - tEplObdSubEntryPtr pSubEntry; - unsigned int nSubIndexCount; - tEplKernel Ret; - - ASSERTMSG(pObdEntry_p != NULL, - "EplObdGetSubindexIntern(): pointer to index is NULL!\n"); - ASSERTMSG(ppObdSubEntry_p != NULL, - "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n"); - - Ret = kEplObdSubindexNotExist; - - // get start address of subindex table and count of subindices - pSubEntry = pObdEntry_p->m_pSubIndex; - nSubIndexCount = pObdEntry_p->m_uiCount; - ASSERTMSG((pSubEntry != NULL) && (nSubIndexCount > 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL - - // search subindex in subindex table - while (nSubIndexCount > 0) { - // check if array is found - if ((pSubEntry->m_Access & kEplObdAccArray) != 0) { - // check if subindex is in range - if (uiSubIndex_p < pObdEntry_p->m_uiCount) { - // update subindex number (subindex entry of an array is always in RAM !!!) - pSubEntry->m_uiSubIndex = uiSubIndex_p; - *ppObdSubEntry_p = pSubEntry; - Ret = kEplSuccessful; - goto Exit; - } - } - // go to the end of this function if subindex is found - else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) { - *ppObdSubEntry_p = pSubEntry; - Ret = kEplSuccessful; - goto Exit; - } - // objects are sorted in OD - // if the current subindex in OD is greater than the subindex which is to search then break loop - // in this case user OD has to be search too - if (uiSubIndex_p < pSubEntry->m_uiSubIndex) { - break; - } - - pSubEntry++; - nSubIndexCount--; - } - - // in this line SubIndex was not fount - - Exit: - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdSetStoreLoadObjCallback() -// -// Description: function set address to callbackfunction for command Store and Load -// -// Parameters: fpCallback_p -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) -tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p) -{ - - EPL_MCO_CHECK_INSTANCE_STATE(); - - // set new address of callback function - EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = fpCallback_p; - - return kEplSuccessful; - -} -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) - -//--------------------------------------------------------------------------- -// -// Function: EplObdAccessOdPartIntern() -// -// Description: runs through OD and executes a job -// -// Parameters: CurrentOdPart_p -// pObdEnty_p -// Direction_p = what is to do (load values from flash or EEPROM, store, ...) -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_ - tEplObdPart CurrentOdPart_p, - tEplObdEntryPtr pObdEnty_p, - tEplObdDir Direction_p) -{ - - tEplObdSubEntryPtr pSubIndex; - unsigned int nSubIndexCount; - tEplObdAccess Access; - void *pDstData; - void *pDefault; - tEplObdSize ObjSize; - tEplKernel Ret; - tEplObdCbStoreParam CbStore; - tEplObdVarEntry *pVarEntry; - - ASSERT(pObdEnty_p != NULL); - - Ret = kEplSuccessful; - - // prepare structure for STORE RESTORE callback function - CbStore.m_bCurrentOdPart = (u8) CurrentOdPart_p; - CbStore.m_pData = NULL; - CbStore.m_ObjSize = 0; - - // command of first action depends on direction to access -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) - if (Direction_p == kEplObdDirLoad) { - CbStore.m_bCommand = (u8) kEplObdCommOpenRead; - - // call callback function for previous command - Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set command for index and subindex loop - CbStore.m_bCommand = (u8) kEplObdCommReadObj; - } else if (Direction_p == kEplObdDirStore) { - CbStore.m_bCommand = (u8) kEplObdCommOpenWrite; - - // call callback function for previous command - Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set command for index and subindex loop - CbStore.m_bCommand = (u8) kEplObdCommWriteObj; - } -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) - - // we should not restore the OD values here - // the next NMT command "Reset Node" or "Reset Communication" resets the OD data - if (Direction_p != kEplObdDirRestore) { - // walk through OD part till end is found - while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) { - // get address to subindex table and count of subindices - pSubIndex = pObdEnty_p->m_pSubIndex; - nSubIndexCount = pObdEnty_p->m_uiCount; - ASSERT((pSubIndex != NULL) && (nSubIndexCount > 0)); // should never be NULL - - // walk through subindex table till all subinices were restored - while (nSubIndexCount != 0) { - Access = (tEplObdAccess) pSubIndex->m_Access; - - // get pointer to current and default data - pDefault = EplObdGetObjectDefaultPtr(pSubIndex); - pDstData = EplObdGetObjectCurrentPtr(pSubIndex); - - // NOTE (for kEplObdTypVString): - // The function returnes the max. number of bytes for a - // current string. - // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit). - ObjSize = EplObdGetObjectSize(pSubIndex); - - // switch direction of OD access - switch (Direction_p) { - // -------------------------------------------------------------------------- - // VarEntry structures has to be initialized - case kEplObdDirInit: - - // If VAR-Flag is set, m_pCurrent means not address of data - // but address of tEplObdVarEntry. Address of data has to be get from - // this structure. - if ((Access & kEplObdAccVar) != 0) { - EplObdGetVarEntry(pSubIndex, - &pVarEntry); - EplObdInitVarEntry(pVarEntry, - pSubIndex-> - m_Type, - ObjSize); -/* - if ((Access & kEplObdAccArray) == 0) - { - EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize); - } - else - { - EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)), - pSubIndex->m_Type, ObjSize); - } -*/ - // at this time no application variable is defined !!! - // therefore data can not be copied. - break; - } else if (pSubIndex->m_Type == - kEplObdTypVString) { - // If pointer m_pCurrent is not equal to NULL then the - // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current - // pointer points to struct tEplObdVString located in MEM. - // The element size includes the max. number of - // bytes. The element m_pString includes the pointer - // to string in MEM. The memory location of default string - // must be copied to memory location of current string. - - pDstData = - pSubIndex->m_pCurrent; - if (pDstData != NULL) { - // 08-dec-2004: code optimization !!! - // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString - // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read - // twice. thats not necessary! - - // For copying data we have to set the destination pointer to the real RAM string. This - // pointer to RAM string is located in default string info structure. (translated r.d.) - pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString; - ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size; - - ((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData; - ((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize; - } - - } else if (pSubIndex->m_Type == - kEplObdTypOString) { - pDstData = - pSubIndex->m_pCurrent; - if (pDstData != NULL) { - // 08-dec-2004: code optimization !!! - // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString - // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read - // twice. thats not necessary! - - // For copying data we have to set the destination pointer to the real RAM string. This - // pointer to RAM string is located in default string info structure. (translated r.d.) - pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString; - ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size; - - ((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData; - ((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize; - } - - } - - // no break !! because copy of data has to done too. - - // -------------------------------------------------------------------------- - // all objects has to be restored with default values - case kEplObdDirRestore: - - // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad - // is replaced to function ObdCopyObjectData() with a new parameter. - - // restore object data for init phase - EplObdCopyObjectData(pDstData, pDefault, - ObjSize, - pSubIndex->m_Type); - break; - - // -------------------------------------------------------------------------- - // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file - case kEplObdDirLoad: - - // restore object data for init phase - EplObdCopyObjectData(pDstData, pDefault, - ObjSize, - pSubIndex->m_Type); - - // no break !! because callback function has to be called too. - - // -------------------------------------------------------------------------- - // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file - case kEplObdDirStore: - - // when attribute kEplObdAccStore is set, then call callback function -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) - if ((Access & kEplObdAccStore) != 0) { - // fill out data pointer and size of data - CbStore.m_pData = pDstData; - CbStore.m_ObjSize = ObjSize; - - // call callback function for read or write object - Ret = - ObdCallStoreCallback - (EPL_MCO_INSTANCE_PTR_ & - CbStore); - if (Ret != kEplSuccessful) { - goto Exit; - } - } -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) - break; - - // -------------------------------------------------------------------------- - // if OD Builder key has to be checked no access to subindex and data should be made - case kEplObdDirOBKCheck: - - // no break !! because we want to break the second loop too. - - // -------------------------------------------------------------------------- - // unknown Direction - default: - - // so we can break the second loop earler - nSubIndexCount = 1; - break; - } - - nSubIndexCount--; - - // next subindex entry - if ((Access & kEplObdAccArray) == 0) { - pSubIndex++; - if ((nSubIndexCount > 0) - && - ((pSubIndex-> - m_Access & kEplObdAccArray) != - 0)) { - // next subindex points to an array - // reset subindex number - pSubIndex->m_uiSubIndex = 1; - } - } else { - if (nSubIndexCount > 0) { - // next subindex points to an array - // increment subindex number - pSubIndex->m_uiSubIndex++; - } - } - } - - // next index entry - pObdEnty_p++; - } - } - // ----------------------------------------------------------------------------------------- - // command of last action depends on direction to access - if (Direction_p == kEplObdDirOBKCheck) { - - goto Exit; - } -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) - else { - if (Direction_p == kEplObdDirLoad) { - CbStore.m_bCommand = (u8) kEplObdCommCloseRead; - } else if (Direction_p == kEplObdDirStore) { - CbStore.m_bCommand = (u8) kEplObdCommCloseWrite; - } else if (Direction_p == kEplObdDirRestore) { - CbStore.m_bCommand = (u8) kEplObdCommClear; - } else { - goto Exit; - } - - // call callback function for last command - Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); - } -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) - -// goto Exit; - - Exit: - - return Ret; - -} - -// ---------------------------------------------------------------------------- -// Function: EplObdCopyObjectData() -// -// Description: checks pointers to object data and copy them from source to destination -// -// Parameters: pDstData_p = destination pointer -// pSrcData_p = source pointer -// ObjSize_p = size of object -// ObjType_p = -// -// Returns: tEplKernel = error code -// ---------------------------------------------------------------------------- - -static void EplObdCopyObjectData(void *pDstData_p, - void *pSrcData_p, - tEplObdSize ObjSize_p, tEplObdType ObjType_p) -{ - - tEplObdSize StrSize = 0; - - // it is allowed to set default and current address to NULL (nothing to copy) - if (pDstData_p != NULL) { - - if (ObjType_p == kEplObdTypVString) { - // The function calculates the really number of characters of string. The - // object entry size can be bigger as string size of default string. - // The '\0'-termination is included. A string with no characters has a - // size of 1. - StrSize = - EplObdGetStrLen((void *)pSrcData_p, ObjSize_p, - kEplObdTypVString); - - // If the string length is greater than or equal to the entry size in OD then only copy - // entry size - 1 and always set the '\0'-termination. - if (StrSize >= ObjSize_p) { - StrSize = ObjSize_p - 1; - } - } - - if (pSrcData_p != NULL) { - // copy data - EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p); - - if (ObjType_p == kEplObdTypVString) { - ((char *)pDstData_p)[StrSize] = '\0'; - } - } - } - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdIsNumericalIntern() -// -// Description: function checks if a entry is numerical or not -// -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer -// uiIndex_p = Index -// uiSubIndex_p = Subindex -// pfEntryNumerical_p = pointer to BOOL for returnvalue -// -> TRUE if entry a numerical value -// -> FALSE if entry not a numerical value -// -// Return: tEplKernel = Errorcode -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, - BOOL * pfEntryNumerical_p) -{ - tEplKernel Ret = kEplSuccessful; - - // get Type - if ((pObdSubEntry_p->m_Type == kEplObdTypVString) - || (pObdSubEntry_p->m_Type == kEplObdTypOString) - || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) { // not numerical types - *pfEntryNumerical_p = FALSE; - } else { // numerical types - *pfEntryNumerical_p = TRUE; - } - - return Ret; - -} - -// ------------------------------------------------------------------------- -// function to classify object type (fixed/non fixed) -// ------------------------------------------------------------------------- - -// ---------------------------------------------------------------------------- -// Function: EplObdCallStoreCallback() -// -// Description: checks address to callback function and calles it when unequal -// to NULL -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer) -// pCbStoreParam_p = address to callback parameters -// -// Returns: tEplKernel = error code -// ---------------------------------------------------------------------------- -#if (EPL_OBD_USE_STORE_RESTORE != FALSE) -static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ - tEplObdCbStoreParam * - pCbStoreParam_p) -{ - - tEplKernel Ret = kEplSuccessful; - - ASSERT(pCbStoreParam_p != NULL); - - // check if function pointer is NULL - if so, no callback should be called - if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) != NULL) { - Ret = - EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) - (EPL_MCO_INSTANCE_PARAM_IDX_() - pCbStoreParam_p); - } - - return Ret; - -} -#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) -//--------------------------------------------------------------------------- -// -// Function: EplObdGetObjectDataPtrIntern() -// -// Description: Function gets the data pointer of an object. -// It returnes the current data pointer. But if object is an -// constant object it returnes the default pointer. -// -// Parameters: pSubindexEntry_p = pointer to subindex entry -// -// Return: void * = pointer to object data -// -// State: -// -//--------------------------------------------------------------------------- - -void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p) -{ - - void *pData; - tEplObdAccess Access; - - ASSERTMSG(pSubindexEntry_p != NULL, - "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n"); - - // there are are some objects whose data pointer has to get from other structure - // get access type for this object - Access = pSubindexEntry_p->m_Access; - - // If object has access type = const, - // for data only exists default values. - if ((Access & kEplObdAccConst) != 0) { - // The pointer to defualt value can be received from ObdGetObjectDefaultPtr() - pData = ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p)); - } else { - // The pointer to current value can be received from ObdGetObjectCurrentPtr() - pData = ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p)); - } - - return pData; - -} -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) -// EOF diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h deleted file mode 100644 index 6bb5a278068..00000000000 --- a/drivers/staging/epl/EplObd.h +++ /dev/null @@ -1,456 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for api function of EplOBD-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObd.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - Microsoft VC7 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/02 k.t.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPLOBD_H_ -#define _EPLOBD_H_ - -#include "EplInc.h" - -// ============================================================================ -// defines -// ============================================================================ - -#define EPL_OBD_TABLE_INDEX_END 0xFFFF - -// for the usage of BOOLEAN in OD -#define OBD_TRUE 0x01 -#define OBD_FALSE 0x00 - -// default OD index for Node id -#define EPL_OBD_NODE_ID_INDEX 0x1F93 -// default subindex for NodeId in OD -#define EPL_OBD_NODE_ID_SUBINDEX 0x01 -// default subindex for NodeIDByHW_BOOL -#define EPL_OBD_NODE_ID_HWBOOL_SUBINDEX 0x02 - -// ============================================================================ -// enums -// ============================================================================ - -// directions for access to object dictionary -typedef enum { - kEplObdDirInit = 0x00, // initialising after power on - kEplObdDirStore = 0x01, // store all object values to non volatile memory - kEplObdDirLoad = 0x02, // load all object values from non volatile memory - kEplObdDirRestore = 0x03, // deletes non volatile memory (restore) - kEplObdDirOBKCheck = 0xFF // reserved -} tEplObdDir; - -// commands for store -typedef enum { - kEplObdCommNothing = 0x00, - kEplObdCommOpenWrite = 0x01, - kEplObdCommWriteObj = 0x02, - kEplObdCommCloseWrite = 0x03, - kEplObdCommOpenRead = 0x04, - kEplObdCommReadObj = 0x05, - kEplObdCommCloseRead = 0x06, - kEplObdCommClear = 0x07, - kEplObdCommUnknown = 0xFF -} tEplObdCommand; - -//----------------------------------------------------------------------------------------------------------- -// events of object callback function -typedef enum { -// m_pArg points to -// --------------------- - kEplObdEvCheckExist = 0x06, // checking if object does exist (reading and writing) NULL - kEplObdEvPreRead = 0x00, // before reading an object source data buffer in OD - kEplObdEvPostRead = 0x01, // after reading an object destination data buffer from caller - kEplObdEvWrStringDomain = 0x07, // event for changing string/domain data pointer or size struct tEplObdVStringDomain in RAM - kEplObdEvInitWrite = 0x04, // initializes writing an object (checking object size) size of object in OD (tEplObdSize) - kEplObdEvPreWrite = 0x02, // before writing an object source data buffer from caller - kEplObdEvPostWrite = 0x03, // after writing an object destination data buffer in OD -// kEplObdEvAbortSdo = 0x05 // after an abort of an SDO transfer - -} tEplObdEvent; - -// part of OD (bit oriented) -typedef unsigned int tEplObdPart; - -#define kEplObdPartNo 0x00 // nothing -#define kEplObdPartGen 0x01 // part (0x1000 - 0x1FFF) -#define kEplObdPartMan 0x02 // manufacturer part (0x2000 - 0x5FFF) -#define kEplObdPartDev 0x04 // device part (0x6000 - 0x9FFF) -#define kEplObdPartUsr 0x08 // dynamic part e.g. for ICE61131-3 - -// combinations -#define kEplObdPartApp ( kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr) // manufacturer and device part (0x2000 - 0x9FFF) and user OD -#define kEplObdPartAll (kEplObdPartGen | kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr) // whole OD - -//----------------------------------------------------------------------------------------------------------- -// access types for objects -// must be a difine because bit-flags -typedef unsigned int tEplObdAccess; - -#define kEplObdAccRead 0x01 // object can be read -#define kEplObdAccWrite 0x02 // object can be written -#define kEplObdAccConst 0x04 // object contains a constant value -#define kEplObdAccPdo 0x08 // object can be mapped in a PDO -#define kEplObdAccArray 0x10 // object contains an array of numerical values -#define kEplObdAccRange 0x20 // object contains lower and upper limit -#define kEplObdAccVar 0x40 // object data is placed in application -#define kEplObdAccStore 0x80 // object data can be stored to non volatile memory - -// combinations (not all combinations are required) -#define kEplObdAccR (0 | 0 | 0 | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccW (0 | 0 | 0 | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccRW (0 | 0 | 0 | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccCR (0 | 0 | 0 | 0 | kEplObdAccConst | 0 | kEplObdAccRead) -#define kEplObdAccGR (0 | 0 | kEplObdAccRange | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccGW (0 | 0 | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccGRW (0 | 0 | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccVR (0 | kEplObdAccVar | 0 | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccVW (0 | kEplObdAccVar | 0 | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccVRW (0 | kEplObdAccVar | 0 | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccVPR (0 | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | 0 | kEplObdAccRead) -#define kEplObdAccVPW (0 | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccVPRW (0 | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccVGR (0 | kEplObdAccVar | kEplObdAccRange | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccVGW (0 | kEplObdAccVar | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccVGRW (0 | kEplObdAccVar | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccVGPR (0 | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | 0 | kEplObdAccRead) -#define kEplObdAccVGPW (0 | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccVGPRW (0 | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSR (kEplObdAccStore | 0 | 0 | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSW (kEplObdAccStore | 0 | 0 | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSRW (kEplObdAccStore | 0 | 0 | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSCR (kEplObdAccStore | 0 | 0 | 0 | kEplObdAccConst | 0 | kEplObdAccRead) -#define kEplObdAccSGR (kEplObdAccStore | 0 | kEplObdAccRange | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSGW (kEplObdAccStore | 0 | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSGRW (kEplObdAccStore | 0 | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSVR (kEplObdAccStore | kEplObdAccVar | 0 | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSVW (kEplObdAccStore | kEplObdAccVar | 0 | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSVRW (kEplObdAccStore | kEplObdAccVar | 0 | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSVPR (kEplObdAccStore | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSVPW (kEplObdAccStore | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSVPRW (kEplObdAccStore | kEplObdAccVar | 0 | kEplObdAccPdo | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSVGR (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0 | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSVGW (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSVGRW (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0 | 0 | kEplObdAccWrite | kEplObdAccRead) -#define kEplObdAccSVGPR (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | 0 | kEplObdAccRead) -#define kEplObdAccSVGPW (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | kEplObdAccWrite | 0 ) -#define kEplObdAccSVGPRW (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0 | kEplObdAccWrite | kEplObdAccRead) - -typedef unsigned int tEplObdSize; // For all objects as objects size are used an unsigned int. - -// ------------------------------------------------------------------------- -// types for data types defined in DS301 -// ------------------------------------------------------------------------- - -// types of objects in object dictionary -// DS-301 defines these types as u16 -typedef enum { -// types which are always supported - kEplObdTypBool = 0x0001, - - kEplObdTypInt8 = 0x0002, - kEplObdTypInt16 = 0x0003, - kEplObdTypInt32 = 0x0004, - kEplObdTypUInt8 = 0x0005, - kEplObdTypUInt16 = 0x0006, - kEplObdTypUInt32 = 0x0007, - kEplObdTypReal32 = 0x0008, - kEplObdTypVString = 0x0009, - kEplObdTypOString = 0x000A, - kEplObdTypDomain = 0x000F, - - kEplObdTypInt24 = 0x0010, - kEplObdTypUInt24 = 0x0016, - - kEplObdTypReal64 = 0x0011, - kEplObdTypInt40 = 0x0012, - kEplObdTypInt48 = 0x0013, - kEplObdTypInt56 = 0x0014, - kEplObdTypInt64 = 0x0015, - kEplObdTypUInt40 = 0x0018, - kEplObdTypUInt48 = 0x0019, - kEplObdTypUInt56 = 0x001A, - kEplObdTypUInt64 = 0x001B, - kEplObdTypTimeOfDay = 0x000C, - kEplObdTypTimeDiff = 0x000D -} tEplObdType; -// other types are not supported in this version - -// ------------------------------------------------------------------------- -// types for data types defined in DS301 -// ------------------------------------------------------------------------- - -typedef unsigned char tEplObdBoolean; // 0001 -typedef signed char tEplObdInteger8; // 0002 -typedef signed short int tEplObdInteger16; // 0003 -typedef signed long tEplObdInteger32; // 0004 -typedef unsigned char tEplObdUnsigned8; // 0005 -typedef unsigned short int tEplObdUnsigned16; // 0006 -typedef unsigned long tEplObdUnsigned32; // 0007 -typedef float tEplObdReal32; // 0008 -typedef unsigned char tEplObdDomain; // 000F -typedef signed long tEplObdInteger24; // 0010 -typedef unsigned long tEplObdUnsigned24; // 0016 - -typedef s64 tEplObdInteger40; // 0012 -typedef s64 tEplObdInteger48; // 0013 -typedef s64 tEplObdInteger56; // 0014 -typedef s64 tEplObdInteger64; // 0015 - -typedef u64 tEplObdUnsigned40; // 0018 -typedef u64 tEplObdUnsigned48; // 0019 -typedef u64 tEplObdUnsigned56; // 001A -typedef u64 tEplObdUnsigned64; // 001B - -typedef double tEplObdReal64; // 0011 - -typedef tTimeOfDay tEplObdTimeOfDay; // 000C -typedef tTimeOfDay tEplObdTimeDifference; // 000D - -// ------------------------------------------------------------------------- -// structur for defining a variable -// ------------------------------------------------------------------------- -// ------------------------------------------------------------------------- -typedef enum { - kVarValidSize = 0x01, - kVarValidData = 0x02, -// kVarValidCallback = 0x04, -// kVarValidArg = 0x08, - - kVarValidAll = 0x03 // currently only size and data are implemented and used -} tEplVarParamValid; - -typedef tEplKernel(*tEplVarCallback) (CCM_DECL_INSTANCE_HDL_ void *pParam_p); - -typedef struct { - tEplVarParamValid m_ValidFlag; - unsigned int m_uiIndex; - unsigned int m_uiSubindex; - tEplObdSize m_Size; - void *m_pData; -// tEplVarCallback m_fpCallback; -// void * m_pArg; - -} tEplVarParam; - -typedef struct { - void *m_pData; - tEplObdSize m_Size; -/* - #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) - tEplVarCallback m_fpCallback; - void * m_pArg; - #endif -*/ -} tEplObdVarEntry; - -typedef struct { - tEplObdSize m_Size; - u8 *m_pString; - -} tEplObdOString; // 000C - -typedef struct { - tEplObdSize m_Size; - char *m_pString; -} tEplObdVString; // 000D - -typedef struct { - tEplObdSize m_Size; - char *m_pDefString; // $$$ d.k. it is unused, so we could delete it - char *m_pString; - -} tEplObdVStringDef; - -typedef struct { - tEplObdSize m_Size; - u8 *m_pDefString; // $$$ d.k. it is unused, so we could delete it - u8 *m_pString; - -} tEplObdOStringDef; - -//r.d. parameter struct for changing object size and/or pointer to data of Strings or Domains -typedef struct { - tEplObdSize m_DownloadSize; // download size from SDO or APP - tEplObdSize m_ObjSize; // current object size from OD - should be changed from callback function - void *m_pData; // current object ptr from OD - should be changed from callback function - -} tEplObdVStringDomain; // 000D - -// ============================================================================ -// types -// ============================================================================ -// ------------------------------------------------------------------------- -// subindexstruct -// ------------------------------------------------------------------------- - -// Change not the order for this struct!!! -typedef struct { - unsigned int m_uiSubIndex; - tEplObdType m_Type; - tEplObdAccess m_Access; - void *m_pDefault; - void *m_pCurrent; // points always to RAM - -} tEplObdSubEntry; - -// r.d.: has always to be because new OBD-Macros for arrays -typedef tEplObdSubEntry *tEplObdSubEntryPtr; - -// ------------------------------------------------------------------------- -// callback function for objdictionary modul -// ------------------------------------------------------------------------- - -// parameters for callback function -typedef struct { - tEplObdEvent m_ObdEvent; - unsigned int m_uiIndex; - unsigned int m_uiSubIndex; - void *m_pArg; - u32 m_dwAbortCode; - -} tEplObdCbParam; - -// define type for callback function: pParam_p points to tEplObdCbParam -typedef tEplKernel(*tEplObdCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbParam *pParam_p); - -// do not change the order for this struct!!! - -typedef struct { - unsigned int m_uiIndex; - tEplObdSubEntryPtr m_pSubIndex; - unsigned int m_uiCount; - tEplObdCallback m_fpCallback; // function is called back if object access - -} tEplObdEntry; - -// allways pointer -typedef tEplObdEntry *tEplObdEntryPtr; - -// ------------------------------------------------------------------------- -// structur to initialize OBD module -// ------------------------------------------------------------------------- - -typedef struct { - tEplObdEntryPtr m_pPart; - tEplObdEntryPtr m_pManufacturerPart; - tEplObdEntryPtr m_pDevicePart; - -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) - - tEplObdEntryPtr m_pUserPart; - -#endif - -} tEplObdInitParam; - -// ------------------------------------------------------------------------- -// structur for parameters of STORE RESTORE command -// ------------------------------------------------------------------------- - -typedef struct { - tEplObdCommand m_bCommand; - tEplObdPart m_bCurrentOdPart; - void *m_pData; - tEplObdSize m_ObjSize; - -} tEplObdCbStoreParam; - -typedef tEplKernel(*tInitTabEntryCallback) (void *pTabEntry_p, unsigned int uiObjIndex_p); - -typedef tEplKernel(*tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbStoreParam *pCbStoreParam_p); - -// ------------------------------------------------------------------------- -// this stucture is used for parameters for function ObdInitModuleTab() -// ------------------------------------------------------------------------- -typedef struct { - unsigned int m_uiLowerObjIndex; // lower limit of ObjIndex - unsigned int m_uiUpperObjIndex; // upper limit of ObjIndex - tInitTabEntryCallback m_fpInitTabEntry; // will be called if ObjIndex was found - void *m_pTabBase; // base address of table - unsigned int m_uiEntrySize; // size of table entry // 25-feb-2005 r.d.: expansion from u8 to u16 necessary for PDO bit mapping - unsigned int m_uiMaxEntries; // max. tabel entries - -} tEplObdModulTabParam; - -//------------------------------------------------------------------- -// enum for function EplObdSetNodeId -//------------------------------------------------------------------- -typedef enum { - kEplObdNodeIdUnknown = 0x00, // unknown how the node id was set - kEplObdNodeIdSoftware = 0x01, // node id set by software - kEplObdNodeIdHardware = 0x02 // node id set by hardware -} tEplObdNodeIdType; - -// ============================================================================ -// global variables -// ============================================================================ - -// ============================================================================ -// public functions -// ============================================================================ - -#endif // #ifndef _EPLOBD_H_ diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h deleted file mode 100644 index fc325bfd604..00000000000 --- a/drivers/staging/epl/EplObdMacro.h +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for macros of EplOBD-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObdMacro.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/05 k.t.: start of the implementation - -> based on CANopen ObdMacro.h - -****************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#if defined (EPL_OBD_DEFINE_MACRO) - - //------------------------------------------------------------------------------------------- -#if defined (EPL_OBD_CREATE_ROM_DATA) - -// #pragma message ("EPL_OBD_CREATE_ROM_DATA") - -#define EPL_OBD_BEGIN() static u32 dwObd_OBK_g = 0x0000; -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() -#define EPL_OBD_BEGIN_PART_MANUFACTURER() -#define EPL_OBD_BEGIN_PART_DEVICE() -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdUnsigned8 xDef##ind##_0x00_g = (cnt); \ - static dtyp xDef##ind##_0x01_g = (def); -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdUnsigned8 xDef##ind##_0x00_g = (cnt); \ - static dtyp xDef##ind##_0x01_g = (def); -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdUnsigned8 xDef##ind##_0x00_g = (cnt); - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val; -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high}; -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static char szCur##ind##_##sub##_g[size+1]; \ - static tEplObdVStringDef xDef##ind##_##sub##_g = {size, val, szCur##ind##_##sub##_g}; - -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static u8 bCur##ind##_##sub##_g[size]; \ - static tEplObdOStringDef xDef##ind##_##sub##_g = {size, ((u8*)""), bCur##ind##_##sub##_g}; -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val; -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high}; -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) - -//------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_CREATE_RAM_DATA) - -// #pragma message ("EPL_OBD_CREATE_RAM_DATA") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() -#define EPL_OBD_BEGIN_PART_MANUFACTURER() -#define EPL_OBD_BEGIN_PART_DEVICE() -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static dtyp axCur##ind##_g[cnt]; -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdVarEntry aVarEntry##ind##_g[cnt]; -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdVarEntry aVarEntry##ind##_g[cnt]; - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xCur##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xCur##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static tEplObdVString xCur##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static tEplObdOString xCur##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) static dtyp xCur##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static tEplObdVarEntry VarEntry##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry VarEntry##ind##_##sub##_g; -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g; - - //------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_CREATE_SUBINDEX_TAB) - -// #pragma message ("EPL_OBD_CREATE_SUBINDEX_TAB") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() -#define EPL_OBD_BEGIN_PART_MANUFACTURER() -#define EPL_OBD_BEGIN_PART_DEVICE() -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[cnt]= { -#define EPL_OBD_END_INDEX(ind) EPL_OBD_END_SUBINDEX()}; -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \ - {0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \ - {1, typ, (acc)|kEplObdAccArray, &xDef##ind##_0x01_g, &axCur##ind##_g[0]}, \ - EPL_OBD_END_SUBINDEX()}; -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \ - {0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \ - {1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, &xDef##ind##_0x01_g, &aVarEntry##ind##_g[0]}, \ - EPL_OBD_END_SUBINDEX()}; -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \ - {0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \ - {1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, NULL, &aVarEntry##ind##_g[0]}, \ - EPL_OBD_END_SUBINDEX()}; - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) {sub,typ, (acc), &xDef##ind##_##sub##_g, &xCur##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) {sub,typ, (acc)|kEplObdAccRange, &xDef##ind##_##sub##_g[0],&xCur##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) {sub,typ, (acc), NULL, &xCur##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) {sub,kEplObdTypVString,(acc)/*|kEplObdAccVar*/, &xDef##ind##_##sub##_g, &xCur##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) {sub,kEplObdTypOString,(acc)/*|kEplObdAccVar*/, &xDef##ind##_##sub##_g, &xCur##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) {sub,kEplObdTypDomain, (acc)|kEplObdAccVar, NULL, &VarEntry##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) {sub,typ, (acc)|kEplObdAccVar, &xDef##ind##_##sub##_g, &VarEntry##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) {sub,typ, (acc)|kEplObdAccVar|kEplObdAccRange,&xDef##ind##_##sub##_g[0],&VarEntry##ind##_##sub##_g}, -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) {sub,typ, (acc)|kEplObdAccVar, NULL, &VarEntry##ind##_##sub##_g}, - - //------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_CREATE_INDEX_TAB) - -// #pragma message ("EPL_OBD_CREATE_INDEX_TAB") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() static tEplObdEntry aObdTab_g[] = { -#define EPL_OBD_BEGIN_PART_MANUFACTURER() static tEplObdEntry aObdTabManufacturer_g[] = { -#define EPL_OBD_BEGIN_PART_DEVICE() static tEplObdEntry aObdTabDevice_g[] = { -#define EPL_OBD_END_PART() {EPL_OBD_TABLE_INDEX_END,(tEplObdSubEntryPtr)&dwObd_OBK_g,0,NULL}}; - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],cnt,(tEplObdCallback)call}, -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call}, -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call}, -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call}, - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) - - //------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_CREATE_INIT_FUNCTION) - -// #pragma message ("EPL_OBD_CREATE_INIT_FUNCTION") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() pInitParam->m_pPart = (tEplObdEntryPtr) &aObdTab_g[0]; -#define EPL_OBD_BEGIN_PART_MANUFACTURER() pInitParam->m_pManufacturerPart = (tEplObdEntryPtr) &aObdTabManufacturer_g[0]; -#define EPL_OBD_BEGIN_PART_DEVICE() pInitParam->m_pDevicePart = (tEplObdEntryPtr) &aObdTabDevice_g[0]; -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) - - //------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_CREATE_INIT_SUBINDEX) - -// #pragma message ("EPL_OBD_CREATE_INIT_SUBINDEX") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() -#define EPL_OBD_BEGIN_PART_MANUFACTURER() -#define EPL_OBD_BEGIN_PART_DEVICE() -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) //CCM_SUBINDEX_RAM_ONLY (EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g))); -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g)); -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g)); -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g)); - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) - - //------------------------------------------------------------------------------------------- -#else - -// #pragma message ("ELSE OF DEFINE") - -#define EPL_OBD_BEGIN() -#define EPL_OBD_END() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_PART_GENERIC() -#define EPL_OBD_BEGIN_PART_MANUFACTURER() -#define EPL_OBD_BEGIN_PART_DEVICE() -#define EPL_OBD_END_PART() - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) -#define EPL_OBD_END_INDEX(ind) -#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) -#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) - - //--------------------------------------------------------------------------------------- -#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,sizes,val) -#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) -#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) -#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) -#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) -#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) - -#endif - - //------------------------------------------------------------------------------------------- -#elif defined (EPL_OBD_UNDEFINE_MACRO) - -// #pragma message ("EPL_OBD_UNDEFINE_MACRO") - -#undef EPL_OBD_BEGIN -#undef EPL_OBD_END - - //--------------------------------------------------------------------------------------- -#undef EPL_OBD_BEGIN_PART_GENERIC -#undef EPL_OBD_BEGIN_PART_MANUFACTURER -#undef EPL_OBD_BEGIN_PART_DEVICE -#undef EPL_OBD_END_PART - - //--------------------------------------------------------------------------------------- -#undef EPL_OBD_BEGIN_INDEX_RAM -#undef EPL_OBD_END_INDEX -#undef EPL_OBD_RAM_INDEX_RAM_ARRAY -#undef EPL_OBD_RAM_INDEX_RAM_VARARRAY -#undef EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT - - //--------------------------------------------------------------------------------------- -#undef EPL_OBD_SUBINDEX_RAM_VAR -#undef EPL_OBD_SUBINDEX_RAM_VAR_RG -#undef EPL_OBD_SUBINDEX_RAM_VSTRING -#undef EPL_OBD_SUBINDEX_RAM_OSTRING -#undef EPL_OBD_SUBINDEX_RAM_VAR_NOINIT -#undef EPL_OBD_SUBINDEX_RAM_DOMAIN -#undef EPL_OBD_SUBINDEX_RAM_USERDEF -#undef EPL_OBD_SUBINDEX_RAM_USERDEF_RG -#undef EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT - -#else - -#error "nothing defined" - -#endif diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c deleted file mode 100644 index 02bd72224ab..00000000000 --- a/drivers/staging/epl/EplObdkCal.c +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for communication abstraction layer - for the Epl-Obd-Kernelspace-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObdkCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -// EOF diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c deleted file mode 100644 index 5f1d9986254..00000000000 --- a/drivers/staging/epl/EplObdu.c +++ /dev/null @@ -1,506 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Epl-Obd-Userspace-module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObdu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" -#include "user/EplObdu.h" -#include "user/EplObduCal.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplObduWriteEntry() -// -// Description: Function writes data to an OBD entry. Strings -// are stored with added '\0' character. -// -// Parameters: uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p) -{ - tEplKernel Ret; - - Ret = EplObduCalWriteEntry(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduReadEntry() -// -// Description: The function reads an object entry. The application -// can always read the data even if attrib kEplObdAccRead -// is not set. The attrib is only checked up for SDO transfer. -// -// Parameters: uiIndex_p = Index oof the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduReadEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p) -{ - tEplKernel Ret; - - Ret = EplObduCalReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdAccessOdPart() -// -// Description: restores default values of one part of OD -// -// Parameters: ObdPart_p = od-part to reset -// Direction_p = directory flag for -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p) -{ - tEplKernel Ret; - - Ret = EplObduCalAccessOdPart(ObdPart_p, Direction_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduDefineVar() -// -// Description: defines a variable in OD -// -// Parameters: pEplVarParam_p = varentry -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p) -{ - tEplKernel Ret; - - Ret = EplObduCalDefineVar(pVarParam_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduGetObjectDataPtr() -// -// Description: It returnes the current data pointer. But if object is an -// constant object it returnes the default pointer. -// -// Parameters: uiIndex_p = Index of the entry -// uiSubindex_p = Subindex of the entry -// -// Return: void * = pointer to object data -// -// State: -// -//--------------------------------------------------------------------------- -void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p) -{ - void *pData; - - pData = EplObduCalGetObjectDataPtr(uiIndex_p, uiSubIndex_p); - - return pData; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduRegisterUserOd() -// -// Description: function registers the user OD -// -// Parameters: pUserOd_p =pointer to user ODd -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) -tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p) -{ - tEplKernel Ret; - - Ret = EplObduCalRegisterUserOd(pUserOd_p); - - return Ret; - -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplObduInitVarEntry() -// -// Description: function to initialize VarEntry dependened on object type -// -// Parameters: pVarEntry_p = pointer to var entry structure -// bType_p = object type -// ObdSize_p = size of object data -// -// Returns: none -// -// State: -// -//--------------------------------------------------------------------------- -void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, tEplObdSize ObdSize_p) -{ - EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p); -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduGetDataSize() -// -// Description: function to initialize VarEntry dependened on object type -// -// gets the data size of an object -// for string objects it returnes the string length -// -// Parameters: uiIndex_p = Index -// uiSubIndex_p= Subindex -// -// Return: tEplObdSize -// -// State: -// -//--------------------------------------------------------------------------- -tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, unsigned int uiSubIndex_p) -{ - tEplObdSize Size; - - Size = EplObduCalGetDataSize(uiIndex_p, uiSubIndex_p); - - return Size; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduGetNodeId() -// -// Description: function returns nodeid from entry 0x1F93 -// -// -// Parameters: -// -// Return: unsigned int = Node Id -// -// State: -// -//--------------------------------------------------------------------------- -unsigned int EplObduGetNodeId(void) -{ - unsigned int uiNodeId; - - uiNodeId = EplObduCalGetNodeId(); - - return uiNodeId; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduSetNodeId() -// -// Description: function sets nodeid in entry 0x1F93 -// -// -// Parameters: uiNodeId_p = Node Id to set -// NodeIdType_p= Type on which way the Node Id was set -// -// Return: tEplKernel = Errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, tEplObdNodeIdType NodeIdType_p) -{ - tEplKernel Ret; - - Ret = EplObduCalSetNodeId(uiNodeId_p, NodeIdType_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduGetAccessType() -// -// Description: Function returns accesstype of the entry -// -// Parameters: uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pAccessTyp_p = pointer to buffer to store accesstyp -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduGetAccessType(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p) -{ - tEplObdAccess AccessType; - - AccessType = - EplObduCalGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p); - - return AccessType; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObdReaduEntryToLe() -// -// Description: The function reads an object entry from the byteoder -// of the system to the little endian byteorder for numeric values. -// For other types a normal read will be processed. This is usefull for -// the PDO and SDO module. The application -// can always read the data even if attrib kEplObdAccRead -// is not set. The attrib is only checked up for SDO transfer. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p) -{ - tEplKernel Ret; - - Ret = - EplObduCalReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p, - pSize_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduWriteEntryFromLe() -// -// Description: Function writes data to an OBD entry from a source with -// little endian byteorder to the od with system specuific -// byteorder. Not numeric values will only by copied. Strings -// are stored with added '\0' character. -// -// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ -// uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - tEplObdSize Size_p) -{ - tEplKernel Ret; - - Ret = - EplObduCalWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p, - Size_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduSearchVarEntry() -// -// Description: gets variable from OD -// -// Parameters: uiIndex_p = index of the var entry to search -// uiSubindex_p = subindex of var entry to search -// ppVarEntry_p = pointer to the pointer to the varentry -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p) -{ - tEplKernel Ret; - - Ret = EplObduCalSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p); - - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c deleted file mode 100644 index 55612cff821..00000000000 --- a/drivers/staging/epl/EplObduCal.c +++ /dev/null @@ -1,543 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for communication abstraction layer - for the Epl-Obd-Userspace-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObduCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ -#include "EplInc.h" -#include "user/EplObduCal.h" -#include "kernel/EplObdk.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) && (EPL_OBD_USE_KERNEL != FALSE) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalWriteEntry() -// -// Description: Function encapsulate access of function EplObdWriteEntry -// -// Parameters: uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdWriteEntry(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalReadEntry() -// -// Description: Function encapsulate access of function EplObdReadEntry -// -// Parameters: uiIndex_p = Index oof the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalAccessOdPart() -// -// Description: Function encapsulate access of function EplObdAccessOdPart -// -// Parameters: ObdPart_p = od-part to reset -// Direction_p = directory flag for -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdAccessOdPart(ObdPart_p, Direction_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalDefineVar() -// -// Description: Function encapsulate access of function EplObdDefineVar -// -// Parameters: pEplVarParam_p = varentry -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdDefineVar(pVarParam_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalGetObjectDataPtr() -// -// Description: Function encapsulate access of function EplObdGetObjectDataPtr -// -// Parameters: uiIndex_p = Index of the entry -// uiSubindex_p = Subindex of the entry -// -// Return: void * = pointer to object data -// -// State: -// -//--------------------------------------------------------------------------- -void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p) -{ - void *pData; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - pData = EplObdGetObjectDataPtr(uiIndex_p, uiSubIndex_p); -#else - pData = NULL; -#endif - - return pData; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalRegisterUserOd() -// -// Description: Function encapsulate access of function EplObdRegisterUserOd -// -// Parameters: pUserOd_p = pointer to user OD -// -// Return: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- -#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) -tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdRegisterUserOd(pUserOd_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; - -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplObduCalInitVarEntry() -// -// Description: Function encapsulate access of function EplObdInitVarEntry -// -// Parameters: pVarEntry_p = pointer to var entry structure -// bType_p = object type -// ObdSize_p = size of object data -// -// Returns: none -// -// State: -// -//--------------------------------------------------------------------------- -void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, - tEplObdSize ObdSize_p) -{ -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - EplObdInitVarEntry(pVarEntry_p, bType_p, ObdSize_p); -#endif -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalGetDataSize() -// -// Description: Function encapsulate access of function EplObdGetDataSize -// -// gets the data size of an object -// for string objects it returnes the string length -// -// Parameters: uiIndex_p = Index -// uiSubIndex_p= Subindex -// -// Return: tEplObdSize -// -// State: -// -//--------------------------------------------------------------------------- -tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p, - unsigned int uiSubIndex_p) -{ - tEplObdSize Size; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Size = EplObdGetDataSize(uiIndex_p, uiSubIndex_p); -#else - Size = 0; -#endif - - return Size; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalGetNodeId() -// -// Description: Function encapsulate access of function EplObdGetNodeId -// -// -// Parameters: -// -// Return: unsigned int = Node Id -// -// State: -// -//--------------------------------------------------------------------------- -unsigned int EplObduCalGetNodeId(void) -{ - unsigned int uiNodeId; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - uiNodeId = EplObdGetNodeId(); -#else - uiNodeId = 0; -#endif - - return uiNodeId; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalSetNodeId() -// -// Description: Function encapsulate access of function EplObdSetNodeId -// -// -// Parameters: uiNodeId_p = Node Id to set -// NodeIdType_p= Type on which way the Node Id was set -// -// Return: tEplKernel = Errorcode -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p, - tEplObdNodeIdType NodeIdType_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdSetNodeId(uiNodeId_p, NodeIdType_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalGetAccessType() -// -// Description: Function encapsulate access of function EplObdGetAccessType -// -// Parameters: uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pAccessTyp_p = pointer to buffer to store accesstype -// -// Return: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p) -{ - tEplObdAccess AccesType; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - AccesType = EplObdGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p); -#else - AccesType = 0; -#endif - - return AccesType; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalReadEntryToLe() -// -// Description: Function encapsulate access of function EplObdReadEntryToLe -// -// Parameters: uiIndex_p = Index of the OD entry to read -// uiSubIndex_p = Subindex to read -// pDstData_p = pointer to the buffer for data -// Offset_p = offset in data for read access -// pSize_p = IN: Size of the buffer -// OUT: number of readed Bytes -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p); -#else - Ret = kEplSuccessful; -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalWriteEntryFromLe() -// -// Description: Function encapsulate access of function EplObdWriteEntryFromLe -// -// Parameters: uiIndex_p = Index of the OD entry -// uiSubIndex_p = Subindex of the OD Entry -// pSrcData_p = Pointer to the data to write -// Size_p = Size of the data in Byte -// -// Return: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = - EplObdWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p); -#else - Ret = kEplSuccessful; -#endif - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplObduCalSearchVarEntry() -// -// Description: gets variable from OD -// -// Parameters: uiIndex_p = index of the var entry to search -// uiSubindex_p = subindex of var entry to search -// ppVarEntry_p = pointer to the pointer to the varentry -// -// Return: tEplKernel -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p) -{ - tEplKernel Ret; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - Ret = EplObdSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p); -#else - Ret = kEplSuccessful; -#endif - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h deleted file mode 100644 index 0b3ad5bc7d5..00000000000 --- a/drivers/staging/epl/EplPdo.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for PDO module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdo.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_PDO_H_ -#define _EPL_PDO_H_ - -#include "EplInc.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// invalid PDO-NodeId -#define EPL_PDO_INVALID_NODE_ID 0xFF -// NodeId for PReq RPDO -#define EPL_PDO_PREQ_NODE_ID 0x00 -// NodeId for PRes TPDO -#define EPL_PDO_PRES_NODE_ID 0x00 - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct { - void *m_pVar; - u16 m_wOffset; // in Bits - u16 m_wSize; // in Bits - BOOL m_fNumeric; // numeric value -> use AMI functions - -} tEplPdoMapping; - -typedef struct { - unsigned int m_uiSizeOfStruct; - unsigned int m_uiPdoId; - unsigned int m_uiNodeId; - // 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes - // TPDO: 0x00=PRes, MN: CnNodeId=PReq - - BOOL m_fTxRx; - u8 m_bMappingVersion; - unsigned int m_uiMaxMappingEntries; // maximum number of mapping entries, i.e. size of m_aPdoMapping - tEplPdoMapping m_aPdoMapping[1]; - -} tEplPdoParam; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPL_PDO_H_ diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c deleted file mode 100644 index db9b3f08384..00000000000 --- a/drivers/staging/epl/EplPdok.c +++ /dev/null @@ -1,669 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for kernel PDO module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdok.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "kernel/EplPdok.h" -#include "kernel/EplPdokCal.h" -#include "kernel/EplEventk.h" -#include "kernel/EplObdk.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0) - -#error 'ERROR: Missing DLLk-Modul!' - -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0) - -#error 'ERROR: Missing OBDk-Modul!' - -#endif -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_PDOK_OBD_IDX_RX_COMM_PARAM 0x1400 -#define EPL_PDOK_OBD_IDX_RX_MAPP_PARAM 0x1600 -#define EPL_PDOK_OBD_IDX_TX_COMM_PARAM 0x1800 -#define EPL_PDOK_OBD_IDX_TX_MAPP_PARAM 0x1A00 - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplPdok */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplPdokAddInstance() -// -// Description: add and initialize new instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokAddInstance(void) -{ - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokDelInstance() -// -// Description: deletes an instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokDelInstance(void) -{ - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCbPdoReceived -// -// Description: This function is called by DLL if PRes or PReq frame was -// received. It posts the frame to the event queue. -// It is called in states NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL. -// The passed PDO needs not to be valid. -// -// Parameters: pFrameInfo_p = pointer to frame info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkPdok; - Event.m_EventType = kEplEventTypePdoRx; - // limit copied data to size of PDO (because from some CNs the frame is larger than necessary) - Event.m_uiSize = AmiGetWordFromLe(&pFrameInfo_p->m_pFrame->m_Data.m_Pres.m_le_wSize) + 24; // pFrameInfo_p->m_uiFrameSize; - Event.m_pArg = pFrameInfo_p->m_pFrame; - Ret = EplEventkPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCbPdoTransmitted -// -// Description: This function is called by DLL if PRes or PReq frame was -// sent. It posts the pointer to the frame to the event queue. -// It is called in NMT_CS_PRE_OPERATIONAL_2, -// NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL. -// -// Parameters: pFrameInfo_p = pointer to frame info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkPdok; - Event.m_EventType = kEplEventTypePdoTx; - Event.m_uiSize = sizeof(tEplFrameInfo); - Event.m_pArg = pFrameInfo_p; - Ret = EplEventkPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCbSoa -// -// Description: This function is called by DLL if SoA frame was -// received resp. sent. It posts this event to the event queue. -// -// Parameters: pFrameInfo_p = pointer to frame info structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplEvent Event; - - Event.m_EventSink = kEplEventSinkPdok; - Event.m_EventType = kEplEventTypePdoSoa; - Event.m_uiSize = 0; - Event.m_pArg = NULL; - Ret = EplEventkPost(&Event); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokProcess -// -// Description: This function processes all received and transmitted PDOs. -// This function must not be interrupted by any other task -// except ISRs (like the ethernet driver ISR, which may call -// EplPdokCbFrameReceived() or EplPdokCbFrameTransmitted()). -// -// Parameters: pEvent_p = pointer to event structure -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokProcess(tEplEvent * pEvent_p) -{ - tEplKernel Ret = kEplSuccessful; - u16 wPdoSize; - u16 wBitOffset; - u16 wBitSize; - u16 wVarSize; - u64 qwObjectMapping; - u8 bMappSubindex; - u8 bObdSubindex; - u16 wObdMappIndex; - u16 wObdCommIndex; - u16 wPdoId; - u8 bObdData; - u8 bObjectCount; - u8 bFrameData; - BOOL fValid; - tEplObdSize ObdSize; - tEplFrame *pFrame; - tEplFrameInfo *pFrameInfo; - unsigned int uiNodeId; - tEplMsgType MsgType; - - // 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes - // TPDO: 0x00=PRes, MN: CnNodeId=PReq - - switch (pEvent_p->m_EventType) { - case kEplEventTypePdoRx: // RPDO received - pFrame = (tEplFrame *) pEvent_p->m_pArg; - - // check if received RPDO is valid - bFrameData = - AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1); - if ((bFrameData & EPL_FRAME_FLAG1_RD) == 0) { // RPDO invalid - goto Exit; - } - // retrieve EPL message type - MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType); - if (MsgType == kEplMsgTypePreq) { // RPDO is PReq frame - uiNodeId = EPL_PDO_PREQ_NODE_ID; // 0x00 - } else { // RPDO is PRes frame - // retrieve node ID - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - } - - // search for appropriate valid RPDO in OD - wObdMappIndex = EPL_PDOK_OBD_IDX_RX_MAPP_PARAM; - for (wObdCommIndex = EPL_PDOK_OBD_IDX_RX_COMM_PARAM; - wObdCommIndex < (EPL_PDOK_OBD_IDX_RX_COMM_PARAM + 0x00FF); - wObdCommIndex++, wObdMappIndex++) { - ObdSize = 1; - // read node ID from OD - Ret = - EplObdReadEntry(wObdCommIndex, 0x01, &bObdData, - &ObdSize); - if ((Ret == kEplObdIndexNotExist) - || (Ret == kEplObdSubindexNotExist) - || (Ret == kEplObdIllegalPart)) { // PDO does not exist; last PDO reached - Ret = kEplSuccessful; - goto Exit; - } else if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - if (bObdData != uiNodeId) { // node ID does not equal - wrong PDO, try next PDO in OD - continue; - } - ObdSize = 1; - // read number of mapped objects from OD; this indicates if the PDO is valid - Ret = - EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount, - &ObdSize); - if ((Ret == kEplObdIndexNotExist) - || (Ret == kEplObdSubindexNotExist) - || (Ret == kEplObdIllegalPart)) { // PDO does not exist; last PDO reached - Ret = kEplSuccessful; - goto Exit; - } else if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - if (bObjectCount == 0) { // PDO in OD not valid, try next PDO in OD - continue; - } - - ObdSize = 1; - // check PDO mapping version - Ret = - EplObdReadEntry(wObdCommIndex, 0x02, &bObdData, - &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - // retrieve PDO version from frame - bFrameData = - AmiGetByteFromLe(&pFrame->m_Data.m_Pres. - m_le_bPdoVersion); - if ((bObdData & EPL_VERSION_MAIN) != (bFrameData & EPL_VERSION_MAIN)) { // PDO versions do not match - // $$$ raise PDO error - // termiate processing of this RPDO - goto Exit; - } - // valid RPDO found - - // retrieve PDO size - wPdoSize = - AmiGetWordFromLe(&pFrame->m_Data.m_Pres.m_le_wSize); - - // process mapping - for (bMappSubindex = 1; bMappSubindex <= bObjectCount; - bMappSubindex++) { - ObdSize = 8; // u64 - // read object mapping from OD - Ret = - EplObdReadEntry(wObdMappIndex, - bMappSubindex, - &qwObjectMapping, &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed - if (qwObjectMapping == 0) { // invalid entry, continue with next entry - continue; - } - // decode object mapping - wObdCommIndex = - (u16) (qwObjectMapping & - 0x000000000000FFFFLL); - bObdSubindex = - (u8) ((qwObjectMapping & - 0x0000000000FF0000LL) >> 16); - wBitOffset = - (u16) ((qwObjectMapping & - 0x0000FFFF00000000LL) >> 32); - wBitSize = - (u16) ((qwObjectMapping & - 0xFFFF000000000000LL) >> 48); - - // check if object exceeds PDO size - if (((wBitOffset + wBitSize) >> 3) > wPdoSize) { // wrong object mapping; PDO size is too low - // $$$ raise PDO error - // terminate processing of this RPDO - goto Exit; - } - // copy object from RPDO to process/OD variable - ObdSize = wBitSize >> 3; - Ret = - EplObdWriteEntryFromLe(wObdCommIndex, - bObdSubindex, - &pFrame->m_Data. - m_Pres. - m_le_abPayload[(wBitOffset >> 3)], ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - - } - - // processing finished successfully - goto Exit; - } - break; - - case kEplEventTypePdoTx: // TPDO transmitted - pFrameInfo = (tEplFrameInfo *) pEvent_p->m_pArg; - pFrame = pFrameInfo->m_pFrame; - - // set TPDO invalid, so that only fully processed TPDOs are sent as valid - bFrameData = - AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1); - AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bFlag1, - (bFrameData & ~EPL_FRAME_FLAG1_RD)); - - // retrieve EPL message type - MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType); - if (MsgType == kEplMsgTypePres) { // TPDO is PRes frame - uiNodeId = EPL_PDO_PRES_NODE_ID; // 0x00 - } else { // TPDO is PReq frame - // retrieve node ID - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId); - } - - // search for appropriate valid TPDO in OD - wObdMappIndex = EPL_PDOK_OBD_IDX_TX_MAPP_PARAM; - wObdCommIndex = EPL_PDOK_OBD_IDX_TX_COMM_PARAM; - for (wPdoId = 0;; wPdoId++, wObdCommIndex++, wObdMappIndex++) { - ObdSize = 1; - // read node ID from OD - Ret = - EplObdReadEntry(wObdCommIndex, 0x01, &bObdData, - &ObdSize); - if ((Ret == kEplObdIndexNotExist) - || (Ret == kEplObdSubindexNotExist) - || (Ret == kEplObdIllegalPart)) { // PDO does not exist; last PDO reached - Ret = kEplSuccessful; - goto Exit; - } else if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - if (bObdData != uiNodeId) { // node ID does not equal - wrong PDO, try next PDO in OD - continue; - } - ObdSize = 1; - // read number of mapped objects from OD; this indicates if the PDO is valid - Ret = - EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount, - &ObdSize); - if ((Ret == kEplObdIndexNotExist) - || (Ret == kEplObdSubindexNotExist) - || (Ret == kEplObdIllegalPart)) { // PDO does not exist; last PDO reached - Ret = kEplSuccessful; - goto Exit; - } else if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - if (bObjectCount == 0) { // PDO in OD not valid, try next PDO in OD - continue; - } - // valid TPDO found - - ObdSize = 1; - // get PDO mapping version from OD - Ret = - EplObdReadEntry(wObdCommIndex, 0x02, &bObdData, - &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // entry read successfully - // set PDO version in frame - AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bPdoVersion, - bObdData); - - // calculate PDO size - wPdoSize = 0; - - // process mapping - for (bMappSubindex = 1; bMappSubindex <= bObjectCount; - bMappSubindex++) { - ObdSize = 8; // u64 - // read object mapping from OD - Ret = - EplObdReadEntry(wObdMappIndex, - bMappSubindex, - &qwObjectMapping, &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - // check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed - if (qwObjectMapping == 0) { // invalid entry, continue with next entry - continue; - } - // decode object mapping - wObdCommIndex = - (u16) (qwObjectMapping & - 0x000000000000FFFFLL); - bObdSubindex = - (u8) ((qwObjectMapping & - 0x0000000000FF0000LL) >> 16); - wBitOffset = - (u16) ((qwObjectMapping & - 0x0000FFFF00000000LL) >> 32); - wBitSize = - (u16) ((qwObjectMapping & - 0xFFFF000000000000LL) >> 48); - - // calculate max PDO size - ObdSize = wBitSize >> 3; - wVarSize = (wBitOffset >> 3) + (u16) ObdSize; - if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize) { // TPDO is too short - // $$$ raise PDO error, set Ret - goto Exit; - } - if (wVarSize > wPdoSize) { // memorize new PDO size - wPdoSize = wVarSize; - } - // copy object from process/OD variable to TPDO - Ret = - EplObdReadEntryToLe(wObdCommIndex, - bObdSubindex, - &pFrame->m_Data.m_Pres. - m_le_abPayload[(wBitOffset >> 3)], &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - goto Exit; - } - - } - - // set PDO size in frame - AmiSetWordToLe(&pFrame->m_Data.m_Pres.m_le_wSize, - wPdoSize); - - Ret = EplPdokCalAreTpdosValid(&fValid); - if (fValid != FALSE) { - // set TPDO valid - bFrameData = - AmiGetByteFromLe(&pFrame->m_Data.m_Pres. - m_le_bFlag1); - AmiSetByteToLe(&pFrame->m_Data.m_Pres. - m_le_bFlag1, - (bFrameData | - EPL_FRAME_FLAG1_RD)); - } - // processing finished successfully - - goto Exit; - } - break; - - case kEplEventTypePdoSoa: // SoA received - - // invalidate TPDOs - Ret = EplPdokCalSetTpdosValid(FALSE); - break; - - default: - { - ASSERTMSG(FALSE, - "EplPdokProcess(): unhandled event type!\n"); - } - } - - Exit: - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplPdokCal.c b/drivers/staging/epl/EplPdokCal.c deleted file mode 100644 index f44c4757800..00000000000 --- a/drivers/staging/epl/EplPdokCal.c +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for kernel PDO Communication Abstraction Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdokCal.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/27 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "kernel/EplPdokCal.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplPdokCal */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - BOOL m_fTpdosValid; - -} tEplPdokCalInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplPdokCalInstance EplPdokCalInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCalAddInstance() -// -// Description: add and initialize new instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCalAddInstance(void) -{ - - EPL_MEMSET(&EplPdokCalInstance_g, 0, sizeof(EplPdokCalInstance_g)); - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCalDelInstance() -// -// Description: deletes an instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCalDelInstance(void) -{ - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCalSetTpdosValid() -// -// Description: This function sets the validity flag for TPDOs to the -// specified value. -// -// Parameters: fValid_p = validity flag -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p) -{ - tEplKernel Ret = kEplSuccessful; - - EplPdokCalInstance_g.m_fTpdosValid = fValid_p; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdokCalAreTpdosValid() -// -// Description: This function returns the validity flag for TPDOs. -// -// Parameters: pfValid_p = OUT: validity flag -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p) -{ - tEplKernel Ret = kEplSuccessful; - - *pfValid_p = EplPdokCalInstance_g.m_fTpdosValid; - - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -#endif - -// EOF diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c deleted file mode 100644 index d6d06242d74..00000000000 --- a/drivers/staging/epl/EplPdou.c +++ /dev/null @@ -1,565 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for user PDO module - Currently, this module just implements a OD callback function - to check if the PDO configuration is valid. - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdou.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#include "EplInc.h" -//#include "user/EplPdouCal.h" -#include "user/EplObdu.h" -#include "user/EplPdou.h" -#include "EplSdoAc.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0) - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE) -#error "EPL PDOu module needs EPL module OBDU or OBDK!" -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_PDOU_OBD_IDX_RX_COMM_PARAM 0x1400 -#define EPL_PDOU_OBD_IDX_RX_MAPP_PARAM 0x1600 -#define EPL_PDOU_OBD_IDX_TX_COMM_PARAM 0x1800 -#define EPL_PDOU_OBD_IDX_TX_MAPP_PARAM 0x1A00 -#define EPL_PDOU_OBD_IDX_MAPP_PARAM 0x0200 -#define EPL_PDOU_OBD_IDX_MASK 0xFF00 -#define EPL_PDOU_PDO_ID_MASK 0x00FF - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S EplPdou */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p, - unsigned int uiIndex_p); - -static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p, - unsigned int *puiIndex_p, - unsigned int *puiSubIndex_p, - unsigned int *puiBitOffset_p, - unsigned int *puiBitSize_p); - -static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p, - tEplObdAccess AccessType_p, - u32 * pdwAbortCode_p, - unsigned int *puiPdoSize_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplPdouAddInstance() -// -// Description: add and initialize new instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdouAddInstance(void) -{ - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdouDelInstance() -// -// Description: deletes an instance of EPL stack -// -// Parameters: none -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdouDelInstance(void) -{ - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdouCbObdAccess -// -// Description: callback function for OD accesses -// -// Parameters: pParam_p = OBD parameter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiPdoId; - unsigned int uiIndexType; - tEplObdSize ObdSize; - u8 bObjectCount; - u64 qwObjectMapping; - tEplObdAccess AccessType; - u8 bMappSubindex; - unsigned int uiCurPdoSize; - u16 wMaxPdoSize; - unsigned int uiSubIndex; - - // fetch PDO ID - uiPdoId = pParam_p->m_uiIndex & EPL_PDOU_PDO_ID_MASK; - - // fetch object index type - uiIndexType = pParam_p->m_uiIndex & EPL_PDOU_OBD_IDX_MASK; - - if (pParam_p->m_ObdEvent != kEplObdEvPreWrite) { // read accesses, post write events etc. are OK - pParam_p->m_dwAbortCode = 0; - goto Exit; - } - // check index type - switch (uiIndexType) { - case EPL_PDOU_OBD_IDX_RX_COMM_PARAM: - // RPDO communication parameter accessed - case EPL_PDOU_OBD_IDX_TX_COMM_PARAM: - { // TPDO communication parameter accessed - Ret = EplPdouCheckPdoValidity(pParam_p, - (EPL_PDOU_OBD_IDX_MAPP_PARAM - | pParam_p->m_uiIndex)); - if (Ret != kEplSuccessful) { // PDO is valid or does not exist - goto Exit; - } - - goto Exit; - } - - case EPL_PDOU_OBD_IDX_RX_MAPP_PARAM: - { // RPDO mapping parameter accessed - - AccessType = kEplObdAccWrite; - break; - } - - case EPL_PDOU_OBD_IDX_TX_MAPP_PARAM: - { // TPDO mapping parameter accessed - - AccessType = kEplObdAccRead; - break; - } - - default: - { // this callback function is only for - // PDO mapping and communication parameters - pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR; - goto Exit; - } - } - - // RPDO and TPDO mapping parameter accessed - - if (pParam_p->m_uiSubIndex == 0) { // object mapping count accessed - - // PDO is enabled or disabled - bObjectCount = *((u8 *) pParam_p->m_pArg); - - if (bObjectCount == 0) { // PDO shall be disabled - - // that is always possible - goto Exit; - } - // PDO shall be enabled - // it should have been disabled for this operation - Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex); - if (Ret != kEplSuccessful) { // PDO is valid or does not exist - goto Exit; - } - - if (AccessType == kEplObdAccWrite) { - uiSubIndex = 0x04; // PReqActPayloadLimit_U16 - } else { - uiSubIndex = 0x05; // PResActPayloadLimit_U16 - } - - // fetch maximum PDO size from Object 1F98h: NMT_CycleTiming_REC - ObdSize = sizeof(wMaxPdoSize); - Ret = - EplObduReadEntry(0x1F98, uiSubIndex, &wMaxPdoSize, - &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR; - goto Exit; - } - // check all objectmappings - for (bMappSubindex = 1; bMappSubindex <= bObjectCount; - bMappSubindex++) { - // read object mapping from OD - ObdSize = sizeof(qwObjectMapping); // u64 - Ret = EplObduReadEntry(pParam_p->m_uiIndex, - bMappSubindex, &qwObjectMapping, - &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - pParam_p->m_dwAbortCode = - EPL_SDOAC_GENERAL_ERROR; - goto Exit; - } - // check object mapping - Ret = EplPdouCheckObjectMapping(qwObjectMapping, - AccessType, - &pParam_p-> - m_dwAbortCode, - &uiCurPdoSize); - if (Ret != kEplSuccessful) { // illegal object mapping - goto Exit; - } - - if (uiCurPdoSize > wMaxPdoSize) { // mapping exceeds object size - pParam_p->m_dwAbortCode = - EPL_SDOAC_GENERAL_ERROR; - Ret = kEplPdoVarNotFound; - } - - } - - } else { // ObjectMapping - Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex); - if (Ret != kEplSuccessful) { // PDO is valid or does not exist - goto Exit; - } - // check existence of object and validity of object length - - qwObjectMapping = *((u64 *) pParam_p->m_pArg); - - Ret = EplPdouCheckObjectMapping(qwObjectMapping, - AccessType, - &pParam_p->m_dwAbortCode, - &uiCurPdoSize); - - } - - Exit: - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplPdouCheckPdoValidity -// -// Description: check if PDO is valid -// -// Parameters: pParam_p = OBD parameter -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p, - unsigned int uiIndex_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplObdSize ObdSize; - u8 bObjectCount; - - ObdSize = 1; - // read number of mapped objects from OD; this indicates if the PDO is valid - Ret = EplObduReadEntry(uiIndex_p, 0x00, &bObjectCount, &ObdSize); - if (Ret != kEplSuccessful) { // other fatal error occured - pParam_p->m_dwAbortCode = - EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY; - goto Exit; - } - // entry read successfully - if (bObjectCount != 0) { // PDO in OD is still valid - pParam_p->m_dwAbortCode = EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY; - Ret = kEplPdoNotExist; - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdouDecodeObjectMapping -// -// Description: decodes the given object mapping entry into index, subindex, -// bit offset and bit size. -// -// Parameters: qwObjectMapping_p = object mapping entry -// puiIndex_p = [OUT] pointer to object index -// puiSubIndex_p = [OUT] pointer to subindex -// puiBitOffset_p = [OUT] pointer to bit offset -// puiBitSize_p = [OUT] pointer to bit size -// -// Returns: (void) -// -// State: -// -//--------------------------------------------------------------------------- - -static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p, - unsigned int *puiIndex_p, - unsigned int *puiSubIndex_p, - unsigned int *puiBitOffset_p, - unsigned int *puiBitSize_p) -{ - *puiIndex_p = (unsigned int) - (qwObjectMapping_p & 0x000000000000FFFFLL); - - *puiSubIndex_p = (unsigned int) - ((qwObjectMapping_p & 0x0000000000FF0000LL) >> 16); - - *puiBitOffset_p = (unsigned int) - ((qwObjectMapping_p & 0x0000FFFF00000000LL) >> 32); - - *puiBitSize_p = (unsigned int) - ((qwObjectMapping_p & 0xFFFF000000000000LL) >> 48); - -} - -//--------------------------------------------------------------------------- -// -// Function: EplPdouCheckObjectMapping -// -// Description: checks the given object mapping entry. -// -// Parameters: qwObjectMapping_p = object mapping entry -// AccessType_p = access type to mapped object: -// write = RPDO and read = TPDO -// puiPdoSize_p = [OUT] pointer to covered PDO size -// (offset + size) in byte; -// 0 if mapping failed -// pdwAbortCode_p = [OUT] pointer to SDO abort code; -// 0 if mapping is possible -// -// Returns: tEplKernel = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p, - tEplObdAccess AccessType_p, - u32 * pdwAbortCode_p, - unsigned int *puiPdoSize_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplObdSize ObdSize; - unsigned int uiIndex; - unsigned int uiSubIndex; - unsigned int uiBitOffset; - unsigned int uiBitSize; - tEplObdAccess AccessType; - BOOL fNumerical; - - if (qwObjectMapping_p == 0) { // discard zero value - *puiPdoSize_p = 0; - goto Exit; - } - // decode object mapping - EplPdouDecodeObjectMapping(qwObjectMapping_p, - &uiIndex, - &uiSubIndex, &uiBitOffset, &uiBitSize); - - if ((uiBitOffset & 0x7) != 0x0) { // bit mapping is not supported - *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR; - Ret = kEplPdoGranularityMismatch; - goto Exit; - } - - if ((uiBitSize & 0x7) != 0x0) { // bit mapping is not supported - *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR; - Ret = kEplPdoGranularityMismatch; - goto Exit; - } - // check access type - Ret = EplObduGetAccessType(uiIndex, uiSubIndex, &AccessType); - if (Ret != kEplSuccessful) { // entry doesn't exist - *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST; - goto Exit; - } - - if ((AccessType & kEplObdAccPdo) == 0) { // object is not mappable - *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE; - Ret = kEplPdoVarNotFound; - goto Exit; - } - - if ((AccessType & AccessType_p) == 0) { // object is not writeable (RPDO) or readable (TPDO) respectively - *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE; - Ret = kEplPdoVarNotFound; - goto Exit; - } - - ObdSize = EplObduGetDataSize(uiIndex, uiSubIndex); - if (ObdSize < (uiBitSize >> 3)) { // object does not exist or has smaller size - *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR; - Ret = kEplPdoVarNotFound; - } - - Ret = EplObduIsNumerical(uiIndex, uiSubIndex, &fNumerical); - if (Ret != kEplSuccessful) { // entry doesn't exist - *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST; - goto Exit; - } - - if ((fNumerical != FALSE) - && ((uiBitSize >> 3) != ObdSize)) { - // object is numerical, - // therefor size has to fit, but it does not. - *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR; - Ret = kEplPdoVarNotFound; - goto Exit; - } - // calucaled needed PDO size - *puiPdoSize_p = (uiBitOffset >> 3) + (uiBitSize >> 3); - - Exit: - return Ret; -} - -#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h deleted file mode 100644 index 8002e0cc4d9..00000000000 --- a/drivers/staging/epl/EplSdo.h +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for api function of the sdo module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdo.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" -#include "EplFrame.h" -#include "EplSdoAc.h" - -#ifndef _EPLSDO_H_ -#define _EPLSDO_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- -// global defines -#ifndef EPL_SDO_MAX_PAYLOAD -#define EPL_SDO_MAX_PAYLOAD 256 -#endif - -// handle between Protocol Abstraction Layer and asynchronous SDO Sequence Layer -#define EPL_SDO_UDP_HANDLE 0x8000 -#define EPL_SDO_ASND_HANDLE 0x4000 -#define EPL_SDO_ASY_HANDLE_MASK 0xC000 -#define EPL_SDO_ASY_INVALID_HDL 0x3FFF - -// handle between SDO Sequence Layer and sdo command layer -#define EPL_SDO_ASY_HANDLE 0x8000 -#define EPL_SDO_PDO_HANDLE 0x4000 -#define EPL_SDO_SEQ_HANDLE_MASK 0xC000 -#define EPL_SDO_SEQ_INVALID_HDL 0x3FFF - -#define EPL_ASND_HEADER_SIZE 4 -//#define EPL_SEQ_HEADER_SIZE 4 -#define EPL_ETHERNET_HEADER_SIZE 14 - -#define EPL_SEQ_NUM_MASK 0xFC - -// size for send buffer and history -#define EPL_MAX_SDO_FRAME_SIZE EPL_C_IP_MIN_MTU -// size for receive frame -// -> needed because SND-Kit sends up to 1518 Byte -// without Sdo-Command: Maximum Segment Size -#define EPL_MAX_SDO_REC_FRAME_SIZE EPL_C_IP_MAX_MTU - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- -// handle between Protocol Abstraction Layer and asynchronuus SDO Sequence Layer -typedef unsigned int tEplSdoConHdl; - -// callback function pointer for Protocol Abstraction Layer to call -// asynchronuus SDO Sequence Layer -typedef tEplKernel(*tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p, - tEplAsySdoSeq *pSdoSeqData_p, - unsigned int uiDataSize_p); - -// handle between asynchronuus SDO Sequence Layer and SDO Command layer -typedef unsigned int tEplSdoSeqConHdl; - -// callback function pointer for asynchronuus SDO Sequence Layer to call -// SDO Command layer for received data -typedef tEplKernel(* tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoCom *pAsySdoCom_p, - unsigned int uiDataSize_p); - -// status of connection -typedef enum { - kAsySdoConStateConnected = 0x00, - kAsySdoConStateInitError = 0x01, - kAsySdoConStateConClosed = 0x02, - kAsySdoConStateAckReceived = 0x03, - kAsySdoConStateFrameSended = 0x04, - kAsySdoConStateTimeout = 0x05 -} tEplAsySdoConState; - -// callback function pointer for asynchronuus SDO Sequence Layer to call -// SDO Command layer for connection status -typedef tEplKernel(* tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoConState AsySdoConState_p); - -// handle between SDO Command layer and application -typedef unsigned int tEplSdoComConHdl; - -// status of connection -typedef enum { - kEplSdoComTransferNotActive = 0x00, - kEplSdoComTransferRunning = 0x01, - kEplSdoComTransferTxAborted = 0x02, - kEplSdoComTransferRxAborted = 0x03, - kEplSdoComTransferFinished = 0x04, - kEplSdoComTransferLowerLayerAbort = 0x05 -} tEplSdoComConState; - -// SDO Services and Command-Ids from DS 1.0.0 p.152 -typedef enum { - kEplSdoServiceNIL = 0x00, - kEplSdoServiceWriteByIndex = 0x01, - kEplSdoServiceReadByIndex = 0x02 - //-------------------------------- - // the following services are optional and - // not supported now -/* - kEplSdoServiceWriteAllByIndex = 0x03, - kEplSdoServiceReadAllByIndex = 0x04, - kEplSdoServiceWriteByName = 0x05, - kEplSdoServiceReadByName = 0x06, - - kEplSdoServiceFileWrite = 0x20, - kEplSdoServiceFileRead = 0x21, - - kEplSdoServiceWriteMultiByIndex = 0x31, - kEplSdoServiceReadMultiByIndex = 0x32, - - kEplSdoServiceMaxSegSize = 0x70 - - // 0x80 - 0xFF manufacturer specific - - */ -} tEplSdoServiceType; - -// describes if read or write access -typedef enum { - kEplSdoAccessTypeRead = 0x00, - kEplSdoAccessTypeWrite = 0x01 -} tEplSdoAccessType; - -typedef enum { - kEplSdoTypeAuto = 0x00, - kEplSdoTypeUdp = 0x01, - kEplSdoTypeAsnd = 0x02, - kEplSdoTypePdo = 0x03 -} tEplSdoType; - -typedef enum { - kEplSdoTransAuto = 0x00, - kEplSdoTransExpedited = 0x01, - kEplSdoTransSegmented = 0x02 -} tEplSdoTransType; - -// structure to inform application about finish of SDO transfer -typedef struct { - tEplSdoComConHdl m_SdoComConHdl; - tEplSdoComConState m_SdoComConState; - u32 m_dwAbortCode; - tEplSdoAccessType m_SdoAccessType; - unsigned int m_uiNodeId; // NodeId of the target - unsigned int m_uiTargetIndex; // index which was accessed - unsigned int m_uiTargetSubIndex; // subindex which was accessed - unsigned int m_uiTransferredByte; // number of bytes transferred - void *m_pUserArg; // user definable argument pointer - -} tEplSdoComFinished; - -// callback function pointer to inform application about connection -typedef tEplKernel(* tEplSdoFinishedCb) (tEplSdoComFinished *pSdoComFinished_p); - -// structure to init SDO transfer to Read or Write by Index -typedef struct { - tEplSdoComConHdl m_SdoComConHdl; - unsigned int m_uiIndex; - unsigned int m_uiSubindex; - void *m_pData; - unsigned int m_uiDataSize; - unsigned int m_uiTimeout; // not used in this version - tEplSdoAccessType m_SdoAccessType; - tEplSdoFinishedCb m_pfnSdoFinishedCb; - void *m_pUserArg; // user definable argument pointer - -} tEplSdoComTransParamByIndex; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPLSDO_H_ diff --git a/drivers/staging/epl/EplSdoAc.h b/drivers/staging/epl/EplSdoAc.h deleted file mode 100644 index 400fb38ce3e..00000000000 --- a/drivers/staging/epl/EplSdoAc.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: definitions for SDO Abort codes - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoAc.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/30 k.t.: first implementation - -****************************************************************************/ - -#ifndef _EPLSDOAC_H_ -#define _EPLSDOAC_H_ - -// ========================================================================= -// SDO abort codes -// ========================================================================= - -#define EPL_SDOAC_TIME_OUT 0x05040000L -#define EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER 0x05040001L -#define EPL_SDOAC_INVALID_BLOCK_SIZE 0x05040002L -#define EPL_SDOAC_INVALID_SEQUENCE_NUMBER 0x05040003L -#define EPL_SDOAC_OUT_OF_MEMORY 0x05040005L -#define EPL_SDOAC_UNSUPPORTED_ACCESS 0x06010000L -#define EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ 0x06010001L -#define EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ 0x06010002L -#define EPL_SDOAC_OBJECT_NOT_EXIST 0x06020000L -#define EPL_SDOAC_OBJECT_NOT_MAPPABLE 0x06040041L -#define EPL_SDOAC_PDO_LENGTH_EXCEEDED 0x06040042L -#define EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY 0x06040043L -#define EPL_SDOAC_INVALID_HEARTBEAT_DEC 0x06040044L -#define EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY 0x06040047L -#define EPL_SDOAC_ACCESS_FAILED_DUE_HW_ERROR 0x06060000L -#define EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH 0x06070010L -#define EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH 0x06070012L -#define EPL_SDOAC_DATA_TYPE_LENGTH_TOO_LOW 0x06070013L -#define EPL_SDOAC_SUB_INDEX_NOT_EXIST 0x06090011L -#define EPL_SDOAC_VALUE_RANGE_EXCEEDED 0x06090030L -#define EPL_SDOAC_VALUE_RANGE_TOO_HIGH 0x06090031L -#define EPL_SDOAC_VALUE_RANGE_TOO_LOW 0x06090032L -#define EPL_SDOAC_MAX_VALUE_LESS_MIN_VALUE 0x06090036L -#define EPL_SDOAC_GENERAL_ERROR 0x08000000L -#define EPL_SDOAC_DATA_NOT_TRANSF_OR_STORED 0x08000020L -#define EPL_SDOAC_DATA_NOT_TRANSF_DUE_LOCAL_CONTROL 0x08000021L -#define EPL_SDOAC_DATA_NOT_TRANSF_DUE_DEVICE_STATE 0x08000022L -#define EPL_SDOAC_OBJECT_DICTIONARY_NOT_EXIST 0x08000023L -#define EPL_SDOAC_CONFIG_DATA_EMPTY 0x08000024L - -#endif // _EPLSDOAC_H_ - -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler -// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c deleted file mode 100644 index aa8bdef317c..00000000000 --- a/drivers/staging/epl/EplSdoAsndu.c +++ /dev/null @@ -1,483 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for SDO/Asnd-Protocolabstractionlayer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoAsndu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.7 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/07 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplSdoAsndu.h" -#include "user/EplDlluCal.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_SDO_MAX_CONNECTION_ASND -#define EPL_SDO_MAX_CONNECTION_ASND 5 -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -// instance table -typedef struct { - unsigned int m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND]; - tEplSequLayerReceiveCb m_fpSdoAsySeqCb; - -} tEplSdoAsndInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplSdoAsndInstance SdoAsndInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: EPL SDO-Asnd Protocolabstraction layer -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduInit -// -// Description: init first instance of the module -// -// -// -// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer -// callback-function -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p) -{ - tEplKernel Ret; - - Ret = EplSdoAsnduAddInstance(fpReceiveCb_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduAddInstance -// -// Description: init additional instance of the module -// -// -// -// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer -// callback-function -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // init control structure - EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g)); - - // save pointer to callback-function - if (fpReceiveCb_p != NULL) { - SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p; - } else { - Ret = kEplSdoUdpMissCb; - } - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalRegAsndService(kEplDllAsndSdo, - EplSdoAsnduCb, kEplDllAsndFilterLocal); -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduDelInstance -// -// Description: del instance of the module -// del socket and del Listen-Thread -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - // deregister callback function from DLL - Ret = EplDlluCalRegAsndService(kEplDllAsndSdo, - NULL, kEplDllAsndFilterNone); -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduInitCon -// -// Description: init a new connect -// -// -// -// Parameters: pSdoConHandle_p = pointer for the new connection handle -// uiTargetNodeId_p = NodeId of the target node -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p, - unsigned int uiTargetNodeId_p) -{ - tEplKernel Ret; - unsigned int uiCount; - unsigned int uiFreeCon; - unsigned int *puiConnection; - - Ret = kEplSuccessful; - - if ((uiTargetNodeId_p == EPL_C_ADR_INVALID) - || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) { - Ret = kEplSdoAsndInvalidNodeId; - goto Exit; - } - // get free entry in control structure - uiCount = 0; - uiFreeCon = EPL_SDO_MAX_CONNECTION_ASND; - puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0]; - while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) { - if (*puiConnection == uiTargetNodeId_p) { // existing connection to target node found - // save handle for higher layer - *pSdoConHandle_p = (uiCount | EPL_SDO_ASND_HANDLE); - - goto Exit; - } else if (*puiConnection == 0) { // free entry-> save target nodeId - uiFreeCon = uiCount; - } - uiCount++; - puiConnection++; - } - - if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND) { - // no free connection - Ret = kEplSdoAsndNoFreeHandle; - } else { - puiConnection = - &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon]; - *puiConnection = uiTargetNodeId_p; - // save handle for higher layer - *pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE); - - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduSendData -// -// Description: send data using exisiting connection -// -// -// -// Parameters: SdoConHandle_p = connection handle -// pSrcData_p = pointer to data -// dwDataSize_p = number of databyte -// -> without asnd-header!!! -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p, - tEplFrame *pSrcData_p, - u32 dwDataSize_p) -{ - tEplKernel Ret; - unsigned int uiArray; - tEplFrameInfo FrameInfo; - - Ret = kEplSuccessful; - - uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK); - - if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) { - Ret = kEplSdoAsndInvalidHandle; - goto Exit; - } - // fillout Asnd header - // own node id not needed -> filled by DLL - - // set message type - AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (u8) kEplMsgTypeAsnd); // ASnd == 0x06 - // target node id - AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, - (u8) SdoAsndInstance_g. - m_auiSdoAsndConnection[uiArray]); - // set source-nodeid (filled by DLL 0) - AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00); - - // calc size - dwDataSize_p += EPL_ASND_HEADER_SIZE; - - // send function of DLL - FrameInfo.m_uiFrameSize = dwDataSize_p; - FrameInfo.m_pFrame = pSrcData_p; - EPL_MEMSET(&FrameInfo.m_NetTime, 0x00, sizeof(tEplNetTime)); -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - Ret = EplDlluCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric); -#endif - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduDelCon -// -// Description: delete connection from intern structure -// -// -// -// Parameters: SdoConHandle_p = connection handle -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p) -{ - tEplKernel Ret; - unsigned int uiArray; - - Ret = kEplSuccessful; - - uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK); - // check parameter - if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) { - Ret = kEplSdoAsndInvalidHandle; - goto Exit; - } - // set target nodeId to 0 - SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0; - - Exit: - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsnduCb -// -// Description: callback function for SDO ASnd frames -// -// -// -// Parameters: pFrameInfo_p = Frame with SDO payload -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiCount; - unsigned int *puiConnection; - unsigned int uiNodeId; - unsigned int uiFreeEntry = 0xFFFF; - tEplSdoConHdl SdoConHdl; - tEplFrame *pFrame; - - pFrame = pFrameInfo_p->m_pFrame; - - uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId); - - // search corresponding entry in control structure - uiCount = 0; - puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0]; - while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) { - if (uiNodeId == *puiConnection) { - break; - } else if ((*puiConnection == 0) - && (uiFreeEntry == 0xFFFF)) { // free entry - uiFreeEntry = uiCount; - } - uiCount++; - puiConnection++; - } - - if (uiCount == EPL_SDO_MAX_CONNECTION_ASND) { - if (uiFreeEntry != 0xFFFF) { - puiConnection = - &SdoAsndInstance_g. - m_auiSdoAsndConnection[uiFreeEntry]; - *puiConnection = uiNodeId; - uiCount = uiFreeEntry; - } else { - EPL_DBGLVL_SDO_TRACE0 - ("EplSdoAsnduCb(): no free handle\n"); - goto Exit; - } - } -// if (uiNodeId == *puiConnection) - { // entry found or created - SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE); - - SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl, - &pFrame->m_Data.m_Asnd. - m_Payload.m_SdoSequenceFrame, - (pFrameInfo_p->m_uiFrameSize - - 18)); - } - - Exit: - return Ret; - -} - -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) -// EOF diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c deleted file mode 100644 index 256d7086634..00000000000 --- a/drivers/staging/epl/EplSdoAsySequ.c +++ /dev/null @@ -1,2522 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for asychronous SDO Sequence Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoAsySequ.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.10 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplSdoAsySequ.h" - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) == 0) &&\ - (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) == 0) ) - -#error 'ERROR: At least UDP or Asnd module needed!' - -#endif -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define EPL_SDO_HISTORY_SIZE 5 - -#ifndef EPL_MAX_SDO_SEQ_CON -#define EPL_MAX_SDO_SEQ_CON 10 -#endif - -#define EPL_SEQ_DEFAULT_TIMEOUT 5000 // in [ms] => 5 sec - -#define EPL_SEQ_RETRY_COUNT 5 // => max. Timeout 30 sec - -#define EPL_SEQ_NUM_THRESHOLD 100 // threshold which distinguishes between old and new sequence numbers - -// define frame with size of Asnd-Header-, SDO Sequenze Header size, SDO Command header -// and Ethernet-Header size -#define EPL_SEQ_FRAME_SIZE 24 -// size of the header of the asynchronus SDO Sequence layer -#define EPL_SEQ_HEADER_SIZE 4 - -// buffersize for one frame in history -#define EPL_SEQ_HISTROY_FRAME_SIZE EPL_MAX_SDO_FRAME_SIZE - -// mask to get scon and rcon -#define EPL_ASY_SDO_CON_MASK 0x03 - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -// events for processfunction -typedef enum { - kAsySdoSeqEventNoEvent = 0x00, // no Event - kAsySdoSeqEventInitCon = 0x01, // init connection - kAsySdoSeqEventFrameRec = 0x02, // frame received - kAsySdoSeqEventFrameSend = 0x03, // frame to send - kAsySdoSeqEventTimeout = 0x04, // Timeout for connection - kAsySdoSeqEventCloseCon = 0x05 // higher layer close connection -} tEplAsySdoSeqEvent; - -// structure for History-Buffer -typedef struct { - u8 m_bFreeEntries; - u8 m_bWrite; // index of the next free buffer entry - u8 m_bAck; // index of the next message which should become acknowledged - u8 m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission - u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE] - [EPL_SEQ_HISTROY_FRAME_SIZE]; - unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE]; - -} tEplAsySdoConHistory; - -// state of the statemaschine -typedef enum { - kEplAsySdoStateIdle = 0x00, - kEplAsySdoStateInit1 = 0x01, - kEplAsySdoStateInit2 = 0x02, - kEplAsySdoStateInit3 = 0x03, - kEplAsySdoStateConnected = 0x04, - kEplAsySdoStateWaitAck = 0x05 -} tEplAsySdoState; - -// connection control structure -typedef struct { - tEplSdoConHdl m_ConHandle; - tEplAsySdoState m_SdoState; - u8 m_bRecSeqNum; // name from view of the communication partner - u8 m_bSendSeqNum; // name from view of the communication partner - tEplAsySdoConHistory m_SdoConHistory; - tEplTimerHdl m_EplTimerHdl; - unsigned int m_uiRetryCount; // retry counter - unsigned int m_uiUseCount; // one sequence layer connection may be used by - // multiple command layer connections - -} tEplAsySdoSeqCon; - -// instance structure -typedef struct { - tEplAsySdoSeqCon m_AsySdoConnection[EPL_MAX_SDO_SEQ_CON]; - tEplSdoComReceiveCb m_fpSdoComReceiveCb; - tEplSdoComConCb m_fpSdoComConCb; - -#if defined(WIN32) || defined(_WIN32) - LPCRITICAL_SECTION m_pCriticalSection; - CRITICAL_SECTION m_CriticalSection; - - LPCRITICAL_SECTION m_pCriticalSectionReceive; - CRITICAL_SECTION m_CriticalSectionReceive; -#endif - -} tEplAsySdoSequInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplAsySdoSequInstance AsySdoSequInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - tEplAsySdoSeq * pRecFrame_p, - tEplAsySdoSeqEvent Event_p); - -static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - BOOL fFrameInHistory); - -static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pEplFrame_p); - -tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p, - tEplAsySdoSeq *pSdoSeqData_p, - unsigned int uiDataSize_p); - -static tEplKernel EplSdoAsyInitHistory(void); - -static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame * pFrame_p, - unsigned int uiSize_p); - -static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - u8 bRecSeqNumber_p); - -static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame ** ppFrame_p, - unsigned int *puiSize_p, - BOOL fInitRead); - -static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon * - pAsySdoSeqCon_p); - -static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned long ulTimeout); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: this module contains the asynchronus SDO Sequence Layer for -// the EPL SDO service -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqInit -// -// Description: init first instance -// -// -// -// Parameters: fpSdoComCb_p = callback function to inform Command layer -// about new frames -// fpSdoComConCb_p = callback function to inform command layer -// about connection state -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p) -{ - tEplKernel Ret; - - Ret = EplSdoAsySeqAddInstance(fpSdoComCb_p, fpSdoComConCb_p); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqAddInstance -// -// Description: init following instances -// -// -// -// Parameters: fpSdoComCb_p = callback function to inform Command layer -// about new frames -// fpSdoComConCb_p = callback function to inform command layer -// about connection state -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // check functionpointer - if (fpSdoComCb_p == NULL) { - Ret = kEplSdoSeqMissCb; - goto Exit; - } else { - AsySdoSequInstance_g.m_fpSdoComReceiveCb = fpSdoComCb_p; - } - - // check functionpointer - if (fpSdoComConCb_p == NULL) { - Ret = kEplSdoSeqMissCb; - goto Exit; - } else { - AsySdoSequInstance_g.m_fpSdoComConCb = fpSdoComConCb_p; - } - - // set controllstructure to 0 - EPL_MEMSET(&AsySdoSequInstance_g.m_AsySdoConnection[0], 0x00, - sizeof(AsySdoSequInstance_g.m_AsySdoConnection)); - - // init History - Ret = EplSdoAsyInitHistory(); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if defined(WIN32) || defined(_WIN32) - // create critical section for process function - AsySdoSequInstance_g.m_pCriticalSection = - &AsySdoSequInstance_g.m_CriticalSection; - InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); - - // init critical section for receive cb function - AsySdoSequInstance_g.m_pCriticalSectionReceive = - &AsySdoSequInstance_g.m_CriticalSectionReceive; - InitializeCriticalSection(AsySdoSequInstance_g. - m_pCriticalSectionReceive); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // init lower layer - Ret = EplSdoUdpuAddInstance(EplSdoAsyReceiveCb); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // init lower layer - Ret = EplSdoAsnduAddInstance(EplSdoAsyReceiveCb); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqDelInstance -// -// Description: delete instances -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqDelInstance(void) -{ - tEplKernel Ret; - unsigned int uiCount; - tEplAsySdoSeqCon *pAsySdoSeqCon; - - Ret = kEplSuccessful; - - // delete timer of open connections - uiCount = 0; - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0]; - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle != 0) { - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - } - uiCount++; - pAsySdoSeqCon++; - } - -#if defined(WIN32) || defined(_WIN32) - // delete critical section for process function - DeleteCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - - // set instance-table to 0 - EPL_MEMSET(&AsySdoSequInstance_g, 0x00, sizeof(AsySdoSequInstance_g)); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // delete lower layer - Ret = EplSdoUdpuDelInstance(); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // delete lower layer - Ret = EplSdoAsnduDelInstance(); -#endif - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqInitCon -// -// Description: start initialization of a sequence layer connection. -// It tries to reuse an existing connection to the same node. -// -// -// Parameters: pSdoSeqConHdl_p = pointer to the variable for the connection handle -// uiNodeId_p = Node Id of the target -// SdoType = Type of the SDO connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p, - unsigned int uiNodeId_p, - tEplSdoType SdoType) -{ - tEplKernel Ret; - unsigned int uiCount; - unsigned int uiFreeCon; - tEplSdoConHdl ConHandle; - tEplAsySdoSeqCon *pAsySdoSeqCon; - Ret = kEplSuccessful; - - // check SdoType - // call init function of the protcol abstraction layer - // which tries to find an existing connection to the same node - switch (SdoType) { - // SDO over UDP - case kEplSdoTypeUdp: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuInitCon(&ConHandle, uiNodeId_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - break; - } - - // SDO over Asnd - case kEplSdoTypeAsnd: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduInitCon(&ConHandle, uiNodeId_p); - if (Ret != kEplSuccessful) { - goto Exit; - } -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - break; - } - - // unsupported protocols - // -> auto should be replaced by command layer - case kEplSdoTypeAuto: - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoSeqUnsupportedProt; - goto Exit; - } - - } // end of switch(SdoType) - - // find existing connection to the same node or find empty entry for connection - uiCount = 0; - uiFreeCon = EPL_MAX_SDO_SEQ_CON; - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0]; - - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle == ConHandle) { // existing connection found - break; - } - if (pAsySdoSeqCon->m_ConHandle == 0) { - uiFreeCon = uiCount; - } - uiCount++; - pAsySdoSeqCon++; - } - - if (uiCount == EPL_MAX_SDO_SEQ_CON) { - if (uiFreeCon == EPL_MAX_SDO_SEQ_CON) { // no free entry found - switch (SdoType) { - // SDO over UDP - case kEplSdoTypeUdp: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuDelCon(ConHandle); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - break; - } - - // SDO over Asnd - case kEplSdoTypeAsnd: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduDelCon(ConHandle); - if (Ret != kEplSuccessful) { - goto Exit; - } -#endif - break; - } - - // unsupported protocols - // -> auto should be replaced by command layer - case kEplSdoTypeAuto: - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoSeqUnsupportedProt; - goto Exit; - } - - } // end of switch(SdoType) - - Ret = kEplSdoSeqNoFreeHandle; - goto Exit; - } else { // free entry found - pAsySdoSeqCon = - &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeCon]; - pAsySdoSeqCon->m_ConHandle = ConHandle; - uiCount = uiFreeCon; - } - } - // set handle - *pSdoSeqConHdl_p = (uiCount | EPL_SDO_ASY_HANDLE); - - // increment use counter - pAsySdoSeqCon->m_uiUseCount++; - - // call intern process function - Ret = EplSdoAsySeqProcess(uiCount, - 0, NULL, NULL, kAsySdoSeqEventInitCon); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendData -// -// Description: send sata unsing a established connection -// -// -// -// Parameters: pSdoSeqConHdl_p = connection handle -// uiDataSize_p = Size of Frame to send -// -> wihtout SDO sequence layer header, Asnd header -// and ethernetnet -// ==> SDO Sequence layer payload -// SdoType = Type of the SDO connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p, - unsigned int uiDataSize_p, - tEplFrame *pabData_p) -{ - tEplKernel Ret; - unsigned int uiHandle; - - uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK); - - // check if connection ready - if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState == - kEplAsySdoStateIdle) { - // no connection with this handle - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } else if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle]. - m_SdoState != kEplAsySdoStateConnected) { - Ret = kEplSdoSeqConnectionBusy; - goto Exit; - } - - Ret = EplSdoAsySeqProcess(uiHandle, - uiDataSize_p, - pabData_p, NULL, kAsySdoSeqEventFrameSend); - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqProcessEvent -// -// Description: function processes extern events -// -> later needed for timeout controll with timer-module -// -// -// -// Parameters: pEvent_p = pointer to event -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p) -{ - tEplKernel Ret; - tEplTimerEventArg *pTimerEventArg; - tEplAsySdoSeqCon *pAsySdoSeqCon; - tEplTimerHdl EplTimerHdl; - unsigned int uiCount; - - Ret = kEplSuccessful; - // check parameter - if (pEvent_p == NULL) { - Ret = kEplSdoSeqInvalidEvent; - goto Exit; - } - - if (pEvent_p->m_EventType != kEplEventTypeTimer) { - Ret = kEplSdoSeqInvalidEvent; - goto Exit; - } - // get timerhdl - pTimerEventArg = (tEplTimerEventArg *) pEvent_p->m_pArg; - EplTimerHdl = pTimerEventArg->m_TimerHdl; - - // get pointer to intern control structure of connection - if (pTimerEventArg->m_ulArg == 0) { - goto Exit; - } - pAsySdoSeqCon = (tEplAsySdoSeqCon *) pTimerEventArg->m_ulArg; - - // check if time is current - if (EplTimerHdl != pAsySdoSeqCon->m_EplTimerHdl) { - // delete timer - EplTimeruDeleteTimer(&EplTimerHdl); - goto Exit; - } - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - - // get indexnumber of control structure - uiCount = 0; - while ((&AsySdoSequInstance_g.m_AsySdoConnection[uiCount]) != - pAsySdoSeqCon) { - uiCount++; - if (uiCount > EPL_MAX_SDO_SEQ_CON) { - goto Exit; - } - } - - // process event and call processfunction if needed - Ret = EplSdoAsySeqProcess(uiCount, - 0, NULL, NULL, kAsySdoSeqEventTimeout); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqDelCon -// -// Description: del and close one connection -// -// -// -// Parameters: SdoSeqConHdl_p = handle of connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiHandle; - tEplAsySdoSeqCon *pAsySdoSeqCon; - - uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK); - - // check if handle invalid - if (uiHandle >= EPL_MAX_SDO_SEQ_CON) { - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } - // get pointer to connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle]; - - // decrement use counter - pAsySdoSeqCon->m_uiUseCount--; - - if (pAsySdoSeqCon->m_uiUseCount == 0) { - // process close in processfunction - Ret = EplSdoAsySeqProcess(uiHandle, - 0, - NULL, NULL, kAsySdoSeqEventCloseCon); - - //check protocol - if ((pAsySdoSeqCon->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == - EPL_SDO_UDP_HANDLE) { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - // call close function of lower layer - EplSdoUdpuDelCon(pAsySdoSeqCon->m_ConHandle); -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - } else { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - // call close function of lower layer - EplSdoAsnduDelCon(pAsySdoSeqCon->m_ConHandle); -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - } - - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl); - - // clean controllstructure - EPL_MEMSET(pAsySdoSeqCon, 0x00, sizeof(tEplAsySdoSeqCon)); - pAsySdoSeqCon->m_SdoConHistory.m_bFreeEntries = - EPL_SDO_HISTORY_SIZE; - } - - Exit: - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplEplSdoAsySeqProcess -// -// Description: intern function to process the asynchronus SDO Sequence Layer -// state maschine -// -// -// -// Parameters: uiHandle_p = index of the control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of sequence header and Asnd header!!! -// -// pData_p = pointer to frame to send (can be NULL) -// pRecFrame_p = pointer to received frame (can be NULL) -// Event_p = Event to process -// -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - tEplAsySdoSeq * pRecFrame_p, - tEplAsySdoSeqEvent Event_p) -{ - tEplKernel Ret; - unsigned int uiFrameSize; - tEplFrame *pEplFrame; - tEplAsySdoSeqCon *pAsySdoSeqCon; - tEplSdoSeqConHdl SdoSeqConHdl; - unsigned int uiFreeEntries; - -#if defined(WIN32) || defined(_WIN32) - // enter critical section for process function - EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - - Ret = kEplSuccessful; - - // get handle for hinger layer - SdoSeqConHdl = uiHandle_p | EPL_SDO_ASY_HANDLE; - - // check if handle invalid - if ((SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == - EPL_SDO_SEQ_INVALID_HDL) { - Ret = kEplSdoSeqInvalidHdl; - goto Exit; - } - // get pointer to connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle_p]; - - // check size - if ((pData_p == NULL) && (pRecFrame_p == NULL) && (uiDataSize_p != 0)) { - Ret = kEplSdoSeqInvalidFrame; - goto Exit; - } - // check state - switch (pAsySdoSeqCon->m_SdoState) { - // idle state - case kEplAsySdoStateIdle: - { - // check event - switch (Event_p) { - // new connection - // -> send init frame and change to - // kEplAsySdoStateInit1 - case kAsySdoSeqEventInitCon: - { - // set sending scon to 1 - pAsySdoSeqCon->m_bRecSeqNum = 0x01; - // set set send rcon to 0 - pAsySdoSeqCon->m_bSendSeqNum = 0x00; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit1; - - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - break; - } - - // init con from extern - // check rcon and scon - // -> send answer - case kAsySdoSeqEventFrameRec: - { -/* - PRINTF3("%s scon=%u rcon=%u\n", - __func__, - pRecFrame_p->m_le_bSendSeqNumCon, - pRecFrame_p->m_le_bRecSeqNumCon); -*/ - // check if scon == 1 and rcon == 0 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x00) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit2 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit2; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - } else { // error -> close - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 1 - // wait for frame with scon = 1 - // and rcon = 1 - case kEplAsySdoStateInit1: - { -// PRINTF0("EplSdoAsySequ: StateInit1\n"); - - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 1 and rcon == 1 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)) { // create answer own scon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit3 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit3; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - } - // check if scon == 1 and rcon == 0, i.e. other side wants me to be server - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x00) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateInit2 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit2; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 2 - case kEplAsySdoStateInit2: - { -// PRINTF0("EplSdoAsySequ: StateInit2\n"); - - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 2 and rcon == 1 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) { // create answer own rcon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } - // check scon == 1 and rcon == 1, i.e. other side wants me to initiate the connection - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // create answer and send answer - // set rcon to 1 (in send direction own scon) - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // change state to kEplAsySdoStateInit3 - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateInit3; - - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // init connection step 3 - case kEplAsySdoStateInit3: - { - // check event - switch (Event_p) { - // frame received - case kAsySdoSeqEventFrameRec: - { - // check scon == 2 and rcon == 2 - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x02) - && - ((pRecFrame_p-> - m_le_bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) == 0x02)) { - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } - // check scon == 2 and rcon == 1 - else if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) == - 0x01) - && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) { // create answer own rcon = 2 - // save sequence numbers - pAsySdoSeqCon->m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon->m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - pAsySdoSeqCon->m_bRecSeqNum++; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - // change state to kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConnected); - - } else { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - if (((pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) != - 0x00) - || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) { // d.k. only answer with close message if the message sent was not a close message - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - // set rcon and scon to 0 - pAsySdoSeqCon-> - m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon-> - m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, - NULL, FALSE); - } - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateInitError); - } - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { // error -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateInitError); - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // connection established - case kEplAsySdoStateConnected: - { - // check event - switch (Event_p) { - - // frame to send - case kAsySdoSeqEventFrameSend: - { - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // check if data frame or ack - if (pData_p == NULL) { // send ack - // inc scon - //pAsySdoSeqCon->m_bRecSeqNum += 4; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - if (Ret != kEplSuccessful) { - goto Exit; - } - } else { // send dataframe - // increment send sequence number - pAsySdoSeqCon->m_bRecSeqNum += - 4; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - uiDataSize_p, pData_p, - TRUE); - if (Ret == kEplSdoSeqRequestAckNeeded) { // request ack - // change state to wait ack - pAsySdoSeqCon-> - m_SdoState = - kEplAsySdoStateWaitAck; - // set Ret to kEplSuccessful, because no error - // for higher layer - Ret = kEplSuccessful; - - } else if (Ret != - kEplSuccessful) { - goto Exit; - } else { - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - } - } - break; - } // end of case kAsySdoSeqEventFrameSend - - // frame received - case kAsySdoSeqEventFrameRec: - { - u8 bSendSeqNumCon = - AmiGetByteFromLe(&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // set timer - Ret = - EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - // check scon - switch (bSendSeqNumCon & - EPL_ASY_SDO_CON_MASK) { - // close from other node - case 0: - case 1: - { - // return to idle - pAsySdoSeqCon-> - m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConClosed); - - break; - } - - // Request Ack or Error Ack - // possible contain data - case 3: - // normal frame - case 2: - { - if ((AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon) - & - EPL_ASY_SDO_CON_MASK) - == 3) { -// PRINTF0("EplSdoAsySequ: error response received\n"); - - // error response (retransmission request) - // resend frames from history - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - TRUE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - - while ((pEplFrame != NULL) - && - (uiFrameSize - != 0)) { - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret - != - kEplSuccessful) - { - goto Exit; - } - // read next frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - FALSE); - if (Ret - != - kEplSuccessful) - { - goto Exit; - } - } // end of while((pabFrame != NULL) - } // end of if (error response) - - if (((pAsySdoSeqCon->m_bSendSeqNum + 4) & EPL_SEQ_NUM_MASK) == (bSendSeqNumCon & EPL_SEQ_NUM_MASK)) { // next frame of sequence received - // save send sequence number (without ack request) - pAsySdoSeqCon-> - m_bSendSeqNum - = - bSendSeqNumCon - & ~0x01; - - // check if ack or data-frame - //ignore ack -> already processed - if (uiDataSize_p - > - EPL_SEQ_HEADER_SIZE) - { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE)); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - - } else { - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateAckReceived); - } - } else if (((bSendSeqNumCon - pAsySdoSeqCon->m_bSendSeqNum - 4) & EPL_SEQ_NUM_MASK) < EPL_SEQ_NUM_THRESHOLD) { // frame of sequence was lost, - // because difference of received and old value - // is less then halve of the values range. - - // send error frame with own rcon = 3 - pAsySdoSeqCon-> - m_bSendSeqNum - |= 0x03; - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - // restore send sequence number - pAsySdoSeqCon-> - m_bSendSeqNum - = - (pAsySdoSeqCon-> - m_bSendSeqNum - & - EPL_SEQ_NUM_MASK) - | 0x02; - if (Ret != - kEplSuccessful) - { - goto Exit; - } - // break here, because a requested acknowledge - // was sent implicitly above - break; - } - // else, ignore repeated frame - - if ((bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 3) { // ack request received - - // create ack with own scon = 2 - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - } - - break; - } - - } // switch(pAsySdoSeqCon->m_bSendSeqNum & EPL_ASY_SDO_CON_MASK) - break; - } // end of case kAsySdoSeqEventFrameRec: - - //close event from higher layer - case kAsySdoSeqEventCloseCon: - { - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // delete timer - EplTimeruDeleteTimer(&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb is not necessary, because the event came from there -// AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl, -// kAsySdoConStateInitError); - break; - } - - // timeout - case kAsySdoSeqEventTimeout: - { - - uiFreeEntries = - EplSdoAsyGetFreeEntriesFromHistory - (pAsySdoSeqCon); - if ((uiFreeEntries < - EPL_SDO_HISTORY_SIZE) - && (pAsySdoSeqCon->m_uiRetryCount < EPL_SEQ_RETRY_COUNT)) { // unacknowlegded frames in history - // and retry counter not exceeded - - // resend data with acknowledge request - - // increment retry counter - pAsySdoSeqCon->m_uiRetryCount++; - - // set timer - Ret = - EplSdoAsySeqSetTimer - (pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - // read first frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, &pEplFrame, - &uiFrameSize, TRUE); - if (Ret != kEplSuccessful) { - goto Exit; - } - - if ((pEplFrame != NULL) - && (uiFrameSize != 0)) { - - // set ack request in scon - AmiSetByteToLe - (&pEplFrame->m_Data. - m_Asnd.m_Payload. - m_SdoSequenceFrame. - m_le_bSendSeqNumCon, - AmiGetByteFromLe - (&pEplFrame-> - m_Data.m_Asnd. - m_Payload. - m_SdoSequenceFrame. - m_le_bSendSeqNumCon) - | 0x03); - - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret != - kEplSuccessful) { - goto Exit; - } - - } - } else { - // timeout, because of no traffic -> Close - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= - EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, 0, NULL, - FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateTimeout); - } - - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(Event_p) - break; - } - - // wait for Acknowledge (history buffer full) - case kEplAsySdoStateWaitAck: - { - PRINTF0("EplSdoAsySequ: StateWaitAck\n"); - - // set timer - Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon, - EPL_SEQ_DEFAULT_TIMEOUT); - - //TODO: retry of acknowledge - if (Event_p == kAsySdoSeqEventFrameRec) { - // check rcon - switch (pRecFrame_p-> - m_le_bRecSeqNumCon & - EPL_ASY_SDO_CON_MASK) { - // close-frome other node - case 0: - { - // return to idle - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateIdle; - // delete timer - EplTimeruDeleteTimer - (&pAsySdoSeqCon-> - m_EplTimerHdl); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateConClosed); - - break; - } - - // normal frame - case 2: - { - // should be ack - // -> change to state kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateAckReceived); - // send data to higher layer if needed - if (uiDataSize_p > - EPL_SEQ_HEADER_SIZE) { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) - & pRecFrame_p-> - m_le_abSdoSeqPayload), - (uiDataSize_p - - EPL_SEQ_HEADER_SIZE)); - } - break; - } - - // Request Ack or Error Ack - case 3: - { - // -> change to state kEplAsySdoStateConnected - pAsySdoSeqCon->m_SdoState = - kEplAsySdoStateConnected; - - if (pRecFrame_p->m_le_bRecSeqNumCon == pAsySdoSeqCon->m_bRecSeqNum) { // ack request - // -> send ack - // save sequence numbers - pAsySdoSeqCon-> - m_bRecSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bRecSeqNumCon); - pAsySdoSeqCon-> - m_bSendSeqNum = - AmiGetByteFromLe - (&pRecFrame_p-> - m_le_bSendSeqNumCon); - - // create answer own rcon = 2 - pAsySdoSeqCon-> - m_bRecSeqNum--; - - // check if ack or data-frame - if (uiDataSize_p > - EPL_SEQ_HEADER_SIZE) - { - AsySdoSequInstance_g. - m_fpSdoComReceiveCb - (SdoSeqConHdl, - ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE)); - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb - (SdoSeqConHdl, - kAsySdoConStateFrameSended); - - } else { - Ret = - EplSdoAsySeqSendIntern - (pAsySdoSeqCon, - 0, NULL, - FALSE); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - } - - } else { - // error ack - // resend frames from history - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - TRUE); - while ((pEplFrame != - NULL) - && (uiFrameSize - != 0)) { - // send frame - Ret = - EplSdoAsySeqSendLowerLayer - (pAsySdoSeqCon, - uiFrameSize, - pEplFrame); - if (Ret != - kEplSuccessful) - { - goto Exit; - } - // read next frame - - // read frame from history - Ret = - EplSdoAsyReadFromHistory - (pAsySdoSeqCon, - &pEplFrame, - &uiFrameSize, - FALSE); - } // end of while((pabFrame != NULL) - } - break; - } - } // end of switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) - - } else if (Event_p == kAsySdoSeqEventTimeout) { // error -> Close - pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle; - // set rcon and scon to 0 - pAsySdoSeqCon->m_bSendSeqNum &= - EPL_SEQ_NUM_MASK; - pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK; - // send frame - EplSdoAsySeqSendIntern(pAsySdoSeqCon, - 0, NULL, FALSE); - - // call Command Layer Cb - AsySdoSequInstance_g. - m_fpSdoComConCb(SdoSeqConHdl, - kAsySdoConStateTimeout); - } - - break; - } - - // unknown state - default: - { - EPL_DBGLVL_SDO_TRACE0 - ("Error: Unknown State in EplSdoAsySeqProcess\n"); - - } - } // end of switch(pAsySdoSeqCon->m_SdoState) - - Exit: - -#if defined(WIN32) || defined(_WIN32) - // leave critical section for process function - LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSection); -#endif - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendIntern -// -// Description: intern function to create and send a frame -// -> if uiDataSize_p == 0 create a frame with infos from -// pAsySdoSeqCon_p -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of sequence header and Asnd header!!! -// pData_p = pointer to frame to process (can be NULL) -// fFrameInHistory = if TRUE frame is saved to history else not -// -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pData_p, - BOOL fFrameInHistory_p) -{ - tEplKernel Ret; - u8 abFrame[EPL_SEQ_FRAME_SIZE]; - tEplFrame *pEplFrame; - unsigned int uiFreeEntries; - - if (pData_p == NULL) { // set pointer to own frame - EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); - pEplFrame = (tEplFrame *) & abFrame[0]; - } else { // set pointer to frame from calling function - pEplFrame = pData_p; - } - - if (fFrameInHistory_p != FALSE) { - // check if only one free entry in history buffer - uiFreeEntries = - EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon_p); - if (uiFreeEntries == 1) { // request an acknowledge in dataframe - // own scon = 3 - pAsySdoSeqCon_p->m_bRecSeqNum |= 0x03; - } - } - // fillin header informations - // set service id sdo - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_le_bServiceId, 0x05); - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_abReserved, 0x00); - // set receive sequence number and rcon - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_bRecSeqNumCon, pAsySdoSeqCon_p->m_bSendSeqNum); - // set send sequence number and scon - AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_bSendSeqNumCon, pAsySdoSeqCon_p->m_bRecSeqNum); - - // add size - uiDataSize_p += EPL_SEQ_HEADER_SIZE; - - // forward frame to appropriate lower layer - Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon_p, uiDataSize_p, pEplFrame); // pointer to frame - - // check if all allright - if ((Ret == kEplSuccessful) - && (fFrameInHistory_p != FALSE)) { - // set own scon to 2 if needed - if ((pAsySdoSeqCon_p->m_bRecSeqNum & 0x03) == 0x03) { - pAsySdoSeqCon_p->m_bRecSeqNum--; - } - // save frame to history - Ret = EplSdoAsyAddFrameToHistory(pAsySdoSeqCon_p, - pEplFrame, uiDataSize_p); - if (Ret == kEplSdoSeqNoFreeHistory) { // request Ack needed - Ret = kEplSdoSeqRequestAckNeeded; - } - - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSendLowerLayer -// -// Description: intern function to send a previously created frame to lower layer -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of the connection -// uiDataSize_p = size of data frame to process (can be 0) -// -> without size of Asnd header!!! -// pData_p = pointer to frame to process (can be NULL) -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned int uiDataSize_p, - tEplFrame * pEplFrame_p) -{ - tEplKernel Ret; - - // call send-function - // check handle for UDP or Asnd - if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE) { // send over UDP -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - Ret = EplSdoUdpuSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p, // pointer to frame - uiDataSize_p); -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - - } else if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_ASND_HANDLE) { // ASND -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - Ret = EplSdoAsnduSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p, // pointer to frame - uiDataSize_p); -#else - Ret = kEplSdoSeqUnsupportedProt; -#endif - } else { // error - Ret = kEplSdoSeqInvalidHdl; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyReceiveCb -// -// Description: callback-function for received frames from lower layer -// -// -// -// Parameters: ConHdl_p = handle of the connection -// pSdoSeqData_p = pointer to frame -// uiDataSize_p = size of frame -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p, - tEplAsySdoSeq *pSdoSeqData_p, - unsigned int uiDataSize_p) -{ - tEplKernel Ret; - unsigned int uiCount = 0; - unsigned int uiFreeEntry = EPL_MAX_SDO_SEQ_CON; - tEplAsySdoSeqCon *pAsySdoSeqCon; - -#if defined(WIN32) || defined(_WIN32) - // enter critical section - EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive); -#endif - - EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p, - ((u8 *) pSdoSeqData_p)[0]); - - // search controll structure for this connection - pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount]; - while (uiCount < EPL_MAX_SDO_SEQ_CON) { - if (pAsySdoSeqCon->m_ConHandle == ConHdl_p) { - break; - } else if ((pAsySdoSeqCon->m_ConHandle == 0) - && (uiFreeEntry == EPL_MAX_SDO_SEQ_CON)) { - // free entry - uiFreeEntry = uiCount; - } - uiCount++; - pAsySdoSeqCon++; - } - - if (uiCount == EPL_MAX_SDO_SEQ_CON) { // new connection - if (uiFreeEntry == EPL_MAX_SDO_SEQ_CON) { - Ret = kEplSdoSeqNoFreeHandle; - goto Exit; - } else { - pAsySdoSeqCon = - &AsySdoSequInstance_g. - m_AsySdoConnection[uiFreeEntry]; - // save handle from lower layer - pAsySdoSeqCon->m_ConHandle = ConHdl_p; - // increment use counter - pAsySdoSeqCon->m_uiUseCount++; - uiCount = uiFreeEntry; - } - } - // call history ack function - Ret = EplSdoAsyAckFrameToHistory(pAsySdoSeqCon, - (AmiGetByteFromLe - (&pSdoSeqData_p-> - m_le_bRecSeqNumCon) & - EPL_SEQ_NUM_MASK)); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if defined(WIN32) || defined(_WIN32) - // leave critical section - LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive); -#endif - - // call process function with pointer of frame and event kAsySdoSeqEventFrameRec - Ret = EplSdoAsySeqProcess(uiCount, - uiDataSize_p, - NULL, pSdoSeqData_p, kAsySdoSeqEventFrameRec); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyInitHistory -// -// Description: inti function for history buffer -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyInitHistory(void) -{ - tEplKernel Ret; - unsigned int uiCount; - - Ret = kEplSuccessful; - // init m_bFreeEntries in history-buffer - for (uiCount = 0; uiCount < EPL_MAX_SDO_SEQ_CON; uiCount++) { - AsySdoSequInstance_g.m_AsySdoConnection[uiCount]. - m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyAddFrameToHistory -// -// Description: function to add a frame to the history buffer -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// pFrame_p = pointer to frame -// uiSize_p = size of the frame -// -> without size of the ethernet header -// and the asnd header -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame * pFrame_p, - unsigned int uiSize_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - - Ret = kEplSuccessful; - - // add frame to history buffer - - // check size - // $$$ d.k. EPL_SEQ_HISTORY_FRAME_SIZE includes the header size, but uiSize_p does not!!! - if (uiSize_p > EPL_SEQ_HISTROY_FRAME_SIZE) { - Ret = kEplSdoSeqFrameSizeError; - goto Exit; - } - // save pointer to history - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // check if a free entry is available - if (pHistory->m_bFreeEntries > 0) { // write message in free entry - EPL_MEMCPY(& - ((tEplFrame *) pHistory-> - m_aabHistoryFrame[pHistory->m_bWrite])-> - m_le_bMessageType, &pFrame_p->m_le_bMessageType, - uiSize_p + EPL_ASND_HEADER_SIZE); - // store size - pHistory->m_auiFrameSize[pHistory->m_bWrite] = uiSize_p; - - // decremend number of free bufferentries - pHistory->m_bFreeEntries--; - - // increment writeindex - pHistory->m_bWrite++; - - // check if write-index run over array-boarder - if (pHistory->m_bWrite == EPL_SDO_HISTORY_SIZE) { - pHistory->m_bWrite = 0; - } - - } else { // no free entry - Ret = kEplSdoSeqNoFreeHistory; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyAckFrameToHistory -// -// Description: function to delete acknowledged frames fron history buffer -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// bRecSeqNumber_p = receive sequence number of the received frame -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - u8 bRecSeqNumber_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - u8 bAckIndex; - u8 bCurrentSeqNum; - - Ret = kEplSuccessful; - - // get pointer to history buffer - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // release all acknowledged frames from history buffer - - // check if there are entries in history - if (pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) { - bAckIndex = pHistory->m_bAck; - do { - bCurrentSeqNum = - (((tEplFrame *) pHistory-> - m_aabHistoryFrame[bAckIndex])->m_Data.m_Asnd. - m_Payload.m_SdoSequenceFrame. - m_le_bSendSeqNumCon & EPL_SEQ_NUM_MASK); - if (((bRecSeqNumber_p - - bCurrentSeqNum) & EPL_SEQ_NUM_MASK) - < EPL_SEQ_NUM_THRESHOLD) { - pHistory->m_auiFrameSize[bAckIndex] = 0; - bAckIndex++; - pHistory->m_bFreeEntries++; - if (bAckIndex == EPL_SDO_HISTORY_SIZE) { // read index run over array-boarder - bAckIndex = 0; - } - } else { // nothing to do anymore, - // because any further frame in history has larger sequence - // number than the acknowledge - goto Exit; - } - } - while ((((bRecSeqNumber_p - 1 - - bCurrentSeqNum) & EPL_SEQ_NUM_MASK) - < EPL_SEQ_NUM_THRESHOLD) - && (pHistory->m_bWrite != bAckIndex)); - - // store local read-index to global var - pHistory->m_bAck = bAckIndex; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyReadFromHistory -// -// Description: function to one frame from history -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// ppFrame_p = pointer to pointer to the buffer of the stored frame -// puiSize_p = OUT: size of the frame -// fInitRead = bool which indicate a start of retransmission -// -> return last not acknowledged message if TRUE -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - tEplFrame ** ppFrame_p, - unsigned int *puiSize_p, - BOOL fInitRead_p) -{ - tEplKernel Ret; - tEplAsySdoConHistory *pHistory; - - Ret = kEplSuccessful; - - // read one message from History - - // get pointer to history buffer - pHistory = &pAsySdoSeqCon_p->m_SdoConHistory; - - // check if init - if (fInitRead_p != FALSE) { // initialize read index to the index which shall be acknowledged next - pHistory->m_bRead = pHistory->m_bAck; - } - // check if entries are available for reading - if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) - && (pHistory->m_bWrite != pHistory->m_bRead)) { -// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck); -// PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]); - - // return pointer to stored frame - *ppFrame_p = - (tEplFrame *) pHistory->m_aabHistoryFrame[pHistory-> - m_bRead]; - - // save size - *puiSize_p = pHistory->m_auiFrameSize[pHistory->m_bRead]; - - pHistory->m_bRead++; - if (pHistory->m_bRead == EPL_SDO_HISTORY_SIZE) { - pHistory->m_bRead = 0; - } - - } else { -// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries); - - // no more frames to send - // return null pointer - *ppFrame_p = NULL; - - *puiSize_p = 0; - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsyGetFreeEntriesFromHistory -// -// Description: function returns the number of free histroy entries -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// -// -// Returns: unsigned int = number of free entries -// -// -// State: -// -//--------------------------------------------------------------------------- -static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon * - pAsySdoSeqCon_p) -{ - unsigned int uiFreeEntries; - - uiFreeEntries = - (unsigned int)pAsySdoSeqCon_p->m_SdoConHistory.m_bFreeEntries; - - return uiFreeEntries; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoAsySeqSetTimer -// -// Description: function sets or modify timer in timermosule -// -// -// -// Parameters: pAsySdoSeqCon_p = pointer to control structure of this connection -// ulTimeout = timeout in ms -// -// -// Returns: unsigned int = number of free entries -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p, - unsigned long ulTimeout) -{ - tEplKernel Ret; - tEplTimerArg TimerArg; - - TimerArg.m_EventSink = kEplEventSinkSdoAsySeq; - TimerArg.m_ulArg = (unsigned long)pAsySdoSeqCon_p; - - if (pAsySdoSeqCon_p->m_EplTimerHdl == 0) { // create new timer - Ret = EplTimeruSetTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl, - ulTimeout, TimerArg); - } else { // modify exisiting timer - Ret = EplTimeruModifyTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl, - ulTimeout, TimerArg); - - } - - return Ret; -} - -// EOF diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c deleted file mode 100644 index bf35afab152..00000000000 --- a/drivers/staging/epl/EplSdoComu.c +++ /dev/null @@ -1,3345 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for SDO Command Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoComu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.14 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplSdoComu.h" - -#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\ - (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0) ) - -#error 'ERROR: At least SDO Server or SDO Client should be activate!' - -#endif - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE) - -#error 'ERROR: SDO Server needs OBDu module!' - -#endif - -#endif - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_MAX_SDO_COM_CON -#define EPL_MAX_SDO_COM_CON 5 -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -// intern events -typedef enum { - kEplSdoComConEventSendFirst = 0x00, // first frame to send - kEplSdoComConEventRec = 0x01, // frame received - kEplSdoComConEventConEstablished = 0x02, // connection established - kEplSdoComConEventConClosed = 0x03, // connection closed - kEplSdoComConEventAckReceived = 0x04, // acknowledge received by lower layer - // -> continue sending - kEplSdoComConEventFrameSended = 0x05, // lower has send a frame - kEplSdoComConEventInitError = 0x06, // error duringinitialisiation - // of the connection - kEplSdoComConEventTimeout = 0x07 // timeout in lower layer -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - , - - kEplSdoComConEventInitCon = 0x08, // init connection (only client) - kEplSdoComConEventAbort = 0x09 // abort sdo transfer (only client) -#endif -} tEplSdoComConEvent; - -typedef enum { - kEplSdoComSendTypeReq = 0x00, // send a request - kEplSdoComSendTypeAckRes = 0x01, // send a resonse without data - kEplSdoComSendTypeRes = 0x02, // send response with data - kEplSdoComSendTypeAbort = 0x03 // send abort -} tEplSdoComSendType; - -// state of the state maschine -typedef enum { - // General State - kEplSdoComStateIdle = 0x00, // idle state - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - // Server States - kEplSdoComStateServerSegmTrans = 0x01, // send following frames -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - // Client States - kEplSdoComStateClientWaitInit = 0x10, // wait for init connection - // on lower layer - kEplSdoComStateClientConnected = 0x11, // connection established - kEplSdoComStateClientSegmTrans = 0x12 // send following frames -#endif -} tEplSdoComState; - -// control structure for transaction -typedef struct { - tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used - tEplSdoComState m_SdoComState; - u8 m_bTransactionId; - unsigned int m_uiNodeId; // NodeId of the target - // -> needed to reinit connection - // after timeout - tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented - tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex - tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo - u8 *m_pData; // pointer to data - unsigned int m_uiTransSize; // number of bytes - // to transfer - unsigned int m_uiTransferredByte; // number of bytes - // already transferred - tEplSdoFinishedCb m_pfnTransferFinished; // callback function of the - // application - // -> called in the end of - // the SDO transfer - void *m_pUserArg; // user definable argument pointer - - u32 m_dwLastAbortCode; // save the last abort code -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - // only for client - unsigned int m_uiTargetIndex; // index to access - unsigned int m_uiTargetSubIndex; // subiondex to access - - // for future use - unsigned int m_uiTimeout; // timeout for this connection - -#endif - -} tEplSdoComCon; - -// instance table -typedef struct { - tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON]; - -#if defined(WIN32) || defined(_WIN32) - LPCRITICAL_SECTION m_pCriticalSection; - CRITICAL_SECTION m_CriticalSection; -#endif - -} tEplSdoComInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -static tEplSdoComInstance SdoComInstance_g; -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- -tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoCom *pAsySdoCom_p, - unsigned int uiDataSize_p); - -tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoConState AsySdoConState_p); - -static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplSdoComConEvent SdoComConEvent_p, - tEplAsySdoCom * pAsySdoCom_p); - -static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p, - tEplSdoComConEvent SdoComConEvent_p, - tEplAsySdoCom * pAsySdoCom_p); - -static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p, - tEplSdoComCon * pSdoComCon_p, - tEplSdoComConState - SdoComConState_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) -static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p); - -static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p, - unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplSdoComSendType SendType_p); - -static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p); -#endif - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - -static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p); - -static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p); - -static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p, - u32 dwAbortCode_p); -#endif - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: SDO Command layer Modul -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComInit -// -// Description: Init first instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoComInit(void) -{ - tEplKernel Ret; - - Ret = EplSdoComAddInstance(); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComAddInstance -// -// Description: Init additional instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoComAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // init controll structure - EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g)); - - // init instance of lower layer - Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb); - if (Ret != kEplSuccessful) { - goto Exit; - } -#if defined(WIN32) || defined(_WIN32) - // create critical section for process function - SdoComInstance_g.m_pCriticalSection = - &SdoComInstance_g.m_CriticalSection; - InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection); -#endif - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComDelInstance -// -// Description: delete instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoComDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - -#if defined(WIN32) || defined(_WIN32) - // delete critical section for process function - DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection); -#endif - - Ret = EplSdoAsySeqDelInstance(); - if (Ret != kEplSuccessful) { - goto Exit; - } - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComDefineCon -// -// Description: function defines a SDO connection to another node -// -> init lower layer and returns a handle for the connection. -// Two client connections to the same node via the same protocol -// are not allowed. If this function detects such a situation -// it will return kEplSdoComHandleExists and the handle of -// the existing connection in pSdoComConHdl_p. -// Using of existing server connections is possible. -// -// Parameters: pSdoComConHdl_p = pointer to the buffer of the handle -// uiTargetNodeId_p = NodeId of the targetnode -// ProtType_p = type of protocol to use for connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiTargetNodeId_p, - tEplSdoType ProtType_p) -{ - tEplKernel Ret; - unsigned int uiCount; - unsigned int uiFreeHdl; - tEplSdoComCon *pSdoComCon; - - // check Parameter - ASSERT(pSdoComConHdl_p != NULL); - - // check NodeId - if ((uiTargetNodeId_p == EPL_C_ADR_INVALID) - || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) { - Ret = kEplInvalidNodeId; - - } - // search free control structure - pSdoComCon = &SdoComInstance_g.m_SdoComCon[0]; - uiCount = 0; - uiFreeHdl = EPL_MAX_SDO_COM_CON; - while (uiCount < EPL_MAX_SDO_COM_CON) { - if (pSdoComCon->m_SdoSeqConHdl == 0) { // free entry - uiFreeHdl = uiCount; - } else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p) - && (pSdoComCon->m_SdoProtType == ProtType_p)) { // existing client connection with same node ID and same protocol type - *pSdoComConHdl_p = uiCount; - Ret = kEplSdoComHandleExists; - goto Exit; - } - uiCount++; - pSdoComCon++; - } - - if (uiFreeHdl == EPL_MAX_SDO_COM_CON) { - Ret = kEplSdoComNoFreeHandle; - goto Exit; - } - - pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl]; - // save handle for application - *pSdoComConHdl_p = uiFreeHdl; - // save parameters - pSdoComCon->m_SdoProtType = ProtType_p; - pSdoComCon->m_uiNodeId = uiTargetNodeId_p; - - // set Transaction Id - pSdoComCon->m_bTransactionId = 0; - - // check protocol - switch (ProtType_p) { - // udp - case kEplSdoTypeUdp: - { - // call connection int function of lower layer - Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl, - pSdoComCon->m_uiNodeId, - kEplSdoTypeUdp); - if (Ret != kEplSuccessful) { - goto Exit; - } - break; - } - - // Asend - case kEplSdoTypeAsnd: - { - // call connection int function of lower layer - Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl, - pSdoComCon->m_uiNodeId, - kEplSdoTypeAsnd); - if (Ret != kEplSuccessful) { - goto Exit; - } - break; - } - - // Pdo -> not supported - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoComUnsupportedProt; - goto Exit; - } - } // end of switch(m_ProtType_p) - - // call process function - Ret = EplSdoComProcessIntern(uiFreeHdl, - kEplSdoComConEventInitCon, NULL); - - Exit: - return Ret; -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplSdoComInitTransferByIndex -// -// Description: function init SDO Transfer for a defined connection -// -// -// -// Parameters: SdoComTransParam_p = Structure with parameters for connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - - // check parameter - if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF) - || (pSdoComTransParam_p->m_uiIndex == 0) - || (pSdoComTransParam_p->m_uiIndex > 0xFFFF) - || (pSdoComTransParam_p->m_pData == NULL) - || (pSdoComTransParam_p->m_uiDataSize == 0)) { - Ret = kEplSdoComInvalidParam; - goto Exit; - } - - if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // get pointer to control structure of connection - pSdoComCon = - &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl]; - - // check if handle ok - if (pSdoComCon->m_SdoSeqConHdl == 0) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // check if command layer is idle - if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) { // handle is not idle - Ret = kEplSdoComHandleBusy; - goto Exit; - } - // save parameter - // callback function for end of transfer - pSdoComCon->m_pfnTransferFinished = - pSdoComTransParam_p->m_pfnSdoFinishedCb; - pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg; - - // set type of SDO command - if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) { - pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex; - } else { - pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex; - - } - // save pointer to data - pSdoComCon->m_pData = pSdoComTransParam_p->m_pData; - // maximal bytes to transfer - pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize; - // bytes already transfered - pSdoComCon->m_uiTransferredByte = 0; - - // reset parts of control structure - pSdoComCon->m_dwLastAbortCode = 0; - pSdoComCon->m_SdoTransType = kEplSdoTransAuto; - // save timeout - //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout; - - // save index and subindex - pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex; - pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex; - - // call process function - Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst, // event to start transfer - NULL); - - Exit: - return Ret; - -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComUndefineCon -// -// Description: function undefine a SDO connection -// -// -// -// Parameters: SdoComConHdl_p = handle for the connection -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - - Ret = kEplSuccessful; - - if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // get pointer to control structure - pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; - - // $$$ d.k. abort a running transfer before closing the sequence layer - - if (((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) != - EPL_SDO_SEQ_INVALID_HDL) - && (pSdoComCon->m_SdoSeqConHdl != 0)) { - // close connection in lower layer - switch (pSdoComCon->m_SdoProtType) { - case kEplSdoTypeAsnd: - case kEplSdoTypeUdp: - { - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - break; - } - - case kEplSdoTypePdo: - case kEplSdoTypeAuto: - default: - { - Ret = kEplSdoComUnsupportedProt; - goto Exit; - } - - } // end of switch(pSdoComCon->m_SdoProtType) - } - - // clean controll structure - EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon)); - Exit: - return Ret; -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplSdoComGetState -// -// Description: function returns the state fo the connection -// -// -// -// Parameters: SdoComConHdl_p = handle for the connection -// pSdoComFinished_p = pointer to structur for sdo state -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p, - tEplSdoComFinished *pSdoComFinished_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - - Ret = kEplSuccessful; - - if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // get pointer to control structure - pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; - - // check if handle ok - if (pSdoComCon->m_SdoSeqConHdl == 0) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - - pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg; - pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId; - pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex; - pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex; - pSdoComFinished_p->m_uiTransferredByte = - pSdoComCon->m_uiTransferredByte; - pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode; - pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p; - if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex) { - pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite; - } else { - pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead; - } - - if (pSdoComCon->m_dwLastAbortCode != 0) { // sdo abort - pSdoComFinished_p->m_SdoComConState = - kEplSdoComTransferRxAborted; - - // delete abort code - pSdoComCon->m_dwLastAbortCode = 0; - - } else if ((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL) { // check state - pSdoComFinished_p->m_SdoComConState = - kEplSdoComTransferLowerLayerAbort; - } else if (pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit) { - // finished - pSdoComFinished_p->m_SdoComConState = - kEplSdoComTransferNotActive; - } else if (pSdoComCon->m_uiTransSize == 0) { // finished - pSdoComFinished_p->m_SdoComConState = - kEplSdoComTransferFinished; - } - - Exit: - return Ret; - -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplSdoComSdoAbort -// -// Description: function abort a sdo transfer -// -// -// -// Parameters: SdoComConHdl_p = handle for the connection -// dwAbortCode_p = abort code -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p, - u32 dwAbortCode_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - - if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // get pointer to control structure of connection - pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; - - // check if handle ok - if (pSdoComCon->m_SdoSeqConHdl == 0) { - Ret = kEplSdoComInvalidHandle; - goto Exit; - } - // save pointer to abort code - pSdoComCon->m_pData = (u8 *) & dwAbortCode_p; - - Ret = EplSdoComProcessIntern(SdoComConHdl_p, - kEplSdoComConEventAbort, - (tEplAsySdoCom *) NULL); - - Exit: - return Ret; -} -#endif - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComReceiveCb -// -// Description: callback function for SDO Sequence Layer -// -> indicates new data -// -// -// -// Parameters: SdoSeqConHdl_p = Handle for connection -// pAsySdoCom_p = pointer to data -// uiDataSize_p = size of data ($$$ not used yet, but it should) -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoCom *pAsySdoCom_p, - unsigned int uiDataSize_p) -{ - tEplKernel Ret; - - // search connection internally - Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p, - kEplSdoComConEventRec, pAsySdoCom_p); - - EPL_DBGLVL_SDO_TRACE3 - ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n", - SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0], - uiDataSize_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComConCb -// -// Description: callback function called by SDO Sequence Layer to inform -// command layer about state change of connection -// -// -// -// Parameters: SdoSeqConHdl_p = Handle of the connection -// AsySdoConState_p = Event of the connection -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplAsySdoConState AsySdoConState_p) -{ - tEplKernel Ret; - tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst; - - Ret = kEplSuccessful; - - // check state - switch (AsySdoConState_p) { - case kAsySdoConStateConnected: - { - EPL_DBGLVL_SDO_TRACE0("Connection established\n"); - SdoComConEvent = kEplSdoComConEventConEstablished; - // start transmission if needed - break; - } - - case kAsySdoConStateInitError: - { - EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n"); - SdoComConEvent = kEplSdoComConEventInitError; - // inform app about error and close sequence layer handle - break; - } - - case kAsySdoConStateConClosed: - { - EPL_DBGLVL_SDO_TRACE0("Connection closed\n"); - SdoComConEvent = kEplSdoComConEventConClosed; - // close sequence layer handle - break; - } - - case kAsySdoConStateAckReceived: - { - EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n"); - SdoComConEvent = kEplSdoComConEventAckReceived; - // continue transmission - break; - } - - case kAsySdoConStateFrameSended: - { - EPL_DBGLVL_SDO_TRACE0("One Frame sent\n"); - SdoComConEvent = kEplSdoComConEventFrameSended; - // to continue transmission - break; - - } - - case kAsySdoConStateTimeout: - { - EPL_DBGLVL_SDO_TRACE0("Timeout\n"); - SdoComConEvent = kEplSdoComConEventTimeout; - // close sequence layer handle - break; - - } - } // end of switch(AsySdoConState_p) - - Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p, - SdoComConEvent, (tEplAsySdoCom *) NULL); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComSearchConIntern -// -// Description: search a Sdo Sequence Layer connection handle in the -// control structure of the Command Layer -// -// Parameters: SdoSeqConHdl_p = Handle to search -// SdoComConEvent_p = event to process -// pAsySdoCom_p = pointer to received frame -// -// Returns: tEplKernel -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p, - tEplSdoComConEvent SdoComConEvent_p, - tEplAsySdoCom * pAsySdoCom_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - tEplSdoComConHdl HdlCount; - tEplSdoComConHdl HdlFree; - - Ret = kEplSdoComNotResponsible; - - // get pointer to first element of the array - pSdoComCon = &SdoComInstance_g.m_SdoComCon[0]; - HdlCount = 0; - HdlFree = 0xFFFF; - while (HdlCount < EPL_MAX_SDO_COM_CON) { - if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) { // matching command layer handle found - Ret = EplSdoComProcessIntern(HdlCount, - SdoComConEvent_p, - pAsySdoCom_p); - } else if ((pSdoComCon->m_SdoSeqConHdl == 0) - && (HdlFree == 0xFFFF)) { - HdlFree = HdlCount; - } - - pSdoComCon++; - HdlCount++; - } - - if (Ret == kEplSdoComNotResponsible) { // no responsible command layer handle found - if (HdlFree == 0xFFFF) { // no free handle - // delete connection immediately - // 2008/04/14 m.u./d.k. This connection actually does not exist. - // pSdoComCon is invalid. - // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl); - Ret = kEplSdoComNoFreeHandle; - } else { // create new handle - HdlCount = HdlFree; - pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount]; - pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p; - Ret = EplSdoComProcessIntern(HdlCount, - SdoComConEvent_p, - pAsySdoCom_p); - } - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComProcessIntern -// -// Description: search a Sdo Sequence Layer connection handle in the -// control structer of the Command Layer -// -// -// -// Parameters: SdoComCon_p = index of control structure of connection -// SdoComConEvent_p = event to process -// pAsySdoCom_p = pointer to received frame -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p, - tEplSdoComConEvent SdoComConEvent_p, - tEplAsySdoCom * pAsySdoCom_p) -{ - tEplKernel Ret; - tEplSdoComCon *pSdoComCon; - u8 bFlag; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - u32 dwAbortCode; - unsigned int uiSize; -#endif - -#if defined(WIN32) || defined(_WIN32) - // enter critical section for process function - EnterCriticalSection(SdoComInstance_g.m_pCriticalSection); - EPL_DBGLVL_SDO_TRACE0 - ("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n"); -#endif - - Ret = kEplSuccessful; - - // get pointer to control structure - pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p]; - - // process state maschine - switch (pSdoComCon->m_SdoComState) { - // idle state - case kEplSdoComStateIdle: - { - // check events - switch (SdoComConEvent_p) { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - // init con for client - case kEplSdoComConEventInitCon: - { - - // call of the init function already - // processed in EplSdoComDefineCon() - // only change state to kEplSdoComStateClientWaitInit - pSdoComCon->m_SdoComState = - kEplSdoComStateClientWaitInit; - break; - } -#endif - - // int con for server - case kEplSdoComConEventRec: - { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - // check if init of an transfer and no SDO abort - if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0) { // SDO request - if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0) { // no SDO abort - // save tansaction id - pSdoComCon-> - m_bTransactionId = - AmiGetByteFromLe - (&pAsySdoCom_p-> - m_le_bTransactionId); - // check command - switch (pAsySdoCom_p-> - m_le_bCommandId) - { - case kEplSdoServiceNIL: - { // simply acknowlegde NIL command on sequence layer - - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, - 0, - (tEplFrame - *) - NULL); - - break; - } - - case kEplSdoServiceReadByIndex: - { // read by index - - // search entry an start transfer - EplSdoComServerInitReadByIndex - (pSdoComCon, - pAsySdoCom_p); - // check next state - if (pSdoComCon->m_uiTransSize == 0) { // ready -> stay idle - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateIdle; - // reset abort code - pSdoComCon-> - m_dwLastAbortCode - = - 0; - } else { // segmented transfer - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateServerSegmTrans; - } - - break; - } - - case kEplSdoServiceWriteByIndex: - { - - // search entry an start write - EplSdoComServerInitWriteByIndex - (pSdoComCon, - pAsySdoCom_p); - // check next state - if (pSdoComCon->m_uiTransSize == 0) { // already -> stay idle - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateIdle; - // reset abort code - pSdoComCon-> - m_dwLastAbortCode - = - 0; - } else { // segmented transfer - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateServerSegmTrans; - } - - break; - } - - default: - { - // unsupported command - // -> abort senden - dwAbortCode - = - EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER; - // send abort - pSdoComCon-> - m_pData - = - (u8 - *) - & - dwAbortCode; - Ret = - EplSdoComServerSendFrameIntern - (pSdoComCon, - 0, - 0, - kEplSdoComSendTypeAbort); - - } - - } // end of switch(pAsySdoCom_p->m_le_bCommandId) - } - } else { // this command layer handle is not responsible - // (wrong direction or wrong transaction ID) - Ret = kEplSdoComNotResponsible; - goto Exit; - } -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - - break; - } - - // connection closed - case kEplSdoComConEventInitError: - case kEplSdoComConEventTimeout: - case kEplSdoComConEventConClosed: - { - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - // clean control structure - EPL_MEMSET(pSdoComCon, 0x00, - sizeof(tEplSdoComCon)); - break; - } - - default: - // d.k. do nothing - break; - } // end of switch(SdoComConEvent_p) - break; - } - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - //------------------------------------------------------------------------- - // SDO Server part - // segmented transfer - case kEplSdoComStateServerSegmTrans: - { - // check events - switch (SdoComConEvent_p) { - // send next frame - case kEplSdoComConEventAckReceived: - case kEplSdoComConEventFrameSended: - { - // check if it is a read - if (pSdoComCon->m_SdoServiceType == - kEplSdoServiceReadByIndex) { - // send next frame - EplSdoComServerSendFrameIntern - (pSdoComCon, 0, 0, - kEplSdoComSendTypeRes); - // if all send -> back to idle - if (pSdoComCon->m_uiTransSize == 0) { // back to idle - pSdoComCon-> - m_SdoComState = - kEplSdoComStateIdle; - // reset abort code - pSdoComCon-> - m_dwLastAbortCode = - 0; - } - - } - break; - } - - // process next frame - case kEplSdoComConEventRec: - { - // check if the frame is a SDO response and has the right transaction ID - bFlag = - AmiGetByteFromLe(&pAsySdoCom_p-> - m_le_bFlags); - if (((bFlag & 0x80) != 0) - && - (AmiGetByteFromLe - (&pAsySdoCom_p-> - m_le_bTransactionId) == - pSdoComCon->m_bTransactionId)) { - // check if it is a abort - if ((bFlag & 0x40) != 0) { // SDO abort - // clear control structure - pSdoComCon-> - m_uiTransSize = 0; - pSdoComCon-> - m_uiTransferredByte - = 0; - // change state - pSdoComCon-> - m_SdoComState = - kEplSdoComStateIdle; - // reset abort code - pSdoComCon-> - m_dwLastAbortCode = - 0; - // d.k.: do not execute anything further on this command - break; - } - // check if it is a write - if (pSdoComCon-> - m_SdoServiceType == - kEplSdoServiceWriteByIndex) - { - // write data to OD - uiSize = - AmiGetWordFromLe - (&pAsySdoCom_p-> - m_le_wSegmentSize); - if (pSdoComCon-> - m_dwLastAbortCode == - 0) { - EPL_MEMCPY - (pSdoComCon-> - m_pData, - &pAsySdoCom_p-> - m_le_abCommandData - [0], - uiSize); - } - // update counter - pSdoComCon-> - m_uiTransferredByte - += uiSize; - pSdoComCon-> - m_uiTransSize -= - uiSize; - - // update pointer - if (pSdoComCon-> - m_dwLastAbortCode == - 0) { - ( /*(u8*) */ - pSdoComCon-> - m_pData) += - uiSize; - } - // check end of transfer - if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) { // transfer ready - pSdoComCon-> - m_uiTransSize - = 0; - - if (pSdoComCon-> - m_dwLastAbortCode - == 0) { - // send response - // send next frame - EplSdoComServerSendFrameIntern - (pSdoComCon, - 0, - 0, - kEplSdoComSendTypeRes); - // if all send -> back to idle - if (pSdoComCon->m_uiTransSize == 0) { // back to idle - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateIdle; - // reset abort code - pSdoComCon-> - m_dwLastAbortCode - = - 0; - } - } else { // send dabort code - // send abort - pSdoComCon-> - m_pData - = - (u8 - *) - & - pSdoComCon-> - m_dwLastAbortCode; - Ret = - EplSdoComServerSendFrameIntern - (pSdoComCon, - 0, - 0, - kEplSdoComSendTypeAbort); - - // reset abort code - pSdoComCon-> - m_dwLastAbortCode - = 0; - - } - } else { - // send acknowledge without any Command layer data - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, - 0, - (tEplFrame - *) NULL); - } - } - } else { // this command layer handle is not responsible - // (wrong direction or wrong transaction ID) - Ret = kEplSdoComNotResponsible; - goto Exit; - } - break; - } - - // connection closed - case kEplSdoComConEventInitError: - case kEplSdoComConEventTimeout: - case kEplSdoComConEventConClosed: - { - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - // clean control structure - EPL_MEMSET(pSdoComCon, 0x00, - sizeof(tEplSdoComCon)); - break; - } - - default: - // d.k. do nothing - break; - } // end of switch(SdoComConEvent_p) - - break; - } -#endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - //------------------------------------------------------------------------- - // SDO Client part - // wait for finish of establishing connection - case kEplSdoComStateClientWaitInit: - { - - // if connection handle is invalid reinit connection - // d.k.: this will be done only on new events (i.e. InitTransfer) - if ((pSdoComCon-> - m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == - EPL_SDO_SEQ_INVALID_HDL) { - // check kind of connection to reinit - // check protocol - switch (pSdoComCon->m_SdoProtType) { - // udp - case kEplSdoTypeUdp: - { - // call connection int function of lower layer - Ret = - EplSdoAsySeqInitCon - (&pSdoComCon-> - m_SdoSeqConHdl, - pSdoComCon->m_uiNodeId, - kEplSdoTypeUdp); - if (Ret != kEplSuccessful) { - goto Exit; - } - break; - } - - // Asend -> not supported - case kEplSdoTypeAsnd: - { - // call connection int function of lower layer - Ret = - EplSdoAsySeqInitCon - (&pSdoComCon-> - m_SdoSeqConHdl, - pSdoComCon->m_uiNodeId, - kEplSdoTypeAsnd); - if (Ret != kEplSuccessful) { - goto Exit; - } - break; - } - - // Pdo -> not supported - case kEplSdoTypePdo: - default: - { - Ret = kEplSdoComUnsupportedProt; - goto Exit; - } - } // end of switch(m_ProtType_p) - // d.k.: reset transaction ID, because new sequence layer connection was initialized - // $$$ d.k. is this really necessary? - //pSdoComCon->m_bTransactionId = 0; - } - // check events - switch (SdoComConEvent_p) { - // connection established - case kEplSdoComConEventConEstablished: - { - //send first frame if needed - if ((pSdoComCon->m_uiTransSize > 0) - && (pSdoComCon->m_uiTargetIndex != 0)) { // start SDO transfer - Ret = - EplSdoComClientSend - (pSdoComCon); - if (Ret != kEplSuccessful) { - goto Exit; - } - // check if segemted transfer - if (pSdoComCon-> - m_SdoTransType == - kEplSdoTransSegmented) { - pSdoComCon-> - m_SdoComState = - kEplSdoComStateClientSegmTrans; - goto Exit; - } - } - // goto state kEplSdoComStateClientConnected - pSdoComCon->m_SdoComState = - kEplSdoComStateClientConnected; - goto Exit; - } - - case kEplSdoComConEventSendFirst: - { - // infos for transfer already saved by function EplSdoComInitTransferByIndex - break; - } - - case kEplSdoComConEventConClosed: - case kEplSdoComConEventInitError: - case kEplSdoComConEventTimeout: - { - // close sequence layer handle - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - pSdoComCon->m_SdoSeqConHdl |= - EPL_SDO_SEQ_INVALID_HDL; - // call callback function - if (SdoComConEvent_p == - kEplSdoComConEventTimeout) { - pSdoComCon->m_dwLastAbortCode = - EPL_SDOAC_TIME_OUT; - } else { - pSdoComCon->m_dwLastAbortCode = - 0; - } - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferLowerLayerAbort); - // d.k.: do not clean control structure - break; - } - - default: - // d.k. do nothing - break; - - } // end of switch(SdoComConEvent_p) - break; - } - - // connected - case kEplSdoComStateClientConnected: - { - // check events - switch (SdoComConEvent_p) { - // send a frame - case kEplSdoComConEventSendFirst: - case kEplSdoComConEventAckReceived: - case kEplSdoComConEventFrameSended: - { - Ret = EplSdoComClientSend(pSdoComCon); - if (Ret != kEplSuccessful) { - goto Exit; - } - // check if read transfer finished - if ((pSdoComCon->m_uiTransSize == 0) - && (pSdoComCon-> - m_uiTransferredByte != 0) - && (pSdoComCon->m_SdoServiceType == - kEplSdoServiceReadByIndex)) { - // inc transaction id - pSdoComCon->m_bTransactionId++; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferFinished); - - goto Exit; - } - // check if segemted transfer - if (pSdoComCon->m_SdoTransType == - kEplSdoTransSegmented) { - pSdoComCon->m_SdoComState = - kEplSdoComStateClientSegmTrans; - goto Exit; - } - break; - } - - // frame received - case kEplSdoComConEventRec: - { - // check if the frame is a SDO response and has the right transaction ID - bFlag = - AmiGetByteFromLe(&pAsySdoCom_p-> - m_le_bFlags); - if (((bFlag & 0x80) != 0) - && - (AmiGetByteFromLe - (&pAsySdoCom_p-> - m_le_bTransactionId) == - pSdoComCon->m_bTransactionId)) { - // check if abort or not - if ((bFlag & 0x40) != 0) { - // send acknowledge without any Command layer data - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, 0, - (tEplFrame *) - NULL); - // inc transaction id - pSdoComCon-> - m_bTransactionId++; - // save abort code - pSdoComCon-> - m_dwLastAbortCode = - AmiGetDwordFromLe - (&pAsySdoCom_p-> - m_le_abCommandData - [0]); - // call callback of application - Ret = - EplSdoComTransferFinished - (SdoComCon_p, - pSdoComCon, - kEplSdoComTransferRxAborted); - - goto Exit; - } else { // normal frame received - // check frame - Ret = - EplSdoComClientProcessFrame - (SdoComCon_p, - pAsySdoCom_p); - - // check if transfer ready - if (pSdoComCon-> - m_uiTransSize == - 0) { - // send acknowledge without any Command layer data - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, - 0, - (tEplFrame - *) NULL); - // inc transaction id - pSdoComCon-> - m_bTransactionId++; - // call callback of application - pSdoComCon-> - m_dwLastAbortCode - = 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, - pSdoComCon, - kEplSdoComTransferFinished); - - goto Exit; - } - - } - } else { // this command layer handle is not responsible - // (wrong direction or wrong transaction ID) - Ret = kEplSdoComNotResponsible; - goto Exit; - } - break; - } - - // connection closed event go back to kEplSdoComStateClientWaitInit - case kEplSdoComConEventConClosed: - { // connection closed by communication partner - // close sequence layer handle - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - // set handle to invalid and enter kEplSdoComStateClientWaitInit - pSdoComCon->m_SdoSeqConHdl |= - EPL_SDO_SEQ_INVALID_HDL; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientWaitInit; - - // call callback of application - pSdoComCon->m_dwLastAbortCode = 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferLowerLayerAbort); - - goto Exit; - - break; - } - - // abort to send from higher layer - case kEplSdoComConEventAbort: - { - EplSdoComClientSendAbort(pSdoComCon, - *((u32 *) - pSdoComCon-> - m_pData)); - - // inc transaction id - pSdoComCon->m_bTransactionId++; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - *((u32 *) pSdoComCon->m_pData); - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferTxAborted); - - break; - } - - case kEplSdoComConEventInitError: - case kEplSdoComConEventTimeout: - { - // close sequence layer handle - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - pSdoComCon->m_SdoSeqConHdl |= - EPL_SDO_SEQ_INVALID_HDL; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientWaitInit; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - EPL_SDOAC_TIME_OUT; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferLowerLayerAbort); - - } - - default: - // d.k. do nothing - break; - - } // end of switch(SdoComConEvent_p) - - break; - } - - // process segmented transfer - case kEplSdoComStateClientSegmTrans: - { - // check events - switch (SdoComConEvent_p) { - // sned a frame - case kEplSdoComConEventSendFirst: - case kEplSdoComConEventAckReceived: - case kEplSdoComConEventFrameSended: - { - Ret = EplSdoComClientSend(pSdoComCon); - if (Ret != kEplSuccessful) { - goto Exit; - } - // check if read transfer finished - if ((pSdoComCon->m_uiTransSize == 0) - && (pSdoComCon->m_SdoServiceType == - kEplSdoServiceReadByIndex)) { - // inc transaction id - pSdoComCon->m_bTransactionId++; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientConnected; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferFinished); - - goto Exit; - } - - break; - } - - // frame received - case kEplSdoComConEventRec: - { - // check if the frame is a response - bFlag = - AmiGetByteFromLe(&pAsySdoCom_p-> - m_le_bFlags); - if (((bFlag & 0x80) != 0) - && - (AmiGetByteFromLe - (&pAsySdoCom_p-> - m_le_bTransactionId) == - pSdoComCon->m_bTransactionId)) { - // check if abort or not - if ((bFlag & 0x40) != 0) { - // send acknowledge without any Command layer data - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, 0, - (tEplFrame *) - NULL); - // inc transaction id - pSdoComCon-> - m_bTransactionId++; - // change state - pSdoComCon-> - m_SdoComState = - kEplSdoComStateClientConnected; - // save abort code - pSdoComCon-> - m_dwLastAbortCode = - AmiGetDwordFromLe - (&pAsySdoCom_p-> - m_le_abCommandData - [0]); - // call callback of application - Ret = - EplSdoComTransferFinished - (SdoComCon_p, - pSdoComCon, - kEplSdoComTransferRxAborted); - - goto Exit; - } else { // normal frame received - // check frame - Ret = - EplSdoComClientProcessFrame - (SdoComCon_p, - pAsySdoCom_p); - - // check if transfer ready - if (pSdoComCon-> - m_uiTransSize == - 0) { - // send acknowledge without any Command layer data - Ret = - EplSdoAsySeqSendData - (pSdoComCon-> - m_SdoSeqConHdl, - 0, - (tEplFrame - *) NULL); - // inc transaction id - pSdoComCon-> - m_bTransactionId++; - // change state - pSdoComCon-> - m_SdoComState - = - kEplSdoComStateClientConnected; - // call callback of application - pSdoComCon-> - m_dwLastAbortCode - = 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, - pSdoComCon, - kEplSdoComTransferFinished); - - } - - } - } - break; - } - - // connection closed event go back to kEplSdoComStateClientWaitInit - case kEplSdoComConEventConClosed: - { // connection closed by communication partner - // close sequence layer handle - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - // set handle to invalid and enter kEplSdoComStateClientWaitInit - pSdoComCon->m_SdoSeqConHdl |= - EPL_SDO_SEQ_INVALID_HDL; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientWaitInit; - // inc transaction id - pSdoComCon->m_bTransactionId++; - // call callback of application - pSdoComCon->m_dwLastAbortCode = 0; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferFinished); - - break; - } - - // abort to send from higher layer - case kEplSdoComConEventAbort: - { - EplSdoComClientSendAbort(pSdoComCon, - *((u32 *) - pSdoComCon-> - m_pData)); - - // inc transaction id - pSdoComCon->m_bTransactionId++; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientConnected; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - *((u32 *) pSdoComCon->m_pData); - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferTxAborted); - - break; - } - - case kEplSdoComConEventInitError: - case kEplSdoComConEventTimeout: - { - // close sequence layer handle - Ret = - EplSdoAsySeqDelCon(pSdoComCon-> - m_SdoSeqConHdl); - pSdoComCon->m_SdoSeqConHdl |= - EPL_SDO_SEQ_INVALID_HDL; - // change state - pSdoComCon->m_SdoComState = - kEplSdoComStateClientWaitInit; - // call callback of application - pSdoComCon->m_dwLastAbortCode = - EPL_SDOAC_TIME_OUT; - Ret = - EplSdoComTransferFinished - (SdoComCon_p, pSdoComCon, - kEplSdoComTransferLowerLayerAbort); - - } - - default: - // d.k. do nothing - break; - - } // end of switch(SdoComConEvent_p) - - break; - } -#endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - - } // end of switch(pSdoComCon->m_SdoComState) - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - Exit: -#endif - -#if defined(WIN32) || defined(_WIN32) - // leave critical section for process function - EPL_DBGLVL_SDO_TRACE0 - ("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n"); - LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection); - -#endif - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComServerInitReadByIndex -// -// Description: function start the processing of an read by index command -// -// -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// pAsySdoCom_p = pointer to received frame -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) -static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p) -{ - tEplKernel Ret; - unsigned int uiIndex; - unsigned int uiSubindex; - tEplObdSize EntrySize; - tEplObdAccess AccessType; - u32 dwAbortCode; - - dwAbortCode = 0; - - // a init of a read could not be a segmented transfer - // -> no variable part of header - - // get index and subindex - uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); - uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]); - - // check accesstype of entry - // existens of entry -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType); -/*#else - Ret = kEplObdSubindexNotExist; - AccessType = 0; -#endif*/ - if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist - dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST; - // send abort - pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); - goto Exit; - } else if (Ret != kEplSuccessful) { // entry doesn't exist - dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST; - // send abort - pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); - goto Exit; - } - // compare accesstype must be read or const - if (((AccessType & kEplObdAccRead) == 0) - && ((AccessType & kEplObdAccConst) == 0)) { - - if ((AccessType & kEplObdAccWrite) != 0) { - // entry read a write only object - dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ; - } else { - dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS; - } - // send abort - pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); - goto Exit; - } - // save service - pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex; - - // get size of object to see iof segmented or expedited transfer -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - EntrySize = EplObduGetDataSize(uiIndex, uiSubindex); -/*#else - EntrySize = 0; -#endif*/ - if (EntrySize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer - pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented; - // get pointer to object-entry data -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - pSdoComCon_p->m_pData = - EplObduGetObjectDataPtr(uiIndex, uiSubindex); -//#endif - } else { // expedited transfer - pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited; - } - - pSdoComCon_p->m_uiTransSize = EntrySize; - pSdoComCon_p->m_uiTransferredByte = 0; - - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, kEplSdoComSendTypeRes); - if (Ret != kEplSuccessful) { - // error -> abort - dwAbortCode = EPL_SDOAC_GENERAL_ERROR; - // send abort - pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); - goto Exit; - } - - Exit: - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComServerSendFrameIntern(); -// -// Description: function creats and send a frame for server -// -// -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// uiIndex_p = index to send if expedited transfer else 0 -// uiSubIndex_p = subindex to send if expedited transfer else 0 -// SendType_p = to of frame to send -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) -static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p, - unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplSdoComSendType SendType_p) -{ - tEplKernel Ret; - u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; - tEplFrame *pFrame; - tEplAsySdoCom *pCommandFrame; - unsigned int uiSizeOfFrame; - u8 bFlag; - - Ret = kEplSuccessful; - - pFrame = (tEplFrame *) & abFrame[0]; - - EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); - - // build generic part of frame - // get pointer to command layerpart of frame - pCommandFrame = - &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_abSdoSeqPayload; - AmiSetByteToLe(&pCommandFrame->m_le_bCommandId, - pSdoComCon_p->m_SdoServiceType); - AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId, - pSdoComCon_p->m_bTransactionId); - - // set size to header size - uiSizeOfFrame = 8; - - // check SendType - switch (SendType_p) { - // requestframe to send - case kEplSdoComSendTypeReq: - { - // nothing to do for server - //-> error - Ret = kEplSdoComInvalidSendType; - break; - } - - // response without data to send - case kEplSdoComSendTypeAckRes: - { - // set response flag - AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80); - - // send frame - Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, - uiSizeOfFrame, pFrame); - - break; - } - - // responsframe to send - case kEplSdoComSendTypeRes: - { - // set response flag - bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags); - bFlag |= 0x80; - AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag); - - // check type of resonse - if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // Expedited transfer - // copy data in frame -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - Ret = EplObduReadEntryToLe(uiIndex_p, - uiSubIndex_p, - &pCommandFrame-> - m_le_abCommandData - [0], - (tEplObdSize *) & - pSdoComCon_p-> - m_uiTransSize); - if (Ret != kEplSuccessful) { - goto Exit; - } -//#endif - - // set size of frame - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - (u16) pSdoComCon_p-> - m_uiTransSize); - - // correct byte-counter - uiSizeOfFrame += pSdoComCon_p->m_uiTransSize; - pSdoComCon_p->m_uiTransferredByte += - pSdoComCon_p->m_uiTransSize; - pSdoComCon_p->m_uiTransSize = 0; - - // send frame - uiSizeOfFrame += pSdoComCon_p->m_uiTransSize; - Ret = - EplSdoAsySeqSendData(pSdoComCon_p-> - m_SdoSeqConHdl, - uiSizeOfFrame, pFrame); - } else if (pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented) { // segmented transfer - // distinguish between init, segment and complete - if (pSdoComCon_p->m_uiTransferredByte == 0) { // init - // set init flag - bFlag = - AmiGetByteFromLe(&pCommandFrame-> - m_le_bFlags); - bFlag |= 0x10; - AmiSetByteToLe(&pCommandFrame-> - m_le_bFlags, bFlag); - // init variable header - AmiSetDwordToLe(&pCommandFrame-> - m_le_abCommandData[0], - pSdoComCon_p-> - m_uiTransSize); - // copy data in frame - EPL_MEMCPY(&pCommandFrame-> - m_le_abCommandData[4], - pSdoComCon_p->m_pData, - (EPL_SDO_MAX_PAYLOAD - 4)); - - // correct byte-counter - pSdoComCon_p->m_uiTransSize -= - (EPL_SDO_MAX_PAYLOAD - 4); - pSdoComCon_p->m_uiTransferredByte += - (EPL_SDO_MAX_PAYLOAD - 4); - // move data pointer - pSdoComCon_p->m_pData += - (EPL_SDO_MAX_PAYLOAD - 4); - - // set segment size - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - (EPL_SDO_MAX_PAYLOAD - - 4)); - - // send frame - uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD; - Ret = - EplSdoAsySeqSendData(pSdoComCon_p-> - m_SdoSeqConHdl, - uiSizeOfFrame, - pFrame); - - } else - if ((pSdoComCon_p->m_uiTransferredByte > 0) - && (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) { // segment - // set segment flag - bFlag = - AmiGetByteFromLe(&pCommandFrame-> - m_le_bFlags); - bFlag |= 0x20; - AmiSetByteToLe(&pCommandFrame-> - m_le_bFlags, bFlag); - - // copy data in frame - EPL_MEMCPY(&pCommandFrame-> - m_le_abCommandData[0], - pSdoComCon_p->m_pData, - EPL_SDO_MAX_PAYLOAD); - - // correct byte-counter - pSdoComCon_p->m_uiTransSize -= - EPL_SDO_MAX_PAYLOAD; - pSdoComCon_p->m_uiTransferredByte += - EPL_SDO_MAX_PAYLOAD; - // move data pointer - pSdoComCon_p->m_pData += - EPL_SDO_MAX_PAYLOAD; - - // set segment size - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - EPL_SDO_MAX_PAYLOAD); - - // send frame - uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD; - Ret = - EplSdoAsySeqSendData(pSdoComCon_p-> - m_SdoSeqConHdl, - uiSizeOfFrame, - pFrame); - } else { - if ((pSdoComCon_p->m_uiTransSize == 0) - && (pSdoComCon_p-> - m_SdoServiceType != - kEplSdoServiceWriteByIndex)) { - goto Exit; - } - // complete - // set segment complete flag - bFlag = - AmiGetByteFromLe(&pCommandFrame-> - m_le_bFlags); - bFlag |= 0x30; - AmiSetByteToLe(&pCommandFrame-> - m_le_bFlags, bFlag); - - // copy data in frame - EPL_MEMCPY(&pCommandFrame-> - m_le_abCommandData[0], - pSdoComCon_p->m_pData, - pSdoComCon_p->m_uiTransSize); - - // correct byte-counter - pSdoComCon_p->m_uiTransferredByte += - pSdoComCon_p->m_uiTransSize; - - // move data pointer - pSdoComCon_p->m_pData += - pSdoComCon_p->m_uiTransSize; - - // set segment size - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - (u16) pSdoComCon_p-> - m_uiTransSize); - - // send frame - uiSizeOfFrame += - pSdoComCon_p->m_uiTransSize; - pSdoComCon_p->m_uiTransSize = 0; - Ret = - EplSdoAsySeqSendData(pSdoComCon_p-> - m_SdoSeqConHdl, - uiSizeOfFrame, - pFrame); - } - - } - break; - } - // abort to send - case kEplSdoComSendTypeAbort: - { - // set response and abort flag - bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags); - bFlag |= 0xC0; - AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag); - - // copy abortcode to frame - AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], - *((u32 *) pSdoComCon_p->m_pData)); - - // set size of segment - AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, - sizeof(u32)); - - // update counter - pSdoComCon_p->m_uiTransferredByte = sizeof(u32); - pSdoComCon_p->m_uiTransSize = 0; - - // calc framesize - uiSizeOfFrame += sizeof(u32); - Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, - uiSizeOfFrame, pFrame); - break; - } - } // end of switch(SendType_p) - - Exit: - return Ret; -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplSdoComServerInitWriteByIndex -// -// Description: function start the processing of an write by index command -// -// -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// pAsySdoCom_p = pointer to received frame -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) -static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - unsigned int uiSubindex; - unsigned int uiBytesToTransfer; - tEplObdSize EntrySize; - tEplObdAccess AccessType; - u32 dwAbortCode; - u8 *pbSrcData; - - dwAbortCode = 0; - - // a init of a write - // -> variable part of header possible - - // check if expedited or segmented transfer - if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10) { // initiate segmented transfer - pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented; - // get index and subindex - uiIndex = - AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]); - uiSubindex = - AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]); - // get source-pointer for copy - pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8]; - // save size - pSdoComCon_p->m_uiTransSize = - AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); - - } else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) { // expedited transfer - pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited; - // get index and subindex - uiIndex = - AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); - uiSubindex = - AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]); - // get source-pointer for copy - pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4]; - // save size - pSdoComCon_p->m_uiTransSize = - AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize); - // subtract header - pSdoComCon_p->m_uiTransSize -= 4; - - } else { - // just ignore any other transfer type - goto Exit; - } - - // check accesstype of entry - // existens of entry -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType); -/*#else - Ret = kEplObdSubindexNotExist; - AccessType = 0; -#endif*/ - if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist - pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST; - // send abort - // d.k. This is wrong: k.t. not needed send abort on end of write - /*pSdoComCon_p->m_pData = (u8*)pSdoComCon_p->m_dwLastAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); */ - goto Abort; - } else if (Ret != kEplSuccessful) { // entry doesn't exist - pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST; - // send abort - // d.k. This is wrong: k.t. not needed send abort on end of write - /* - pSdoComCon_p->m_pData = (u8*)&dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); */ - goto Abort; - } - // compare accesstype must be read - if ((AccessType & kEplObdAccWrite) == 0) { - - if ((AccessType & kEplObdAccRead) != 0) { - // entry write a read only object - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ; - } else { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_UNSUPPORTED_ACCESS; - } - // send abort - // d.k. This is wrong: k.t. not needed send abort on end of write - /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); */ - goto Abort; - } - // save service - pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex; - - pSdoComCon_p->m_uiTransferredByte = 0; - - // write data to OD - if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // expedited transfer - // size checking is done by EplObduWriteEntryFromLe() - -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - Ret = EplObduWriteEntryFromLe(uiIndex, - uiSubindex, - pbSrcData, - pSdoComCon_p->m_uiTransSize); - switch (Ret) { - case kEplSuccessful: - { - break; - } - - case kEplObdAccessViolation: - { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_UNSUPPORTED_ACCESS; - // send abort - goto Abort; - } - - case kEplObdValueLengthError: - { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH; - // send abort - goto Abort; - } - - case kEplObdValueTooHigh: - { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_VALUE_RANGE_TOO_HIGH; - // send abort - goto Abort; - } - - case kEplObdValueTooLow: - { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_VALUE_RANGE_TOO_LOW; - // send abort - goto Abort; - } - - default: - { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_GENERAL_ERROR; - // send abort - goto Abort; - } - } -//#endif - // send command acknowledge - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - 0, - 0, - kEplSdoComSendTypeAckRes); - - pSdoComCon_p->m_uiTransSize = 0; - goto Exit; - } else { - // get size of the object to check if it fits - // because we directly write to the destination memory - // d.k. no one calls the user OD callback function - - //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - EntrySize = EplObduGetDataSize(uiIndex, uiSubindex); - /*#else - EntrySize = 0; - #endif */ - if (EntrySize < pSdoComCon_p->m_uiTransSize) { // parameter too big - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH; - // send abort - // d.k. This is wrong: k.t. not needed send abort on end of write - /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); */ - goto Abort; - } - - uiBytesToTransfer = - AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize); - // eleminate header (Command header (8) + variable part (4) + Command header (4)) - uiBytesToTransfer -= 16; - // get pointer to object entry -//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex, - uiSubindex); -//#endif - if (pSdoComCon_p->m_pData == NULL) { - pSdoComCon_p->m_dwLastAbortCode = - EPL_SDOAC_GENERAL_ERROR; - // send abort - // d.k. This is wrong: k.t. not needed send abort on end of write -/* pSdoComCon_p->m_pData = (u8*)&pSdoComCon_p->m_dwLastAbortCode; - Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, - uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort);*/ - goto Abort; - } - // copy data - EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer); - - // update internal counter - pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer; - pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer; - - // update target pointer - ( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer; - - // send acknowledge without any Command layer data - Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, - 0, (tEplFrame *) NULL); - goto Exit; - } - - Abort: - if (pSdoComCon_p->m_dwLastAbortCode != 0) { - // send abort - pSdoComCon_p->m_pData = - (u8 *) & pSdoComCon_p->m_dwLastAbortCode; - Ret = - EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex, - uiSubindex, - kEplSdoComSendTypeAbort); - - // reset abort code - pSdoComCon_p->m_dwLastAbortCode = 0; - pSdoComCon_p->m_uiTransSize = 0; - goto Exit; - } - - Exit: - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComClientSend -// -// Description: function starts an sdo transfer an send all further frames -// -// -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p) -{ - tEplKernel Ret; - u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; - tEplFrame *pFrame; - tEplAsySdoCom *pCommandFrame; - unsigned int uiSizeOfFrame; - u8 bFlags; - u8 *pbPayload; - - Ret = kEplSuccessful; - - pFrame = (tEplFrame *) & abFrame[0]; - - EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); - - // build generic part of frame - // get pointer to command layerpart of frame - pCommandFrame = - &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_abSdoSeqPayload; - AmiSetByteToLe(&pCommandFrame->m_le_bCommandId, - pSdoComCon_p->m_SdoServiceType); - AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId, - pSdoComCon_p->m_bTransactionId); - - // set size constant part of header - uiSizeOfFrame = 8; - - // check if first frame to send -> command header needed - if (pSdoComCon_p->m_uiTransSize > 0) { - if (pSdoComCon_p->m_uiTransferredByte == 0) { // start SDO transfer - // check if segmented or expedited transfer - // only for write commands - switch (pSdoComCon_p->m_SdoServiceType) { - case kEplSdoServiceReadByIndex: - { // first frame of read access always expedited - pSdoComCon_p->m_SdoTransType = - kEplSdoTransExpedited; - pbPayload = - &pCommandFrame-> - m_le_abCommandData[0]; - // fill rest of header - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, 4); - - // create command header - AmiSetWordToLe(pbPayload, - (u16) pSdoComCon_p-> - m_uiTargetIndex); - pbPayload += 2; - AmiSetByteToLe(pbPayload, - (u8) pSdoComCon_p-> - m_uiTargetSubIndex); - // calc size - uiSizeOfFrame += 4; - - // set pSdoComCon_p->m_uiTransferredByte to one - pSdoComCon_p->m_uiTransferredByte = 1; - break; - } - - case kEplSdoServiceWriteByIndex: - { - if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer - // -> variable part of header needed - // save that transfer is segmented - pSdoComCon_p->m_SdoTransType = - kEplSdoTransSegmented; - // fill variable part of header - AmiSetDwordToLe(&pCommandFrame-> - m_le_abCommandData - [0], - pSdoComCon_p-> - m_uiTransSize); - // set pointer to real payload - pbPayload = - &pCommandFrame-> - m_le_abCommandData[4]; - // fill rest of header - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - EPL_SDO_MAX_PAYLOAD); - bFlags = 0x10; - AmiSetByteToLe(&pCommandFrame-> - m_le_bFlags, - bFlags); - // create command header - AmiSetWordToLe(pbPayload, - (u16) - pSdoComCon_p-> - m_uiTargetIndex); - pbPayload += 2; - AmiSetByteToLe(pbPayload, - (u8) - pSdoComCon_p-> - m_uiTargetSubIndex); - // on byte for reserved - pbPayload += 2; - // calc size - uiSizeOfFrame += - EPL_SDO_MAX_PAYLOAD; - - // copy payload - EPL_MEMCPY(pbPayload, - pSdoComCon_p-> - m_pData, - (EPL_SDO_MAX_PAYLOAD - - 8)); - pSdoComCon_p->m_pData += - (EPL_SDO_MAX_PAYLOAD - 8); - // correct intern counter - pSdoComCon_p->m_uiTransSize -= - (EPL_SDO_MAX_PAYLOAD - 8); - pSdoComCon_p-> - m_uiTransferredByte = - (EPL_SDO_MAX_PAYLOAD - 8); - - } else { // expedited trandsfer - // save that transfer is expedited - pSdoComCon_p->m_SdoTransType = - kEplSdoTransExpedited; - pbPayload = - &pCommandFrame-> - m_le_abCommandData[0]; - - // create command header - AmiSetWordToLe(pbPayload, - (u16) - pSdoComCon_p-> - m_uiTargetIndex); - pbPayload += 2; - AmiSetByteToLe(pbPayload, - (u8) - pSdoComCon_p-> - m_uiTargetSubIndex); - // + 2 -> one byte for subindex and one byte reserved - pbPayload += 2; - // copy data - EPL_MEMCPY(pbPayload, - pSdoComCon_p-> - m_pData, - pSdoComCon_p-> - m_uiTransSize); - // calc size - uiSizeOfFrame += - (4 + - pSdoComCon_p-> - m_uiTransSize); - // fill rest of header - AmiSetWordToLe(&pCommandFrame-> - m_le_wSegmentSize, - (u16) (4 + - pSdoComCon_p-> - m_uiTransSize)); - - pSdoComCon_p-> - m_uiTransferredByte = - pSdoComCon_p->m_uiTransSize; - pSdoComCon_p->m_uiTransSize = 0; - } - break; - } - - case kEplSdoServiceNIL: - default: - // invalid service requested - Ret = kEplSdoComInvalidServiceType; - goto Exit; - } // end of switch(pSdoComCon_p->m_SdoServiceType) - } else // (pSdoComCon_p->m_uiTransferredByte > 0) - { // continue SDO transfer - switch (pSdoComCon_p->m_SdoServiceType) { - // for expedited read is nothing to do - // -> server sends data - - case kEplSdoServiceWriteByIndex: - { // send next frame - if (pSdoComCon_p->m_SdoTransType == - kEplSdoTransSegmented) { - if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // next segment - pbPayload = - &pCommandFrame-> - m_le_abCommandData - [0]; - // fill rest of header - AmiSetWordToLe - (&pCommandFrame-> - m_le_wSegmentSize, - EPL_SDO_MAX_PAYLOAD); - bFlags = 0x20; - AmiSetByteToLe - (&pCommandFrame-> - m_le_bFlags, - bFlags); - // copy data - EPL_MEMCPY(pbPayload, - pSdoComCon_p-> - m_pData, - EPL_SDO_MAX_PAYLOAD); - pSdoComCon_p->m_pData += - EPL_SDO_MAX_PAYLOAD; - // correct intern counter - pSdoComCon_p-> - m_uiTransSize -= - EPL_SDO_MAX_PAYLOAD; - pSdoComCon_p-> - m_uiTransferredByte - = - EPL_SDO_MAX_PAYLOAD; - // calc size - uiSizeOfFrame += - EPL_SDO_MAX_PAYLOAD; - - } else { // end of transfer - pbPayload = - &pCommandFrame-> - m_le_abCommandData - [0]; - // fill rest of header - AmiSetWordToLe - (&pCommandFrame-> - m_le_wSegmentSize, - (u16) - pSdoComCon_p-> - m_uiTransSize); - bFlags = 0x30; - AmiSetByteToLe - (&pCommandFrame-> - m_le_bFlags, - bFlags); - // copy data - EPL_MEMCPY(pbPayload, - pSdoComCon_p-> - m_pData, - pSdoComCon_p-> - m_uiTransSize); - pSdoComCon_p->m_pData += - pSdoComCon_p-> - m_uiTransSize; - // calc size - uiSizeOfFrame += - pSdoComCon_p-> - m_uiTransSize; - // correct intern counter - pSdoComCon_p-> - m_uiTransSize = 0; - pSdoComCon_p-> - m_uiTransferredByte - = - pSdoComCon_p-> - m_uiTransSize; - - } - } else { - goto Exit; - } - break; - } - default: - { - goto Exit; - } - } // end of switch(pSdoComCon_p->m_SdoServiceType) - } - } else { - goto Exit; - } - - // call send function of lower layer - switch (pSdoComCon_p->m_SdoProtType) { - case kEplSdoTypeAsnd: - case kEplSdoTypeUdp: - { - Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, - uiSizeOfFrame, pFrame); - break; - } - - default: - { - Ret = kEplSdoComUnsupportedProt; - } - } // end of switch(pSdoComCon_p->m_SdoProtType) - - Exit: - return Ret; - -} -#endif -//--------------------------------------------------------------------------- -// -// Function: EplSdoComClientProcessFrame -// -// Description: function process a received frame -// -// -// -// Parameters: SdoComCon_p = connection handle -// pAsySdoCom_p = pointer to frame to process -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p, - tEplAsySdoCom * pAsySdoCom_p) -{ - tEplKernel Ret; - u8 bBuffer; - unsigned int uiBuffer; - unsigned int uiDataSize; - unsigned long ulBuffer; - tEplSdoComCon *pSdoComCon; - - Ret = kEplSuccessful; - - // get pointer to control structure - pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p]; - - // check if transaction Id fit - bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId); - if (pSdoComCon->m_bTransactionId != bBuffer) { - // incorrect transaction id - - // if running transfer - if ((pSdoComCon->m_uiTransferredByte != 0) - && (pSdoComCon->m_uiTransSize != 0)) { - pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR; - // -> send abort - EplSdoComClientSendAbort(pSdoComCon, - pSdoComCon->m_dwLastAbortCode); - // call callback of application - Ret = - EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, - kEplSdoComTransferTxAborted); - } - - } else { // check if correct command - bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId); - if (pSdoComCon->m_SdoServiceType != bBuffer) { - // incorrect command - // if running transfer - if ((pSdoComCon->m_uiTransferredByte != 0) - && (pSdoComCon->m_uiTransSize != 0)) { - pSdoComCon->m_dwLastAbortCode = - EPL_SDOAC_GENERAL_ERROR; - // -> send abort - EplSdoComClientSendAbort(pSdoComCon, - pSdoComCon-> - m_dwLastAbortCode); - // call callback of application - Ret = - EplSdoComTransferFinished(SdoComCon_p, - pSdoComCon, - kEplSdoComTransferTxAborted); - } - - } else { // switch on command - switch (pSdoComCon->m_SdoServiceType) { - case kEplSdoServiceWriteByIndex: - { // check if confirmation from server - // nothing more to do - break; - } - - case kEplSdoServiceReadByIndex: - { // check if it is an segmented or an expedited transfer - bBuffer = - AmiGetByteFromLe(&pAsySdoCom_p-> - m_le_bFlags); - // mask uninteressting bits - bBuffer &= 0x30; - switch (bBuffer) { - // expedited transfer - case 0x00: - { - // check size of buffer - uiBuffer = - AmiGetWordFromLe - (&pAsySdoCom_p-> - m_le_wSegmentSize); - if (uiBuffer > pSdoComCon->m_uiTransSize) { // buffer provided by the application is to small - // copy only a part - uiDataSize = - pSdoComCon-> - m_uiTransSize; - } else { // buffer fits - uiDataSize = - uiBuffer; - } - - // copy data - EPL_MEMCPY(pSdoComCon-> - m_pData, - &pAsySdoCom_p-> - m_le_abCommandData - [0], - uiDataSize); - - // correct counter - pSdoComCon-> - m_uiTransSize = 0; - pSdoComCon-> - m_uiTransferredByte - = uiDataSize; - break; - } - - // start of a segmented transfer - case 0x10: - { // get total size of transfer - ulBuffer = - AmiGetDwordFromLe - (&pAsySdoCom_p-> - m_le_abCommandData - [0]); - if (ulBuffer <= pSdoComCon->m_uiTransSize) { // buffer fit - pSdoComCon-> - m_uiTransSize - = - (unsigned - int) - ulBuffer; - } else { // buffer to small - // send abort - pSdoComCon-> - m_dwLastAbortCode - = - EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH; - // -> send abort - EplSdoComClientSendAbort - (pSdoComCon, - pSdoComCon-> - m_dwLastAbortCode); - // call callback of application - Ret = - EplSdoComTransferFinished - (SdoComCon_p, - pSdoComCon, - kEplSdoComTransferRxAborted); - goto Exit; - } - - // get segment size - // check size of buffer - uiBuffer = - AmiGetWordFromLe - (&pAsySdoCom_p-> - m_le_wSegmentSize); - // subtract size of vaiable header from datasize - uiBuffer -= 4; - // copy data - EPL_MEMCPY(pSdoComCon-> - m_pData, - &pAsySdoCom_p-> - m_le_abCommandData - [4], - uiBuffer); - - // correct counter an pointer - pSdoComCon->m_pData += - uiBuffer; - pSdoComCon-> - m_uiTransferredByte - += uiBuffer; - pSdoComCon-> - m_uiTransSize -= - uiBuffer; - - break; - } - - // segment - case 0x20: - { - // get segment size - // check size of buffer - uiBuffer = - AmiGetWordFromLe - (&pAsySdoCom_p-> - m_le_wSegmentSize); - // check if data to copy fit to buffer - if (uiBuffer >= pSdoComCon->m_uiTransSize) { // to much data - uiBuffer = - (pSdoComCon-> - m_uiTransSize - - 1); - } - // copy data - EPL_MEMCPY(pSdoComCon-> - m_pData, - &pAsySdoCom_p-> - m_le_abCommandData - [0], - uiBuffer); - - // correct counter an pointer - pSdoComCon->m_pData += - uiBuffer; - pSdoComCon-> - m_uiTransferredByte - += uiBuffer; - pSdoComCon-> - m_uiTransSize -= - uiBuffer; - break; - } - - // last segment - case 0x30: - { - // get segment size - // check size of buffer - uiBuffer = - AmiGetWordFromLe - (&pAsySdoCom_p-> - m_le_wSegmentSize); - // check if data to copy fit to buffer - if (uiBuffer > pSdoComCon->m_uiTransSize) { // to much data - uiBuffer = - (pSdoComCon-> - m_uiTransSize - - 1); - } - // copy data - EPL_MEMCPY(pSdoComCon-> - m_pData, - &pAsySdoCom_p-> - m_le_abCommandData - [0], - uiBuffer); - - // correct counter an pointer - pSdoComCon->m_pData += - uiBuffer; - pSdoComCon-> - m_uiTransferredByte - += uiBuffer; - pSdoComCon-> - m_uiTransSize = 0; - - break; - } - } // end of switch(bBuffer & 0x30) - - break; - } - - case kEplSdoServiceNIL: - default: - // invalid service requested - // $$$ d.k. What should we do? - break; - } // end of switch(pSdoComCon->m_SdoServiceType) - } - } - - Exit: - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComClientSendAbort -// -// Description: function send a abort message -// -// -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// dwAbortCode_p = Sdo abort code -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) -static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p, - u32 dwAbortCode_p) -{ - tEplKernel Ret; - u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; - tEplFrame *pFrame; - tEplAsySdoCom *pCommandFrame; - unsigned int uiSizeOfFrame; - - Ret = kEplSuccessful; - - pFrame = (tEplFrame *) & abFrame[0]; - - EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); - - // build generic part of frame - // get pointer to command layerpart of frame - pCommandFrame = - &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame. - m_le_abSdoSeqPayload; - AmiSetByteToLe(&pCommandFrame->m_le_bCommandId, - pSdoComCon_p->m_SdoServiceType); - AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId, - pSdoComCon_p->m_bTransactionId); - - uiSizeOfFrame = 8; - - // set response and abort flag - pCommandFrame->m_le_bFlags |= 0x40; - - // copy abortcode to frame - AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p); - - // set size of segment - AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32)); - - // update counter - pSdoComCon_p->m_uiTransferredByte = sizeof(u32); - pSdoComCon_p->m_uiTransSize = 0; - - // calc framesize - uiSizeOfFrame += sizeof(u32); - - // save abort code - pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p; - - // call send function of lower layer - switch (pSdoComCon_p->m_SdoProtType) { - case kEplSdoTypeAsnd: - case kEplSdoTypeUdp: - { - Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, - uiSizeOfFrame, pFrame); - break; - } - - default: - { - Ret = kEplSdoComUnsupportedProt; - } - } // end of switch(pSdoComCon_p->m_SdoProtType) - - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EplSdoComTransferFinished -// -// Description: calls callback function of application if available -// and clears entry in control structure -// -// Parameters: pSdoComCon_p = pointer to control structure of connection -// SdoComConState_p = state of SDO transfer -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p, - tEplSdoComCon * pSdoComCon_p, - tEplSdoComConState SdoComConState_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - if (pSdoComCon_p->m_pfnTransferFinished != NULL) { - tEplSdoFinishedCb pfnTransferFinished; - tEplSdoComFinished SdoComFinished; - - SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg; - SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId; - SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex; - SdoComFinished.m_uiTargetSubIndex = - pSdoComCon_p->m_uiTargetSubIndex; - SdoComFinished.m_uiTransferredByte = - pSdoComCon_p->m_uiTransferredByte; - SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode; - SdoComFinished.m_SdoComConHdl = SdoComCon_p; - SdoComFinished.m_SdoComConState = SdoComConState_p; - if (pSdoComCon_p->m_SdoServiceType == - kEplSdoServiceWriteByIndex) { - SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite; - } else { - SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead; - } - - // reset transfer state so this handle is not busy anymore - pSdoComCon_p->m_uiTransferredByte = 0; - pSdoComCon_p->m_uiTransSize = 0; - - pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished; - // delete function pointer to inform application only once for each transfer - pSdoComCon_p->m_pfnTransferFinished = NULL; - - // call application's callback function - pfnTransferFinished(&SdoComFinished); - - } - - return Ret; -} - -// EOF diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c deleted file mode 100644 index c8e950fa835..00000000000 --- a/drivers/staging/epl/EplSdoUdpu.c +++ /dev/null @@ -1,650 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for SDO/UDP-Protocolabstractionlayer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoUdpu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplSdoUdpu.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - -#include "SocketLinuxKernel.h" -#include -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_SDO_MAX_CONNECTION_UDP -#define EPL_SDO_MAX_CONNECTION_UDP 5 -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - unsigned long m_ulIpAddr; // in network byte order - unsigned int m_uiPort; // in network byte order - -} tEplSdoUdpCon; - -// instance table -typedef struct { - tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP]; - tEplSequLayerReceiveCb m_fpSdoAsySeqCb; - SOCKET m_UdpSocket; - - struct completion m_CompletionUdpThread; - int m_ThreadHandle; - int m_iTerminateThread; -} tEplSdoUdpInstance; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static tEplSdoUdpInstance SdoUdpInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static int EplSdoUdpThread(void *pArg_p); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: Protocolabstraction layer for UDP -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuInit -// -// Description: init first instance of the module -// -// -// -// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer -// callback-function -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p) -{ - tEplKernel Ret; - - Ret = EplSdoUdpuAddInstance(fpReceiveCb_p); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuAddInstance -// -// Description: init additional instance of the module -// înit socket and start Listen-Thread -// -// -// -// Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer -// callback-function -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p) -{ - tEplKernel Ret; - - // set instance variables to 0 - EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g)); - - Ret = kEplSuccessful; - - // save pointer to callback-function - if (fpReceiveCb_p != NULL) { - SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p; - } else { - Ret = kEplSdoUdpMissCb; - goto Exit; - } - - init_completion(&SdoUdpInstance_g.m_CompletionUdpThread); - SdoUdpInstance_g.m_iTerminateThread = 0; - SdoUdpInstance_g.m_ThreadHandle = 0; - SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET; - - Ret = EplSdoUdpuConfig(INADDR_ANY, 0); - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuDelInstance -// -// Description: del instance of the module -// del socket and del Listen-Thread -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started - // close thread - SdoUdpInstance_g.m_iTerminateThread = 1; - /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */ - send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1); - wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread); - SdoUdpInstance_g.m_ThreadHandle = 0; - } - - if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) { - // close socket - closesocket(SdoUdpInstance_g.m_UdpSocket); - SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET; - } - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuConfig -// -// Description: reconfigurate socket with new IP-Address -// -> needed for NMT ResetConfiguration -// -// Parameters: ulIpAddr_p = IpAddress in platform byte order -// uiPort_p = port number in platform byte order -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p) -{ - tEplKernel Ret; - struct sockaddr_in Addr; - int iError; - - Ret = kEplSuccessful; - - if (uiPort_p == 0) { // set UDP port to default port number - uiPort_p = EPL_C_SDO_EPL_PORT; - } else if (uiPort_p > 65535) { - Ret = kEplSdoUdpSocketError; - goto Exit; - } - - if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started - - // close old thread - SdoUdpInstance_g.m_iTerminateThread = 1; - /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */ - send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1); - wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread); - SdoUdpInstance_g.m_iTerminateThread = 0; - SdoUdpInstance_g.m_ThreadHandle = 0; - } - - if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) { - // close socket - iError = closesocket(SdoUdpInstance_g.m_UdpSocket); - SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET; - if (iError != 0) { - Ret = kEplSdoUdpSocketError; - goto Exit; - } - } - // create Socket - SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) { - Ret = kEplSdoUdpNoSocket; - EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n"); - goto Exit; - } - // bind socket - Addr.sin_family = AF_INET; - Addr.sin_port = htons((unsigned short)uiPort_p); - Addr.sin_addr.s_addr = htonl(ulIpAddr_p); - iError = - bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr, - sizeof(Addr)); - if (iError < 0) { - //iError = WSAGetLastError(); - EPL_DBGLVL_SDO_TRACE1 - ("EplSdoUdpuConfig: bind() finished with %i\n", iError); - Ret = kEplSdoUdpNoSocket; - goto Exit; - } - // create Listen-Thread - SdoUdpInstance_g.m_ThreadHandle = - kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, - CLONE_FS | CLONE_FILES); - if (SdoUdpInstance_g.m_ThreadHandle == 0) { - Ret = kEplSdoUdpThreadError; - goto Exit; - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuInitCon -// -// Description: init a new connect -// -// -// -// Parameters: pSdoConHandle_p = pointer for the new connection handle -// uiTargetNodeId_p = NodeId of the target node -// -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p, - unsigned int uiTargetNodeId_p) -{ - tEplKernel Ret; - unsigned int uiCount; - unsigned int uiFreeCon; - tEplSdoUdpCon *pSdoUdpCon; - - Ret = kEplSuccessful; - - // get free entry in control structure - uiCount = 0; - uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP; - pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0]; - while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) { - if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) { // existing connection to target node found - // set handle - *pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE); - - goto Exit; - } else if ((pSdoUdpCon->m_ulIpAddr == 0) - && (pSdoUdpCon->m_uiPort == 0)) { - uiFreeCon = uiCount; - } - uiCount++; - pSdoUdpCon++; - } - - if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) { - // error no free handle - Ret = kEplSdoUdpNoFreeHandle; - } else { - pSdoUdpCon = - &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon]; - // save infos for connection - pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT); - pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p); // 192.168.100.uiTargetNodeId_p - - // set handle - *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE); - - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuSendData -// -// Description: send data using exisiting connection -// -// -// -// Parameters: SdoConHandle_p = connection handle -// pSrcData_p = pointer to data -// dwDataSize_p = number of databyte -// -> without asend-header!!! -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p, - tEplFrame *pSrcData_p, u32 dwDataSize_p) -{ - tEplKernel Ret; - int iError; - unsigned int uiArray; - struct sockaddr_in Addr; - - Ret = kEplSuccessful; - - uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK); - if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) { - Ret = kEplSdoUdpInvalidHdl; - goto Exit; - } - //set message type - AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06); // SDO - // target node id (for Udp = 0) - AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00); - // set source-nodeid (for Udp = 0) - AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00); - - // calc size - dwDataSize_p += EPL_ASND_HEADER_SIZE; - - // call sendto - Addr.sin_family = AF_INET; - Addr.sin_port = - (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray]. - m_uiPort; - Addr.sin_addr.s_addr = - SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr; - - iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle - (const char *)&pSrcData_p->m_le_bMessageType, // data to send - dwDataSize_p, // number of bytes to send - 0, // flags - (struct sockaddr *)&Addr, // target - sizeof(struct sockaddr_in)); // sizeof targetadress - if (iError < 0) { - EPL_DBGLVL_SDO_TRACE1 - ("EplSdoUdpuSendData: sendto() finished with %i\n", iError); - Ret = kEplSdoUdpSendError; - goto Exit; - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpuDelCon -// -// Description: delete connection from intern structure -// -// -// -// Parameters: SdoConHandle_p = connection handle -// -// Returns: tEplKernel = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p) -{ - tEplKernel Ret; - unsigned int uiArray; - - uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK); - - if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) { - Ret = kEplSdoUdpInvalidHdl; - goto Exit; - } else { - Ret = kEplSuccessful; - } - - // delete connection - SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0; - SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0; - - Exit: - return Ret; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoUdpThread -// -// Description: thread check socket for new data -// -// -// -// Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara -// -// -// Returns: u32 = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -static int EplSdoUdpThread(void *pArg_p) -{ - - tEplSdoUdpInstance *pInstance; - struct sockaddr_in RemoteAddr; - int iError; - int iCount; - int iFreeEntry; - u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE]; - unsigned int uiSize; - tEplSdoConHdl SdoConHdl; - - pInstance = (tEplSdoUdpInstance *) pArg_p; - daemonize("EplSdoUdpThread"); - allow_signal(SIGTERM); - - for (; pInstance->m_iTerminateThread == 0;) - - { - // wait for data - uiSize = sizeof(struct sockaddr); - iError = recvfrom(pInstance->m_UdpSocket, // Socket - (char *)&abBuffer[0], // buffer for data - sizeof(abBuffer), // size of the buffer - 0, // flags - (struct sockaddr *)&RemoteAddr, - (int *)&uiSize); - if (iError == -ERESTARTSYS) { - break; - } - if (iError > 0) { - // get handle for higher layer - iCount = 0; - iFreeEntry = 0xFFFF; - while (iCount < EPL_SDO_MAX_CONNECTION_UDP) { - // check if this connection is already known - if ((pInstance->m_aSdoAbsUdpConnection[iCount]. - m_ulIpAddr == RemoteAddr.sin_addr.s_addr) - && (pInstance-> - m_aSdoAbsUdpConnection[iCount]. - m_uiPort == RemoteAddr.sin_port)) { - break; - } - - if ((pInstance->m_aSdoAbsUdpConnection[iCount]. - m_ulIpAddr == 0) - && (pInstance-> - m_aSdoAbsUdpConnection[iCount]. - m_uiPort == 0) - && (iFreeEntry == 0xFFFF)) - { - iFreeEntry = iCount; - } - - iCount++; - } - - if (iCount == EPL_SDO_MAX_CONNECTION_UDP) { - // connection unknown - // see if there is a free handle - if (iFreeEntry != 0xFFFF) { - // save adress infos - pInstance-> - m_aSdoAbsUdpConnection[iFreeEntry]. - m_ulIpAddr = - RemoteAddr.sin_addr.s_addr; - pInstance-> - m_aSdoAbsUdpConnection[iFreeEntry]. - m_uiPort = RemoteAddr.sin_port; - // call callback - SdoConHdl = iFreeEntry; - SdoConHdl |= EPL_SDO_UDP_HANDLE; - // offset 4 -> start of SDO Sequence header - pInstance->m_fpSdoAsySeqCb(SdoConHdl, - (tEplAsySdoSeq - *) & - abBuffer[4], - (iError - - 4)); - } else { - EPL_DBGLVL_SDO_TRACE0 - ("Error in EplSdoUdpThread() no free handle\n"); - } - - } else { - // known connection - // call callback with correct handle - SdoConHdl = iCount; - SdoConHdl |= EPL_SDO_UDP_HANDLE; - // offset 4 -> start of SDO Sequence header - pInstance->m_fpSdoAsySeqCb(SdoConHdl, - (tEplAsySdoSeq *) & - abBuffer[4], - (iError - 4)); - } - } // end of if(iError!=SOCKET_ERROR) - } // end of for(;;) - - complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0); - return 0; -} - -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - -// EOF diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c deleted file mode 100644 index b291399af10..00000000000 --- a/drivers/staging/epl/EplStatusu.c +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Statusu-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplStatusu.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/11/15 d.k.: start of the implementation - -****************************************************************************/ - -#include "user/EplStatusu.h" -#include "user/EplDlluCal.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -typedef struct { - tEplStatusuCbResponse m_apfnCbResponse[254]; - -} tEplStatusuInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplStatusuInstance EplStatusuInstance_g; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuInit -// -// Description: init first instance of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplStatusuInit(void) -{ - tEplKernel Ret; - - Ret = EplStatusuAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuAddInstance -// -// Description: init other instances of the module -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplStatusuAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof(EplStatusuInstance_g)); - - // register StatusResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndStatusResponse, - EplStatusuCbStatusResponse, - kEplDllAsndFilterAny); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuDelInstance -// -// Description: delete instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplStatusuDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // deregister StatusResponse callback function - Ret = - EplDlluCalRegAsndService(kEplDllAsndStatusResponse, NULL, - kEplDllAsndFilterNone); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuReset -// -// Description: resets this instance -// -// Parameters: -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplStatusuReset(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // reset instance structure - EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof(EplStatusuInstance_g)); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuRequestStatusResponse -// -// Description: returns the StatusResponse for the specified node. -// -// Parameters: uiNodeId_p = IN: node ID -// pfnCbResponse_p = IN: function pointer to callback function -// which will be called if StatusResponse is received -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p, - tEplStatusuCbResponse pfnCbResponse_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // decrement node ID, because array is zero based - uiNodeId_p--; - if (uiNodeId_p < tabentries(EplStatusuInstance_g.m_apfnCbResponse)) { -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL) { // request already issued (maybe by someone else) - Ret = kEplInvalidOperation; - } else { - EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] = - pfnCbResponse_p; - Ret = - EplDlluCalIssueRequest(kEplDllReqServiceStatus, - (uiNodeId_p + 1), 0xFF); - } -#else - Ret = kEplInvalidOperation; -#endif - } else { // invalid node ID specified - Ret = kEplInvalidNodeId; - } - - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplStatusuCbStatusResponse -// -// Description: callback funktion for StatusResponse -// -// -// -// Parameters: pFrameInfo_p = Frame with the StatusResponse -// -// -// Returns: tEplKernel = error code -// -// -// State: -// -//--------------------------------------------------------------------------- -static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiNodeId; - unsigned int uiIndex; - tEplStatusuCbResponse pfnCbResponse; - - uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId); - - uiIndex = uiNodeId - 1; - - if (uiIndex < tabentries(EplStatusuInstance_g.m_apfnCbResponse)) { - // memorize pointer to callback function - pfnCbResponse = EplStatusuInstance_g.m_apfnCbResponse[uiIndex]; - if (pfnCbResponse == NULL) { // response was not requested - goto Exit; - } - // reset callback function pointer so that caller may issue next request - EplStatusuInstance_g.m_apfnCbResponse[uiIndex] = NULL; - - if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_STATUSRES) { // StatusResponse not received or it has invalid size - Ret = pfnCbResponse(uiNodeId, NULL); - } else { // StatusResponse received - Ret = - pfnCbResponse(uiNodeId, - &pFrameInfo_p->m_pFrame->m_Data. - m_Asnd.m_Payload.m_StatusResponse); - } - } - - Exit: - return Ret; -} - -// EOF diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h deleted file mode 100644 index e76d21ff9d9..00000000000 --- a/drivers/staging/epl/EplTarget.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for target api function - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTarget.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2005/12/05 -as: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPLTARGET_H_ -#define _EPLTARGET_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- -// ========================================================================= -// macros for memory access (depends on target system) -// ========================================================================= - -// NOTE: -// The following macros are used to combine standard library definitions. Some -// applications needs to use one common library function (e.g. memcpy()). So -// you can set (or change) it here. - -#include -#include -#include -#include -#include - - //29.11.2004 f.j. sonst ist memcpy und memset unbekannt -// #include - -#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz)); -#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz)); - -#define EPL_MALLOC(siz) kmalloc((size_t)(siz), GFP_KERNEL) -#define EPL_FREE(ptr) kfree((void *)ptr) - -#ifndef PRINTF0 -#define PRINTF TRACE -#define PRINTF0(arg) TRACE0(arg) -#define PRINTF1(arg,p1) TRACE1(arg,p1) -#define PRINTF2(arg,p1,p2) TRACE2(arg,p1,p2) -#define PRINTF3(arg,p1,p2,p3) TRACE3(arg,p1,p2,p3) -#define PRINTF4(arg,p1,p2,p3,p4) TRACE4(arg,p1,p2,p3,p4) - //#define PRINTF printf - //#define PRINTF0(arg) PRINTF(arg) - //#define PRINTF1(arg,p1) PRINTF(arg,p1) - //#define PRINTF2(arg,p1,p2) PRINTF(arg,p1,p2) - //#define PRINTF3(arg,p1,p2,p3) PRINTF(arg,p1,p2,p3) - //#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4) -#endif - -#define EPL_TGT_INTMASK_ETH 0x0001 // ethernet interrupt -#define EPL_TGT_INTMASK_DMA 0x0002 // DMA interrupt - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -// currently no Timer functions are needed by EPL stack -// so they are not implemented yet -//void TgtTimerInit(void); -//u32 TgtGetTickCount(void); -//void TgtGetNetTime(tEplNetTime * pNetTime_p); - -// functions for ethernet driver -tEplKernel TgtInitEthIsr(void); -void TgtFreeEthIsr(void); -void TgtEnableGlobalInterrupt(u8 fEnable_p); -void TgtEnableEthInterrupt0(u8 fEnable_p, unsigned int uiInterruptMask_p); -void TgtEnableEthInterrupt1(u8 fEnable_p, unsigned int uiInterruptMask_p); - -#endif // #ifndef _EPLTARGET_H_ diff --git a/drivers/staging/epl/EplTimer.h b/drivers/staging/epl/EplTimer.h deleted file mode 100644 index d1a73eaf65c..00000000000 --- a/drivers/staging/epl/EplTimer.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Epl Timer-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimer.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/06 k.t.: start of the implementation - -****************************************************************************/ - -#include "EplInc.h" -#include "EplEvent.h" - -#ifndef _EPLTIMER_H_ -#define _EPLTIMER_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -// type for timer handle -typedef unsigned long tEplTimerHdl; - -typedef struct { - tEplEventSink m_EventSink; - unsigned long m_ulArg; // d.k.: converted to unsigned long because - // it is never accessed as a pointer by the - // timer module and the data the - // pointer points to is not saved in any way. - // It is just a value. The user is responsible - // to store the data statically and convert - // the pointer between address spaces. - -} tEplTimerArg; - -typedef struct { - tEplTimerHdl m_TimerHdl; - unsigned long m_ulArg; // d.k.: converted to unsigned long because - // it is never accessed as a pointer by the - // timer module and the data the - // pointer points to is not saved in any way. - // It is just a value. - -} tEplTimerEventArg; - -typedef tEplKernel(* tEplTimerkCallback) (tEplTimerEventArg *pEventArg_p); - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -#endif // #ifndef _EPLTIMER_H_ diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c deleted file mode 100644 index ff80fc80d02..00000000000 --- a/drivers/staging/epl/EplTimeruLinuxKernel.c +++ /dev/null @@ -1,446 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for EPL User Timermodule for Linux kernel module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimeruLinuxKernel.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/09/12 d.k.: start of the implementation - -****************************************************************************/ - -#include "user/EplTimeru.h" -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- -typedef struct { - struct timer_list m_Timer; - tEplTimerArg TimerArgument; - -} tEplTimeruData; - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- -static void EplTimeruCbMs(unsigned long ulParameter_p); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: Epl Userspace-Timermodule for Linux Kernel -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruInit -// -// Description: function inits first instance -// -// Parameters: void -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruInit(void) -{ - tEplKernel Ret; - - Ret = EplTimeruAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruAddInstance -// -// Description: function inits additional instance -// -// Parameters: void -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruAddInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruDelInstance -// -// Description: function deletes instance -// -> under Linux nothing to do -// -> no instance table needed -// -// Parameters: void -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruDelInstance(void) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruSetTimerMs -// -// Description: function creates a timer and returns the corresponding handle -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplTimeruData *pData; - - // check pointer to handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - pData = (tEplTimeruData *) EPL_MALLOC(sizeof(tEplTimeruData)); - if (pData == NULL) { - Ret = kEplNoResource; - goto Exit; - } - - init_timer(&pData->m_Timer); - pData->m_Timer.function = EplTimeruCbMs; - pData->m_Timer.data = (unsigned long)pData; - pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000; - - EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg)); - - add_timer(&pData->m_Timer); - - *pTimerHdl_p = (tEplTimerHdl) pData; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruModifyTimerMs -// -// Description: function changes a timer and returns the corresponding handle -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplTimeruData *pData; - - // check pointer to handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - // check handle itself, i.e. was the handle initialized before - if (*pTimerHdl_p == 0) { - Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p); - goto Exit; - } - pData = (tEplTimeruData *) * pTimerHdl_p; - if ((tEplTimeruData *) pData->m_Timer.data != pData) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000)); - - // copy the TimerArg after the timer is restarted, - // so that a timer occured immediately before mod_timer - // won't use the new TimerArg and - // therefore the old timer cannot be distinguished from the new one. - // But if the new timer is too fast, it may get lost. - EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg)); - - // check if timer is really running - if (timer_pending(&pData->m_Timer) == 0) { // timer is not running - // retry starting it - add_timer(&pData->m_Timer); - } - // set handle to pointer of tEplTimeruData -// *pTimerHdl_p = (tEplTimerHdl) pData; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruDeleteTimer -// -// Description: function deletes a timer -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// -// Returns: tEplKernel = errorcode -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplTimeruData *pData; - - // check pointer to handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - // check handle itself, i.e. was the handle initialized before - if (*pTimerHdl_p == 0) { - Ret = kEplSuccessful; - goto Exit; - } - pData = (tEplTimeruData *) * pTimerHdl_p; - if ((tEplTimeruData *) pData->m_Timer.data != pData) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - -/* if (del_timer(&pData->m_Timer) == 1) - { - kfree(pData); - } -*/ - // try to delete the timer - del_timer(&pData->m_Timer); - // free memory in any case - kfree(pData); - - // uninitialize handle - *pTimerHdl_p = 0; - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruIsTimerActive -// -// Description: checks if the timer referenced by the handle is currently -// active. -// -// Parameters: TimerHdl_p = handle of the timer to check -// -// Returns: BOOL = TRUE, if active; -// FALSE, otherwise -// -// State: -// -//--------------------------------------------------------------------------- - -BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p) -{ - BOOL fActive = FALSE; - tEplTimeruData *pData; - - // check handle itself, i.e. was the handle initialized before - if (TimerHdl_p == 0) { // timer was not created yet, so it is not active - goto Exit; - } - pData = (tEplTimeruData *) TimerHdl_p; - if ((tEplTimeruData *) pData->m_Timer.data != pData) { // invalid timer - goto Exit; - } - // check if timer is running - if (timer_pending(&pData->m_Timer) == 0) { // timer is not running - goto Exit; - } - - fActive = TRUE; - - Exit: - return fActive; -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruCbMs -// -// Description: function to process timer -// -// -// -// Parameters: lpParameter = pointer to structur of type tEplTimeruData -// -// -// Returns: (none) -// -// -// State: -// -//--------------------------------------------------------------------------- -static void EplTimeruCbMs(unsigned long ulParameter_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplTimeruData *pData; - tEplEvent EplEvent; - tEplTimerEventArg TimerEventArg; - - pData = (tEplTimeruData *) ulParameter_p; - - // call event function - TimerEventArg.m_TimerHdl = (tEplTimerHdl) pData; - TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg; - - EplEvent.m_EventSink = pData->TimerArgument.m_EventSink; - EplEvent.m_EventType = kEplEventTypeTimer; - EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime)); - EplEvent.m_pArg = &TimerEventArg; - EplEvent.m_uiSize = sizeof(TimerEventArg); - - Ret = EplEventuPost(&EplEvent); - - // d.k. do not free memory, user has to call EplTimeruDeleteTimer() - //kfree(pData); - -} - -// EOF diff --git a/drivers/staging/epl/EplVersion.h b/drivers/staging/epl/EplVersion.h deleted file mode 100644 index 75570d56b86..00000000000 --- a/drivers/staging/epl/EplVersion.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: This file defines the EPL version for the stack, as string - and for object 0x1018 within object dictionary. - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplVersion.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - all - - ------------------------------------------------------------------------- - - Revision History: - -****************************************************************************/ - -#ifndef _EPL_VERSION_H_ -#define _EPL_VERSION_H_ - -// NOTE: -// All version macros should contain the same version number. But do not use -// defines instead of the numbers. Because the macro EPL_STRING_VERSION() can not -// convert a define to a string. -// -// Format: maj.min.build -// maj = major version -// min = minor version (will be set to 0 if major version will be incremented) -// build = current build (will be set to 0 if minor version will be incremented) -// -#define DEFINED_STACK_VERSION EPL_STACK_VERSION (1, 3, 0) -#define DEFINED_OBJ1018_VERSION EPL_OBJ1018_VERSION (1, 3, 0) -#define DEFINED_STRING_VERSION EPL_STRING_VERSION (1, 3, 0) - -// ----------------------------------------------------------------------------- -#define EPL_PRODUCT_NAME "EPL V2" -#define EPL_PRODUCT_VERSION DEFINED_STRING_VERSION -#define EPL_PRODUCT_MANUFACTURER "SYS TEC electronic GmbH" - -#define EPL_PRODUCT_KEY "SO-1083" -#define EPL_PRODUCT_DESCRIPTION "openPOWERLINK Protocol Stack Source" - -#endif // _EPL_VERSION_H_ - -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler -// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/Kconfig b/drivers/staging/epl/Kconfig deleted file mode 100644 index 9f939d5874a..00000000000 --- a/drivers/staging/epl/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config EPL - tristate "openPOWERLINK protocol stack" - depends on NET && HIGH_RES_TIMERS && X86 - default N - ---help--- - Enable support for the openPOWERLINK network protocol stack. diff --git a/drivers/staging/epl/Makefile b/drivers/staging/epl/Makefile deleted file mode 100644 index a2c824187d2..00000000000 --- a/drivers/staging/epl/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -obj-$(CONFIG_EPL) += epl.o - -epl-objs := \ - EplApiGeneric.o \ - EplApiLinuxKernel.o \ - EplApiProcessImage.o \ - EplDllk.o \ - EplDllkCal.o \ - EplDlluCal.o \ - EplErrorHandlerk.o \ - EplEventk.o \ - EplEventu.o \ - EplIdentu.o \ - EplNmtCnu.o \ - EplNmtk.o \ - EplNmtkCal.o \ - EplNmtMnu.o \ - EplNmtu.o \ - EplNmtuCal.o \ - EplObd.o \ - EplObdkCal.o \ - EplObdu.o \ - EplObduCal.o \ - EplPdok.o \ - EplPdokCal.o \ - EplPdou.o \ - EplSdoAsndu.o \ - EplSdoAsySequ.o \ - EplSdoComu.o \ - EplSdoUdpu.o \ - EplStatusu.o \ - EplTimeruLinuxKernel.o \ - amix86.o \ - SharedBuff.o \ - ShbIpc-LinuxKernel.o \ - TimerHighReskX86.o \ - VirtualEthernetLinux.o \ - SocketLinuxKernel.o \ - proc_fs.o \ - demo_main.o \ - Edrv8139.o \ diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c deleted file mode 100644 index 2b10c375f3e..00000000000 --- a/drivers/staging/epl/SharedBuff.c +++ /dev/null @@ -1,1762 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Implementation of platform independend part for the - shared buffer - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/06/27 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#if defined(WIN32) || defined(_WIN32) - -#ifdef UNDER_RTSS - // RTX header -#include -#include -#include - -#elif __BORLANDC__ - // borland C header -#include -#include - -#elif WINCE -#include - -#else - // MSVC needs to include windows.h at first - // the following defines ar necessary for function prototypes for waitable timers -#define _WIN32_WINDOWS 0x0401 -#define _WIN32_WINNT 0x0400 -#include -#include -#endif - -#endif - -#include "global.h" -#include "SharedBuff.h" -#include "ShbIpc.h" - -#include -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// Configuration -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Constant definitions -//--------------------------------------------------------------------------- - -#define SBC_MAGIC_ID 0x53424323 // magic ID ("SBC#") -#define SBL_MAGIC_ID 0x53424C23 // magic ID ("SBL#") - -//--------------------------------------------------------------------------- -// Local types -//--------------------------------------------------------------------------- - -// structure to administrate circular shared buffer head -typedef struct { - unsigned long m_ShbCirMagicID; // magic ID ("SBC#") - unsigned long m_ulBufferTotalSize; // over-all size of complete buffer - unsigned long m_ulBufferDataSize; // size of complete data area - unsigned long m_ulWrIndex; // current write index (set bevore write) - unsigned long m_ulRdIndex; // current read index (set after read) - unsigned long m_ulNumOfWriteJobs; // number of currently (parallel running) write operations - unsigned long m_ulDataInUse; // currently used buffer size (incl. uncompleted write operations) - unsigned long m_ulDataApended; // buffer size of complete new written but not yet readable data (in case of m_ulNumOfWriteJobs>1) - unsigned long m_ulBlocksApended; // number of complete new written but not yet readable data blocks (in case of m_ulNumOfWriteJobs>1) - unsigned long m_ulDataReadable; // buffer size with readable (complete written) data - unsigned long m_ulBlocksReadable; // number of readable (complete written) data blocks - tShbCirSigHndlrNewData m_pfnSigHndlrNewData; // application handler to signal new data - unsigned int m_fBufferLocked; // TRUE if buffer is locked (because of pending reset request) - tShbCirSigHndlrReset m_pfnSigHndlrReset; // application handler to signal buffer reset is done - unsigned char m_Data; // start of data area (the real data size is unknown at this time) - -} tShbCirBuff; - -// structure to administrate linear shared buffer head -typedef struct { - unsigned int m_ShbLinMagicID; // magic ID ("SBL#") - unsigned long m_ulBufferTotalSize; // over-all size of complete buffer - unsigned long m_ulBufferDataSize; // size of complete data area - unsigned char m_Data; // start of data area (the real data size is unknown at this time) - -} tShbLinBuff; - -// type to save size of a single data block inside the circular shared buffer -typedef struct { - unsigned int m_uiFullBlockSize:28; // a single block must not exceed a length of 256MByte :-) - unsigned int m_uiAlignFillBytes:4; - -} tShbCirBlockSize; - -#define SBC_BLOCK_ALIGNMENT 4 // alignment must *not* be lower than sizeof(tShbCirBlockSize)! -#define SBC_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-) - -#define SBL_BLOCK_ALIGNMENT 4 -#define SBL_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-) - -//--------------------------------------------------------------------------- -// Global variables -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Local variables -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Prototypes of internal functions -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Get pointer to Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p) -{ - - tShbCirBuff *pShbCirBuff; - - pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance_p); - ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID); - - return (pShbCirBuff); - -} - -//--------------------------------------------------------------------------- -// Get pointer to Linear Shared Buffer -//--------------------------------------------------------------------------- - -tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p) -{ - - tShbLinBuff *pShbLinBuff; - - pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance_p); - ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID); - - return (pShbLinBuff); - -} - -// not inlined internal functions -int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p); -void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p, - unsigned int fTimeOut_p); - - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -// not inlined external functions - -//--------------------------------------------------------------------------- -// Initialize Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbInit(void) -{ - - tShbError ShbError; - - ShbError = ShbIpcInit(); - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Deinitialize Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbExit(void) -{ - - tShbError ShbError; - - ShbError = ShbIpcExit(); - - return (ShbError); - -} - -//-------------------------------------------------------------------------// -// // -// C i r c u l a r S h a r e d B u f f e r // -// // -//-------------------------------------------------------------------------// - -//--------------------------------------------------------------------------- -// Allocate Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p) -{ - - tShbInstance pShbInstance; - tShbCirBuff *pShbCirBuff; - unsigned int fShbNewCreated; - unsigned long ulBufferDataSize; - unsigned long ulBufferTotalSize; - tShbError ShbError; - - // check arguments - if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) { - return (kShbInvalidArg); - } - - // calculate length of memory to allocate - ulBufferDataSize = - (ulBufferSize_p + - (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1); - ulBufferTotalSize = ulBufferDataSize + sizeof(tShbCirBuff); - - // allocate a new or open an existing shared buffer - ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p, - &pShbInstance, &fShbNewCreated); - if (ShbError != kShbOk) { - goto Exit; - } - - if (pShbInstance == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - - // get pointer to shared buffer - pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance); - - // if the shared buffer was new created, than this process has - // to initialize it, otherwise the buffer is already in use - // and *must not* be reseted - if (fShbNewCreated) { -#ifndef NDEBUG - { - memset(pShbCirBuff, 0xCC, ulBufferTotalSize); - } -#endif - - pShbCirBuff->m_ShbCirMagicID = SBC_MAGIC_ID; - pShbCirBuff->m_ulBufferTotalSize = ulBufferTotalSize; - pShbCirBuff->m_ulBufferDataSize = ulBufferDataSize; - pShbCirBuff->m_ulWrIndex = 0; - pShbCirBuff->m_ulRdIndex = 0; - pShbCirBuff->m_ulNumOfWriteJobs = 0; - pShbCirBuff->m_ulDataInUse = 0; - pShbCirBuff->m_ulDataApended = 0; - pShbCirBuff->m_ulBlocksApended = 0; - pShbCirBuff->m_ulDataReadable = 0; - pShbCirBuff->m_ulBlocksReadable = 0; - pShbCirBuff->m_pfnSigHndlrNewData = NULL; - pShbCirBuff->m_fBufferLocked = FALSE; - pShbCirBuff->m_pfnSigHndlrReset = NULL; - } else { - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - } - - Exit: - - *ppShbInstance_p = pShbInstance; - *pfShbNewCreated_p = fShbNewCreated; - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Release Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p) -{ - - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbOk; - goto Exit; - } - - ShbError = ShbIpcReleaseBuffer(pShbInstance_p); - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Reset Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p, - unsigned long ulTimeOut_p, - tShbCirSigHndlrReset pfnSignalHandlerReset_p) -{ - - tShbCirBuff *pShbCirBuff; - unsigned long ulNumOfWriteJobs = 0; // d.k. GCC complains about uninitialized variable otherwise - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // start reset job by setting request request in buffer header - ShbIpcEnterAtomicSection(pShbInstance_p); - { - if (!pShbCirBuff->m_fBufferLocked) { - ulNumOfWriteJobs = pShbCirBuff->m_ulNumOfWriteJobs; - - pShbCirBuff->m_fBufferLocked = TRUE; - pShbCirBuff->m_pfnSigHndlrReset = - pfnSignalHandlerReset_p; - } else { - ShbError = kShbAlreadyReseting; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - if (ShbError != kShbOk) { - goto Exit; - } - - // if there is currently no running write operation then reset buffer - // immediately, otherwise wait until the last write job is ready by - // starting a signal process - if (ulNumOfWriteJobs == 0) { - // there is currently no running write operation - // -> reset buffer immediately - ShbCirSignalHandlerReset(pShbInstance_p, FALSE); - ShbError = kShbOk; - } else { - // there is currently at least one running write operation - // -> starting signal process to wait until the last write job is ready - ShbError = - ShbIpcStartSignalingJobReady(pShbInstance_p, ulTimeOut_p, - ShbCirSignalHandlerReset); - } - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Write data block to Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p, - const void *pSrcDataBlock_p, - unsigned long ulDataBlockSize_p) -{ - - tShbCirBuff *pShbCirBuff; - tShbCirBlockSize ShbCirBlockSize; - unsigned int uiFullBlockSize; - unsigned int uiAlignFillBytes; - unsigned char *pShbCirDataPtr; - unsigned char *pScrDataPtr; - unsigned long ulDataSize; - unsigned long ulChunkSize; - unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise - unsigned int fSignalNewData; - unsigned int fSignalReset; - tShbError ShbError; - tShbError ShbError2; - int fRes; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - if (ulDataBlockSize_p > SBC_MAX_BLOCK_SIZE) { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - pScrDataPtr = (unsigned char *)pSrcDataBlock_p; - fSignalNewData = FALSE; - fSignalReset = FALSE; - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // calculate data block size in circular buffer - ulDataSize = - (ulDataBlockSize_p + - (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1); - uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header - uiAlignFillBytes = ulDataSize - ulDataBlockSize_p; - - ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize; - ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes; - - // reserve the needed memory for the write operation to do now - // and make necessary adjustments in the circular buffer header - ShbIpcEnterAtomicSection(pShbInstance_p); - { - // check if there is sufficient memory available to store - // the new data - fRes = - uiFullBlockSize <= - (pShbCirBuff->m_ulBufferDataSize - - pShbCirBuff->m_ulDataInUse); - if (fRes) { - // set write pointer for the write operation to do now - // to the current write pointer of the circular buffer - ulWrIndex = pShbCirBuff->m_ulWrIndex; - - // reserve the needed memory for the write operation to do now - pShbCirBuff->m_ulDataInUse += uiFullBlockSize; - - // set new write pointer behind the reserved memory - // for the write operation to do now - pShbCirBuff->m_ulWrIndex += uiFullBlockSize; - pShbCirBuff->m_ulWrIndex %= - pShbCirBuff->m_ulBufferDataSize; - - // increment number of currently (parallel running) - // write operations - pShbCirBuff->m_ulNumOfWriteJobs++; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - if (!fRes) { - ShbError = kShbBufferFull; - goto Exit; - } - - // copy the data to the circular buffer - // (the copy process itself will be done outside of any - // critical/locked section) - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - - // write real size of current block (incl. alignment fill bytes) - *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize; - ulWrIndex += sizeof(tShbCirBlockSize); - ulWrIndex %= pShbCirBuff->m_ulBufferDataSize; - - if (ulWrIndex + ulDataBlockSize_p <= pShbCirBuff->m_ulBufferDataSize) { - // linear write operation - memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, - ulDataBlockSize_p); - } else { - // wrap-around write operation - ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex; - memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulChunkSize); - memcpy(pShbCirDataPtr, pScrDataPtr + ulChunkSize, - ulDataBlockSize_p - ulChunkSize); - } - - // adjust header information for circular buffer with properties - // of the wiritten data block - ShbIpcEnterAtomicSection(pShbInstance_p); - { - pShbCirBuff->m_ulDataApended += uiFullBlockSize; - pShbCirBuff->m_ulBlocksApended++; - - // decrement number of currently (parallel running) write operations - if (!--pShbCirBuff->m_ulNumOfWriteJobs) { - // if there is no other write process running then - // set new size of readable (complete written) data and - // adjust number of readable blocks - pShbCirBuff->m_ulDataReadable += - pShbCirBuff->m_ulDataApended; - pShbCirBuff->m_ulBlocksReadable += - pShbCirBuff->m_ulBlocksApended; - - pShbCirBuff->m_ulDataApended = 0; - pShbCirBuff->m_ulBlocksApended = 0; - - fSignalNewData = TRUE; - fSignalReset = pShbCirBuff->m_fBufferLocked; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - // signal new data event to a potentially reading application - if (fSignalNewData) { - ShbError2 = ShbIpcSignalNewData(pShbInstance_p); - if (ShbError == kShbOk) { - ShbError = ShbError2; - } - } - // signal that the last write job has been finished to allow - // a waiting application to reset the buffer now - if (fSignalReset) { - ShbError2 = ShbIpcSignalJobReady(pShbInstance_p); - if (ShbError == kShbOk) { - ShbError = ShbError2; - } - } - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Allocate block within the Circular Shared Buffer for chunk writing -//--------------------------------------------------------------------------- - -tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p, - tShbCirChunk * pShbCirChunk_p, - unsigned long ulDataBufferSize_p) -{ - - tShbCirBuff *pShbCirBuff; - tShbCirBlockSize ShbCirBlockSize; - unsigned int uiFullBlockSize; - unsigned int uiAlignFillBytes; - unsigned char *pShbCirDataPtr; - unsigned long ulDataSize; - unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise - tShbError ShbError; - int fRes; - - // check arguments - if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if (ulDataBufferSize_p == 0) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if (ulDataBufferSize_p > SBC_MAX_BLOCK_SIZE) { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // calculate data block size in circular buffer - ulDataSize = - (ulDataBufferSize_p + - (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1); - uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header - uiAlignFillBytes = ulDataSize - ulDataBufferSize_p; - - ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize; - ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes; - - // reserve the needed memory for the write operation to do now - // and make necessary adjustments in the circular buffer header - ShbIpcEnterAtomicSection(pShbInstance_p); - { - // check if there is sufficient memory available to store - // the new data - fRes = - (uiFullBlockSize <= - (pShbCirBuff->m_ulBufferDataSize - - pShbCirBuff->m_ulDataInUse)); - if (fRes) { - // set write pointer for the write operation to do now - // to the current write pointer of the circular buffer - ulWrIndex = pShbCirBuff->m_ulWrIndex; - - // reserve the needed memory for the write operation to do now - pShbCirBuff->m_ulDataInUse += uiFullBlockSize; - - // set new write pointer behind the reserved memory - // for the write operation to do now - pShbCirBuff->m_ulWrIndex += uiFullBlockSize; - pShbCirBuff->m_ulWrIndex %= - pShbCirBuff->m_ulBufferDataSize; - - // increment number of currently (parallel running) - // write operations - pShbCirBuff->m_ulNumOfWriteJobs++; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - if (!fRes) { - ShbError = kShbBufferFull; - goto Exit; - } - - // setup header information for allocated buffer - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - - // write real size of current block (incl. alignment fill bytes) - *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize; - ulWrIndex += sizeof(tShbCirBlockSize); - ulWrIndex %= pShbCirBuff->m_ulBufferDataSize; - - // setup chunk descriptor - pShbCirChunk_p->m_uiFullBlockSize = uiFullBlockSize; - pShbCirChunk_p->m_ulAvailableSize = ulDataBufferSize_p; - pShbCirChunk_p->m_ulWrIndex = ulWrIndex; - pShbCirChunk_p->m_fBufferCompleted = FALSE; - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Write data chunk into an allocated buffer of the Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p, - tShbCirChunk *pShbCirChunk_p, - const void *pSrcDataChunk_p, - unsigned long ulDataChunkSize_p, - unsigned int *pfBufferCompleted_p) -{ - - tShbCirBuff *pShbCirBuff; - unsigned char *pShbCirDataPtr; - unsigned char *pScrDataPtr; - unsigned long ulSubChunkSize; - unsigned long ulWrIndex; - unsigned int fBufferCompleted; - unsigned int fSignalNewData; - unsigned int fSignalReset; - tShbError ShbError; - tShbError ShbError2; - - // check arguments - if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL) - || (pfBufferCompleted_p == NULL)) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if ((pSrcDataChunk_p == NULL) || (ulDataChunkSize_p == 0)) { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - if (pShbCirChunk_p->m_fBufferCompleted) { - ShbError = kShbBufferAlreadyCompleted; - goto Exit; - } - - if (ulDataChunkSize_p > pShbCirChunk_p->m_ulAvailableSize) { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - pScrDataPtr = (unsigned char *)pSrcDataChunk_p; - fSignalNewData = FALSE; - fSignalReset = FALSE; - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - ulWrIndex = pShbCirChunk_p->m_ulWrIndex; - - // copy the data to the circular buffer - // (the copy process itself will be done outside of any - // critical/locked section) - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - - if (ulWrIndex + ulDataChunkSize_p <= pShbCirBuff->m_ulBufferDataSize) { - // linear write operation - memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, - ulDataChunkSize_p); - } else { - // wrap-around write operation - ulSubChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex; - memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulSubChunkSize); - memcpy(pShbCirDataPtr, pScrDataPtr + ulSubChunkSize, - ulDataChunkSize_p - ulSubChunkSize); - } - - // adjust chunk descriptor - ulWrIndex += ulDataChunkSize_p; - ulWrIndex %= pShbCirBuff->m_ulBufferDataSize; - - pShbCirChunk_p->m_ulAvailableSize -= ulDataChunkSize_p; - pShbCirChunk_p->m_ulWrIndex = ulWrIndex; - - fBufferCompleted = (pShbCirChunk_p->m_ulAvailableSize == 0); - pShbCirChunk_p->m_fBufferCompleted = fBufferCompleted; - - // if the complete allocated buffer is filled with data then - // adjust header information for circular buffer with properties - // of the wiritten data block - if (fBufferCompleted) { - ShbIpcEnterAtomicSection(pShbInstance_p); - { - pShbCirBuff->m_ulDataApended += - pShbCirChunk_p->m_uiFullBlockSize; - pShbCirBuff->m_ulBlocksApended++; - - // decrement number of currently (parallel running) write operations - if (!--pShbCirBuff->m_ulNumOfWriteJobs) { - // if there is no other write process running then - // set new size of readable (complete written) data and - // adjust number of readable blocks - pShbCirBuff->m_ulDataReadable += - pShbCirBuff->m_ulDataApended; - pShbCirBuff->m_ulBlocksReadable += - pShbCirBuff->m_ulBlocksApended; - - pShbCirBuff->m_ulDataApended = 0; - pShbCirBuff->m_ulBlocksApended = 0; - - fSignalNewData = TRUE; - fSignalReset = pShbCirBuff->m_fBufferLocked; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - } - - // signal new data event to a potentially reading application - if (fSignalNewData) { - ShbError2 = ShbIpcSignalNewData(pShbInstance_p); - if (ShbError == kShbOk) { - ShbError = ShbError2; - } - } - // signal that the last write job has been finished to allow - // a waiting application to reset the buffer now - if (fSignalReset) { - ShbError2 = ShbIpcSignalJobReady(pShbInstance_p); - if (ShbError == kShbOk) { - ShbError = ShbError2; - } - } - - *pfBufferCompleted_p = fBufferCompleted; - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Read data block from Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p, - void *pDstDataBlock_p, - unsigned long ulRdBuffSize_p, - unsigned long *pulDataBlockSize_p) -{ - - tShbCirBuff *pShbCirBuff; - tShbCirBlockSize ShbCirBlockSize; - unsigned long ulDataReadable; - unsigned char *pShbCirDataPtr; - unsigned char *pDstDataPtr; - unsigned long ulDataSize = 0; // d.k. GCC complains about uninitialized variable otherwise - unsigned long ulChunkSize; - unsigned long ulRdIndex; - tShbError ShbError; - - // check arguments - if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) { - return (kShbInvalidArg); - } - - if ((pDstDataBlock_p == NULL) || (ulRdBuffSize_p == 0)) { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - ShbError = kShbOk; - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - pDstDataPtr = (unsigned char *)pDstDataBlock_p; - ulDataSize = 0; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // get total number of readable bytes for the whole circular buffer - ShbIpcEnterAtomicSection(pShbInstance_p); - { - ulDataReadable = pShbCirBuff->m_ulDataReadable; - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - // if there are readable data available, then there must be at least - // one complete readable data block - if (ulDataReadable > 0) { - // get pointer to start of data area and current read index - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - ulRdIndex = pShbCirBuff->m_ulRdIndex; - - // get real size of current block (incl. alignment fill bytes) - ShbCirBlockSize = - *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex); - ulRdIndex += sizeof(tShbCirBlockSize); - ulRdIndex %= pShbCirBuff->m_ulBufferDataSize; - - // get size of user data inside the current block - ulDataSize = - ShbCirBlockSize.m_uiFullBlockSize - - ShbCirBlockSize.m_uiAlignFillBytes; - ulDataSize -= sizeof(tShbCirBlockSize); - } - - // ulDataSize = MIN(ulDataSize, ulRdBuffSize_p); - if (ulDataSize > ulRdBuffSize_p) { - ulDataSize = ulRdBuffSize_p; - ShbError = kShbDataTruncated; - } - - if (ulDataSize == 0) { - // nothing to do here - ShbError = kShbNoReadableData; - goto Exit; - } - - // copy the data from the circular buffer - // (the copy process itself will be done outside of any - // critical/locked section) - if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) { - // linear read operation - memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulDataSize); - } else { - // wrap-around read operation - ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex; - memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulChunkSize); - memcpy(pDstDataPtr + ulChunkSize, pShbCirDataPtr, - ulDataSize - ulChunkSize); - } - -#ifndef NDEBUG - { - tShbCirBlockSize ClrShbCirBlockSize; - - if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) { - // linear buffer - memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulDataSize); - } else { - // wrap-around read operation - ulChunkSize = - pShbCirBuff->m_ulBufferDataSize - ulRdIndex; - memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulChunkSize); - memset(pShbCirDataPtr, 0xDD, ulDataSize - ulChunkSize); - } - - ClrShbCirBlockSize.m_uiFullBlockSize = /*(unsigned int) */ -1; // -1 = xFFFFFFF - ClrShbCirBlockSize.m_uiAlignFillBytes = /*(unsigned int) */ -1; // -1 = Fxxxxxxx - *(tShbCirBlockSize *) (pShbCirDataPtr + - pShbCirBuff->m_ulRdIndex) = - ClrShbCirBlockSize; - } -#endif // #ifndef NDEBUG - - // set new size of readable data, data in use, new read index - // and adjust number of readable blocks - ShbIpcEnterAtomicSection(pShbInstance_p); - { - pShbCirBuff->m_ulDataInUse -= ShbCirBlockSize.m_uiFullBlockSize; - pShbCirBuff->m_ulDataReadable -= - ShbCirBlockSize.m_uiFullBlockSize; - pShbCirBuff->m_ulBlocksReadable--; - - //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ - if ((pShbCirBuff->m_ulDataInUse == 0) - && (pShbCirBuff->m_ulDataReadable == 0)) { - ASSERT(pShbCirBuff->m_ulBlocksReadable == 0); - - pShbCirBuff->m_ulWrIndex = 0; - pShbCirBuff->m_ulRdIndex = 0; - } else - //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ - { - pShbCirBuff->m_ulRdIndex += - ShbCirBlockSize.m_uiFullBlockSize; - pShbCirBuff->m_ulRdIndex %= - pShbCirBuff->m_ulBufferDataSize; - } - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - Exit: - - *pulDataBlockSize_p = ulDataSize; - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Get data size of next readable block from Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p, - unsigned long *pulDataBlockSize_p) -{ - - tShbCirBuff *pShbCirBuff; - unsigned long ulDataReadable; - unsigned char *pShbCirDataPtr; - tShbCirBlockSize ShbCirBlockSize; - unsigned long ulDataSize; - tShbError ShbError; - - // check arguments - if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) { - return (kShbInvalidArg); - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ulDataSize = 0; - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // get total number of readable bytes for the whole circular buffer - ShbIpcEnterAtomicSection(pShbInstance_p); - { - ulDataReadable = pShbCirBuff->m_ulDataReadable; - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - // if there are readable data available, then there must be at least - // one complete readable data block - if (ulDataReadable > 0) { - pShbCirDataPtr = - &pShbCirBuff->m_Data + pShbCirBuff->m_ulRdIndex; - - // get real size of current block (incl. alignment fill bytes) - ShbCirBlockSize = *(tShbCirBlockSize *) pShbCirDataPtr; - - // get size of user data inside the current block - ulDataSize = - ShbCirBlockSize.m_uiFullBlockSize - - ShbCirBlockSize.m_uiAlignFillBytes; - ulDataSize -= sizeof(tShbCirBlockSize); - } - - Exit: - - *pulDataBlockSize_p = ulDataSize; - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Get number of readable blocks from Circular Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p, - unsigned long *pulDataBlockCount_p) -{ - - tShbCirBuff *pShbCirBuff; - unsigned long ulBlockCount; - tShbError ShbError; - - // check arguments - if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) { - ShbError = kShbInvalidArg; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ulBlockCount = 0; - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - ShbIpcEnterAtomicSection(pShbInstance_p); - { - ulBlockCount = pShbCirBuff->m_ulBlocksReadable; - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - *pulDataBlockCount_p = ulBlockCount; - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Set application handler to signal new data for Circular Shared Buffer -// d.k.: new parameter priority as enum -//--------------------------------------------------------------------------- - -tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p, - tShbCirSigHndlrNewData pfnSignalHandlerNewData_p, - tShbPriority ShbPriority_p) -{ - - tShbCirBuff *pShbCirBuff; - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - if (pfnSignalHandlerNewData_p != NULL) { - // set a new signal handler - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { - ShbError = kShbAlreadySignaling; - goto Exit; - } - - pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; - ShbError = - ShbIpcStartSignalingNewData(pShbInstance_p, - ShbCirSignalHandlerNewData, - ShbPriority_p); - } else { - // remove existing signal handler - ShbError = ShbIpcStopSignalingNewData(pShbInstance_p); - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { - pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, 0); - } - pShbCirBuff->m_pfnSigHndlrNewData = NULL; - } - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// DEBUG: Trace Circular Shared Buffer -//--------------------------------------------------------------------------- - -#ifndef NDEBUG -tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p) -{ - - tShbCirBuff *pShbCirBuff; - char szMagigID[sizeof(SBC_MAGIC_ID) + 1]; - tShbCirBlockSize ShbCirBlockSize; - unsigned long ulDataReadable; - unsigned char *pShbCirDataPtr; - unsigned long ulBlockIndex; - unsigned int nBlockCount; - unsigned long ulDataSize; - unsigned long ulChunkSize; - unsigned long ulRdIndex; - tShbError ShbError; - - TRACE0("\n\n##### Circular Shared Buffer #####\n"); - - // check arguments - if (pShbInstance_p == NULL) { - TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", - (unsigned long)pShbInstance_p); - ShbError = kShbInvalidArg; - goto Exit; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - *(unsigned long *)&szMagigID[0] = pShbCirBuff->m_ShbCirMagicID; - szMagigID[sizeof(SBC_MAGIC_ID)] = '\0'; - - ShbIpcEnterAtomicSection(pShbInstance_p); - { - TRACE1("\nBuffer Address: 0x%08lX\n", - (unsigned long)pShbCirBuff); - - TRACE0("\nHeader Info:"); - TRACE2("\nMagigID: '%s' (%08lX)", szMagigID, - pShbCirBuff->m_ShbCirMagicID); - TRACE1("\nBufferTotalSize: %4lu [Bytes]", - pShbCirBuff->m_ulBufferTotalSize); - TRACE1("\nBufferDataSize: %4lu [Bytes]", - pShbCirBuff->m_ulBufferDataSize); - TRACE1("\nWrIndex: %4lu", pShbCirBuff->m_ulWrIndex); - TRACE1("\nRdIndex: %4lu", pShbCirBuff->m_ulRdIndex); - TRACE1("\nNumOfWriteJobs: %4lu", - pShbCirBuff->m_ulNumOfWriteJobs); - TRACE1("\nDataInUse: %4lu [Bytes]", - pShbCirBuff->m_ulDataInUse); - TRACE1("\nDataApended: %4lu [Bytes]", - pShbCirBuff->m_ulDataApended); - TRACE1("\nBlocksApended: %4lu", - pShbCirBuff->m_ulBlocksApended); - TRACE1("\nDataReadable: %4lu [Bytes]", - pShbCirBuff->m_ulDataReadable); - TRACE1("\nBlocksReadable: %4lu", - pShbCirBuff->m_ulBlocksReadable); - TRACE1("\nSigHndlrNewData: %08lX", - (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData); - TRACE1("\nBufferLocked: %d", pShbCirBuff->m_fBufferLocked); - TRACE1("\nSigHndlrReset: %08lX", - (unsigned long)pShbCirBuff->m_pfnSigHndlrReset); - - ShbTraceDump(&pShbCirBuff->m_Data, - pShbCirBuff->m_ulBufferDataSize, 0x00000000L, - "\nData Area:"); - - ulDataReadable = pShbCirBuff->m_ulDataReadable; - nBlockCount = 1; - ulBlockIndex = pShbCirBuff->m_ulRdIndex; - - while (ulDataReadable > 0) { - TRACE1("\n\n--- Block #%u ---", nBlockCount); - - // get pointer to start of data area and current read index - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - ulRdIndex = ulBlockIndex; - - // get real size of current block (incl. alignment fill bytes) - ShbCirBlockSize = - *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex); - ulRdIndex += sizeof(tShbCirBlockSize); - ulRdIndex %= pShbCirBuff->m_ulBufferDataSize; - - // get size of user data inside the current block - ulDataSize = - ShbCirBlockSize.m_uiFullBlockSize - - ShbCirBlockSize.m_uiAlignFillBytes; - ulDataSize -= sizeof(tShbCirBlockSize); - - TRACE1 - ("\nFull Data Size: %4u [Bytes] (incl. header and alignment fill bytes)", - ShbCirBlockSize.m_uiFullBlockSize); - TRACE1("\nUser Data Size: %4lu [Bytes]", - ulDataSize); - TRACE1("\nAlignment Fill Bytes: %4u [Bytes]", - ShbCirBlockSize.m_uiAlignFillBytes); - - if (ulRdIndex + ulDataSize <= - pShbCirBuff->m_ulBufferDataSize) { - // linear data buffer - ShbTraceDump(pShbCirDataPtr + ulRdIndex, - ulDataSize, 0x00000000L, NULL); - } else { - // wrap-around data buffer - ulChunkSize = - pShbCirBuff->m_ulBufferDataSize - ulRdIndex; - ShbTraceDump(pShbCirDataPtr + ulRdIndex, - ulChunkSize, 0x00000000L, NULL); - ShbTraceDump(pShbCirDataPtr, - ulDataSize - ulChunkSize, - ulChunkSize, NULL); - } - - nBlockCount++; - - ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize; - ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize; - - ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize; - } - - ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount - 1); - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - Exit: - - return (ShbError); - -} -#endif - -//-------------------------------------------------------------------------// -// // -// L i n e a r S h a r e d B u f f e r // -// // -//-------------------------------------------------------------------------// - -//--------------------------------------------------------------------------- -// Allocate Linear Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p) -{ - - tShbInstance pShbInstance; - tShbLinBuff *pShbLinBuff; - unsigned int fShbNewCreated; - unsigned long ulBufferDataSize; - unsigned long ulBufferTotalSize; - tShbError ShbError; - - // check arguments - if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) { - return (kShbInvalidArg); - } - - // calculate length of memory to allocate - ulBufferDataSize = - (ulBufferSize_p + - (SBL_BLOCK_ALIGNMENT - 1)) & ~(SBL_BLOCK_ALIGNMENT - 1); - ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff); - - // allocate a new or open an existing shared buffer - ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p, - &pShbInstance, &fShbNewCreated); - if (ShbError != kShbOk) { - goto Exit; - } - - if (pShbInstance == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - - // get pointer to shared buffer - pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance); - - // if the shared buffer was new created, than this process has - // to initialize it, otherwise the buffer is already in use - // and *must not* be reseted - if (fShbNewCreated) { -#ifndef NDEBUG - { - memset(pShbLinBuff, 0xCC, ulBufferTotalSize); - } -#endif - - pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID; - pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize; - pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize; - } else { - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - } - - Exit: - - *ppShbInstance_p = pShbInstance; - *pfShbNewCreated_p = fShbNewCreated; - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Release Linear Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p) -{ - - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbOk; - goto Exit; - } - - ShbError = ShbIpcReleaseBuffer(pShbInstance_p); - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Write data block to Linear Shared Buffer -//--------------------------------------------------------------------------- -tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p, - unsigned long ulDstBufferOffs_p, - const void *pSrcDataBlock_p, - unsigned long ulDataBlockSize_p) -{ - - tShbLinBuff *pShbLinBuff; - unsigned char *pShbLinDataPtr; - unsigned char *pScrDataPtr; - unsigned long ulBufferDataSize; - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); - pScrDataPtr = (unsigned char *)pSrcDataBlock_p; - ShbError = kShbOk; - - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // check if offeset and size for the write operation matches with - // the size of the shared buffer - ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; - if ((ulDstBufferOffs_p > ulBufferDataSize) || - (ulDataBlockSize_p > ulBufferDataSize) || - ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) { - ShbError = kShbDataOutsideBufferArea; - goto Exit; - } - - // copy the data to the linear buffer - // (the copy process will be done inside of any critical/locked section) - pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area - pShbLinDataPtr += ulDstBufferOffs_p; - - ShbIpcEnterAtomicSection(pShbInstance_p); - { - memcpy(pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p); - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Read data block from Linear Shared Buffer -//--------------------------------------------------------------------------- -tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p, - void *pDstDataBlock_p, - unsigned long ulSrcBufferOffs_p, - unsigned long ulDataBlockSize_p) -{ - - tShbLinBuff *pShbLinBuff; - unsigned char *pShbLinDataPtr; - unsigned char *pDstDataPtr; - unsigned long ulBufferDataSize; - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - - if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); - pDstDataPtr = (unsigned char *)pDstDataBlock_p; - ShbError = kShbOk; - - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - // check if offeset and size for the read operation matches with - // the size of the shared buffer - ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; - if ((ulSrcBufferOffs_p > ulBufferDataSize) || - (ulDataBlockSize_p > ulBufferDataSize) || - ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) { - ShbError = kShbDataOutsideBufferArea; - goto Exit; - } - - // copy the data to the linear buffer - // (the copy process will be done inside of any critical/locked section) - pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area - pShbLinDataPtr += ulSrcBufferOffs_p; - - ShbIpcEnterAtomicSection(pShbInstance_p); - { - memcpy(pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p); - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// DEBUG: Trace Linear Shared Buffer -//--------------------------------------------------------------------------- - -#ifndef NDEBUG -tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p) -{ - - tShbLinBuff *pShbLinBuff; - char szMagigID[sizeof(SBL_MAGIC_ID) + 1]; - tShbError ShbError; - - TRACE0("\n\n##### Linear Shared Buffer #####\n"); - - // check arguments - if (pShbInstance_p == NULL) { - TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", - (unsigned long)pShbInstance_p); - ShbError = kShbInvalidArg; - goto Exit; - } - - pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - *(unsigned int *)&szMagigID[0] = pShbLinBuff->m_ShbLinMagicID; - szMagigID[sizeof(SBL_MAGIC_ID)] = '\0'; - - ShbIpcEnterAtomicSection(pShbInstance_p); - { - TRACE1("\nBuffer Address: 0x%08lX\n", - (unsigned long)pShbLinBuff); - - TRACE0("\nHeader Info:"); - TRACE2("\nMagigID: '%s' (%08X)", szMagigID, - pShbLinBuff->m_ShbLinMagicID); - TRACE1("\nBufferTotalSize: %4lu [Bytes]", - pShbLinBuff->m_ulBufferTotalSize); - TRACE1("\nBufferDataSize: %4lu [Bytes]", - pShbLinBuff->m_ulBufferDataSize); - - ShbTraceDump(&pShbLinBuff->m_Data, - pShbLinBuff->m_ulBufferDataSize, 0x00000000L, - "\nData Area:"); - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - Exit: - - return (ShbError); - -} -#endif - -//--------------------------------------------------------------------------- -// Dump buffer contents -//--------------------------------------------------------------------------- - -#ifndef NDEBUG -tShbError ShbTraceDump(const unsigned char *pabStartAddr_p, - unsigned long ulDataSize_p, - unsigned long ulAddrOffset_p, const char *pszInfoText_p) -{ - - const unsigned char *pabBuffData; - unsigned long ulBuffSize; - unsigned char bData; - int nRow; - int nCol; - - // get pointer to buffer and length of buffer - pabBuffData = pabStartAddr_p; - ulBuffSize = ulDataSize_p; - - if (pszInfoText_p != NULL) { - TRACE1("%s", pszInfoText_p); - } - // dump buffer contents - for (nRow = 0;; nRow++) { - TRACE1("\n%08lX: ", - (unsigned long)(nRow * 0x10) + ulAddrOffset_p); - - for (nCol = 0; nCol < 16; nCol++) { - if ((unsigned long)nCol < ulBuffSize) { - TRACE1("%02X ", - (unsigned int)*(pabBuffData + nCol)); - } else { - TRACE0(" "); - } - } - - TRACE0(" "); - - for (nCol = 0; nCol < 16; nCol++) { - bData = *pabBuffData++; - if ((unsigned long)nCol < ulBuffSize) { - if ((bData >= 0x20) && (bData < 0x7F)) { - TRACE1("%c", bData); - } else { - TRACE0("."); - } - } else { - TRACE0(" "); - } - } - - if (ulBuffSize > 16) { - ulBuffSize -= 16; - } else { - break; - } - } - - return (kShbOk); - -} -#endif // #ifndef NDEBUG - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// Handler to signal new data event for Circular Shared Buffer -//--------------------------------------------------------------------------- - -int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p) -{ - - tShbCirBuff *pShbCirBuff; - unsigned long ulDataSize; - unsigned long ulBlockCount; - tShbError ShbError; - - // check arguments - if (pShbInstance_p == NULL) { - return FALSE; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - return FALSE; - } - - // call application handler - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { -/* do - {*/ - ShbError = ShbCirGetReadDataSize(pShbInstance_p, &ulDataSize); - if ((ulDataSize > 0) && (ShbError == kShbOk)) { - pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, - ulDataSize); - } - - ShbError = - ShbCirGetReadBlockCount(pShbInstance_p, &ulBlockCount); -/* } - while ((ulBlockCount > 0) && (ShbError == kShbOk));*/ - } - // Return TRUE if there are pending blocks. - // In that case ShbIpc tries to call this function again immediately if there - // is no other filled shared buffer with higher priority. - return ((ulBlockCount > 0) && (ShbError == kShbOk)); - -} - -//--------------------------------------------------------------------------- -// Handler to reset Circular Shared Buffer -//--------------------------------------------------------------------------- - -void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p, - unsigned int fTimeOut_p) -{ - - tShbCirBuff *pShbCirBuff; - - // check arguments - if (pShbInstance_p == NULL) { - return; - } - - pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { - return; - } - - // reset buffer header - if (!fTimeOut_p) { - ShbIpcEnterAtomicSection(pShbInstance_p); - { - pShbCirBuff->m_ulWrIndex = 0; - pShbCirBuff->m_ulRdIndex = 0; - pShbCirBuff->m_ulNumOfWriteJobs = 0; - pShbCirBuff->m_ulDataInUse = 0; - pShbCirBuff->m_ulDataApended = 0; - pShbCirBuff->m_ulBlocksApended = 0; - pShbCirBuff->m_ulDataReadable = 0; - pShbCirBuff->m_ulBlocksReadable = 0; - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - -#ifndef NDEBUG - { - memset(&pShbCirBuff->m_Data, 0xCC, - pShbCirBuff->m_ulBufferDataSize); - } -#endif - } - - // call application handler - if (pShbCirBuff->m_pfnSigHndlrReset != NULL) { - pShbCirBuff->m_pfnSigHndlrReset(pShbInstance_p, fTimeOut_p); - } - - // unlock buffer - ShbIpcEnterAtomicSection(pShbInstance_p); - { - pShbCirBuff->m_fBufferLocked = FALSE; - pShbCirBuff->m_pfnSigHndlrReset = NULL; - } - ShbIpcLeaveAtomicSection(pShbInstance_p); - - return; - -} - -// EOF diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h deleted file mode 100644 index 4edbd0b2bd5..00000000000 --- a/drivers/staging/epl/SharedBuff.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Declaration of platform independend part for the - shared buffer - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/06/27 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#ifndef _SHAREDBUFF_H_ -#define _SHAREDBUFF_H_ - -//--------------------------------------------------------------------------- -// Type definitions -//--------------------------------------------------------------------------- - -typedef enum { - kShbOk = 0, - kShbNoReadableData = 1, - kShbDataTruncated = 2, - kShbBufferFull = 3, - kShbDataOutsideBufferArea = 4, - kShbBufferAlreadyCompleted = 5, - kShbMemUsedByOtherProcs = 6, - kShbOpenMismatch = 7, - kShbInvalidBufferType = 8, - kShbInvalidArg = 9, - kShbBufferInvalid = 10, - kShbOutOfMem = 11, - kShbAlreadyReseting = 12, - kShbAlreadySignaling = 13, - kShbExceedDataSizeLimit = 14, - -} tShbError; - -// 2006/08/24 d.k.: Priority for threads (new data, job signaling) -typedef enum { - kShbPriorityLow = 0, - kShbPriorityNormal = 1, - kshbPriorityHigh = 2 -} tShbPriority; - -typedef struct { - unsigned int m_uiFullBlockSize; // real size of allocated block (incl. alignment fill bytes) - unsigned long m_ulAvailableSize; // still available size for data - unsigned long m_ulWrIndex; // current write index - unsigned int m_fBufferCompleted; // TRUE if allocated block is complete filled with data - -} tShbCirChunk; - -typedef void *tShbInstance; - -typedef void (*tShbCirSigHndlrNewData) (tShbInstance pShbInstance_p, - unsigned long ulDataBlockSize_p); -typedef void (*tShbCirSigHndlrReset) (tShbInstance pShbInstance_p, - unsigned int fTimeOut_p); - -//--------------------------------------------------------------------------- -// Prototypes -//--------------------------------------------------------------------------- - -#ifdef __cplusplus -extern "C" { -#endif - - tShbError ShbInit(void); - tShbError ShbExit(void); - -// Circular Shared Buffer - tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p); - tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p); - - - tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p, - unsigned long ulTimeOut_p, - tShbCirSigHndlrReset - pfnSignalHandlerReset_p); - tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p, - const void *pSrcDataBlock_p, - unsigned long ulDataBlockSize_p); - tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p, - tShbCirChunk * pShbCirChunk_p, - unsigned long ulDataBufferSize_p); - tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p, - tShbCirChunk * pShbCirChunk_p, - const void *pSrcDataChunk_p, - unsigned long ulDataChunkSize_p, - unsigned int *pfBufferCompleted_p); - tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p, - void *pDstDataBlock_p, - unsigned long ulRdBuffSize_p, - unsigned long *pulDataBlockSize_p); - tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p, - unsigned long *pulDataBlockSize_p); - tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p, - unsigned long *pulDataBlockCount_p); - tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p, - tShbCirSigHndlrNewData - pfnShbSignalHandlerNewData_p, - tShbPriority ShbPriority_p); - - -// Linear Shared Buffer - tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p); - tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p); - - - tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p, - unsigned long ulDstBufferOffs_p, - const void *pSrcDataBlock_p, - unsigned long ulDataBlockSize_p); - tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p, - void *pDstDataBlock_p, - unsigned long ulSrcBufferOffs_p, - unsigned long ulDataBlockSize_p); - - -#ifndef NDEBUG - tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p); - tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p); - tShbError ShbTraceDump(const unsigned char *pabStartAddr_p, - unsigned long ulDataSize_p, - unsigned long ulAddrOffset_p, - const char *pszInfoText_p); -#else -#define ShbCirTraceBuffer(p0) -#define ShbLinTraceBuffer(p0) -#define ShbTraceDump(p0, p1, p2, p3) -#endif - -#ifdef __cplusplus -} -#endif -#endif // #ifndef _SHAREDBUFF_H_ diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c deleted file mode 100644 index 12d1eccde25..00000000000 --- a/drivers/staging/epl/ShbIpc-LinuxKernel.c +++ /dev/null @@ -1,944 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Implementation of platform specific part for the - shared buffer - (Implementation for Linux KernelSpace) - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/06/28 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#include "global.h" -#include "SharedBuff.h" -#include "ShbIpc.h" -#include "ShbLinuxKernel.h" -#include "Debug.h" - -#include -#include -#include -//#include -#include -#include -#include -#include -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// Configuration -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Constant definitions -//--------------------------------------------------------------------------- - -#define MAX_LEN_BUFFER_ID 256 - -#define TIMEOUT_ENTER_ATOMIC 1000 // (ms) for debgging: INFINITE -#define TIMEOUT_TERM_THREAD 1000 -#define INFINITE 3600 - -#define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+") -#define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*") - -#define INVALID_ID -1 - -#define TABLE_SIZE 10 - -//--------------------------------------------------------------------------- -// Local types -//--------------------------------------------------------------------------- - -// This structure is the common header for the shared memory region used -// by all processes attached this shared memory. It includes common -// information to administrate/manage the shared buffer from a couple of -// separated processes (e.g. the refernce counter). This structure is -// located at the start of the shared memory region itself and exists -// consequently only one times per shared memory instance. -typedef struct { - - unsigned long m_ulShMemSize; - unsigned long m_ulRefCount; - int m_iBufferId; -// int m_iUserSpaceMem; //0 for userspace mem !=0 kernelspace mem - spinlock_t m_SpinlockBuffAccess; - BOOL m_fNewData; - BOOL m_fJobReady; - wait_queue_head_t m_WaitQueueNewData; - wait_queue_head_t m_WaitQueueJobReady; - -#ifndef NDEBUG - unsigned long m_ulOwnerProcID; -#endif - -} tShbMemHeader; - -// This structure is the "external entry point" from a separate process -// to get access to a shared buffer. This structure includes all platform -// resp. target specific information to administrate/manage the shared -// buffer from a separate process. Every process attached to the shared -// buffer has its own runtime instance of this structure with its individual -// runtime data (e.g. the scope of an event handle is limitted to the -// owner process only). The structure member points -// to the (process specific) start address of the shared memory region -// itself. -typedef struct { - unsigned long m_SbiMagicID; // magic ID ("SBI+") -// void* m_pSharedMem; - int m_tThreadNewDataId; - long m_lThreadNewDataNice; // nice value of the new data thread - int m_tThreadJobReadyId; - unsigned long m_ulFlagsBuffAccess; // d.k. moved from tShbMemHeader, because each - // process needs to store the interrupt flags separately - tSigHndlrNewData m_pfnSigHndlrNewData; - unsigned long m_ulTimeOutJobReady; - tSigHndlrJobReady m_pfnSigHndlrJobReady; - tShbMemHeader *m_pShbMemHeader; - int m_iThreadTermFlag; - struct completion m_CompletionNewData; -/* - struct semaphore *m_pSemBuffAccess; - struct semaphore *m_pSemNewData; - struct semaphore *m_pSemStopSignalingNewData; - struct semaphore *m_pSemJobReady; -*/ -#ifndef NDEBUG - unsigned long m_ulThreadIDNewData; - unsigned long m_ulThreadIDJobReady; -#endif -} tShbMemInst; - -//--------------------------------------------------------------------------- -// Prototypes of internal functions -//--------------------------------------------------------------------------- - -//tShbMemInst* ShbIpcGetShbMemInst (tShbInstance pShbInstance_p); -//tShbMemHeader* ShbIpcGetShbMemHeader (tShbMemInst* pShbMemInst_p); - -//--------------------------------------------------------------------------- -// Get pointer to process local information structure -//--------------------------------------------------------------------------- - -static inline tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - - pShbMemInst = (tShbMemInst *) pShbInstance_p; - - return (pShbMemInst); - -} - -//--------------------------------------------------------------------------- -// Get pointer to shared memory header -//--------------------------------------------------------------------------- - -static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p) -{ - - tShbMemHeader *pShbMemHeader; - - pShbMemHeader = pShbMemInst_p->m_pShbMemHeader; - - return (pShbMemHeader); - -} - -// Get pointer to process local information structure -//#define ShbIpcGetShbMemInst(pShbInstance_p) ((tShbMemInst*)pShbInstance_p) - -// Get pointer to shared memory header -//#define ShbIpcGetShbMemHeader(pShbMemInst_p) (pShbMemInst_p->m_pShbMemHeader) - -// not inlined internal functions -int ShbIpcThreadSignalNewData(void *pvThreadParam_p); -int ShbIpcThreadSignalJobReady(void *pvThreadParam_p); - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -struct sShbMemTable *psMemTableElementFirst_g; - -static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p); -static int ShbIpcFindListElement(int iBufferId, - struct sShbMemTable - **ppsReturnMemTableElement); -static void ShbIpcAppendListElement(struct sShbMemTable *sNewMemTableElement); -static void ShbIpcDeleteListElement(int iBufferId); -static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]); -static unsigned long ShbIpcCrc32GetCrc(const char *pcString, - unsigned long aulCrcTable[256]); - - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -// not inlined external functions - -//--------------------------------------------------------------------------- -// Initialize IPC for Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbIpcInit(void) -{ - psMemTableElementFirst_g = NULL; - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Deinitialize IPC for Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbIpcExit(void) -{ - - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Allocate Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p) -{ - tShbError ShbError; - int iBufferId = 0; - unsigned long ulCrc32 = 0; - unsigned int uiFirstProcess = 0; - unsigned long ulShMemSize; - tShbMemHeader *pShbMemHeader; - tShbMemInst *pShbMemInst = NULL; - tShbInstance pShbInstance; - unsigned int fShMemNewCreated = FALSE; - void *pSharedMem = NULL; - unsigned long aulCrcTable[256]; - struct sShbMemTable *psMemTableElement; - - DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n"); - ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader); - - //create Buffer ID - ShbIpcCrc32GenTable(aulCrcTable); - ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable); - iBufferId = ulCrc32; - DEBUG_LVL_29_TRACE2 - ("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n", - ulBufferSize_p, sizeof(tShbMemHeader)); - DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n", - iBufferId, ulShMemSize); - //--------------------------------------------------------------- - // (1) open an existing or create a new shared memory - //--------------------------------------------------------------- - //test if buffer already exists - if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0) { - //Buffer already exists - fShMemNewCreated = FALSE; - pSharedMem = psMemTableElement->m_pBuffer; - DEBUG_LVL_29_TRACE1 - ("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n", - pSharedMem); - uiFirstProcess = 1; - } else { - //create new Buffer - fShMemNewCreated = TRUE; - uiFirstProcess = 0; - pSharedMem = kmalloc(ulShMemSize, GFP_KERNEL); - DEBUG_LVL_29_TRACE2 - ("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n", - pSharedMem, iBufferId); - if (pSharedMem == NULL) { - //unable to create mem - ShbError = kShbOutOfMem; - goto Exit; - } - DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n"); - // append Element to Mem Table - psMemTableElement = - kmalloc(sizeof(struct sShbMemTable), GFP_KERNEL); - psMemTableElement->m_iBufferId = iBufferId; - psMemTableElement->m_pBuffer = pSharedMem; - psMemTableElement->m_psNextMemTableElement = NULL; - ShbIpcAppendListElement(psMemTableElement); - } - - DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n"); - //update header - pShbMemHeader = (tShbMemHeader *) pSharedMem; - DEBUG_LVL_29_TRACE1 - ("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n", - pShbMemHeader->m_ulShMemSize); - // allocate a memory block from process specific mempool to save - // process local information to administrate/manage the shared buffer - DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n"); - pShbMemInst = - (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst)); - if (pShbMemInst == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - // reset complete header to default values - //pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID; -// pShbMemInst->m_pSharedMem = pSharedMem; - pShbMemInst->m_tThreadNewDataId = INVALID_ID; - pShbMemInst->m_tThreadJobReadyId = INVALID_ID; - pShbMemInst->m_pfnSigHndlrNewData = NULL; - pShbMemInst->m_ulTimeOutJobReady = 0; - pShbMemInst->m_pfnSigHndlrJobReady = NULL; - pShbMemInst->m_pShbMemHeader = pShbMemHeader; - pShbMemInst->m_iThreadTermFlag = 0; - - // initialize completion etc. - init_completion(&pShbMemInst->m_CompletionNewData); - - ShbError = kShbOk; - if (fShMemNewCreated) { - // this process was the first who wanted to use the shared memory, - // so a new shared memory was created - // -> setup new header information inside the shared memory region - // itself - pShbMemHeader->m_ulShMemSize = ulShMemSize; - pShbMemHeader->m_ulRefCount = 1; - pShbMemHeader->m_iBufferId = iBufferId; - // initialize spinlock - spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess); - // initialize wait queues - init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData); - init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady); - } else { - // any other process has created the shared memory and this - // process only has to attach to it - // -> check and update existing header information inside the - // shared memory region itself - if (pShbMemHeader->m_ulShMemSize != ulShMemSize) { - ShbError = kShbOpenMismatch; - goto Exit; - } - pShbMemHeader->m_ulRefCount++; - } - - Exit: - pShbInstance = (tShbInstance *) pShbMemInst; - *pfShbNewCreated_p = fShMemNewCreated; - *ppShbInstance_p = pShbInstance; - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Release Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p) -{ - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError; - tShbError ShbError2; - - DEBUG_LVL_26_TRACE1("ShbIpcReleaseBuffer(%p)\n", pShbInstance_p); - if (pShbInstance_p == NULL) { - return (kShbOk); - } - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - // stop threads in any case, because they are bound to that specific instance - ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p); - // d.k.: Whats up with JobReady thread? - // Just wake it up, but without setting the semaphore variable - wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady); - - if (!--pShbMemHeader->m_ulRefCount) { - ShbError = kShbOk; - // delete mem table element - ShbIpcDeleteListElement(pShbMemHeader->m_iBufferId); - // delete shared mem - kfree(pShbMemInst->m_pShbMemHeader); - } else { - ShbError = kShbMemUsedByOtherProcs; - } - //delete privat mem - kfree(pShbMemInst); - return (ShbError); -} - -//--------------------------------------------------------------------------- -// Enter atomic section for Shared Buffer access -//--------------------------------------------------------------------------- - -tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError = kShbOk; - - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - DEBUG_LVL_29_TRACE0("enter atomic\n"); - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - // lock interrupts - spin_lock_irqsave(&pShbMemHeader->m_SpinlockBuffAccess, - pShbMemInst->m_ulFlagsBuffAccess); - - Exit: - return ShbError; - -} - -//--------------------------------------------------------------------------- -// Leave atomic section for Shared Buffer access -//--------------------------------------------------------------------------- - -tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError = kShbOk; - - if (pShbInstance_p == NULL) { - ShbError = kShbInvalidArg; - goto Exit; - } - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - // unlock interrupts - spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess, - pShbMemInst->m_ulFlagsBuffAccess); - - Exit: - DEBUG_LVL_29_TRACE0("Leave Atomic \n"); - return ShbError; - -} - -//--------------------------------------------------------------------------- -// Start signaling of new data (called from reading process) -//--------------------------------------------------------------------------- - -tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p, - tSigHndlrNewData pfnSignalHandlerNewData_p, - tShbPriority ShbPriority_p) -{ - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError; - - DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n"); - if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - ShbError = kShbOk; - - if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID) - || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) { - ShbError = kShbAlreadySignaling; - goto Exit; - } - DEBUG_LVL_26_TRACE2 - ("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n", - pShbInstance_p, pfnSignalHandlerNewData_p); - pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; - pShbMemHeader->m_fNewData = FALSE; - pShbMemInst->m_iThreadTermFlag = 0; - - switch (ShbPriority_p) { - case kShbPriorityLow: - pShbMemInst->m_lThreadNewDataNice = -2; - break; - - case kShbPriorityNormal: - pShbMemInst->m_lThreadNewDataNice = -9; - break; - - case kshbPriorityHigh: - pShbMemInst->m_lThreadNewDataNice = -20; - break; - - } - - //create thread for signalling new data - pShbMemInst->m_tThreadNewDataId = - kernel_thread(ShbIpcThreadSignalNewData, pShbInstance_p, - CLONE_FS | CLONE_FILES); - - Exit: - return ShbError; - -} - -//--------------------------------------------------------------------------- -// Stop signaling of new data (called from reading process) -//--------------------------------------------------------------------------- - -tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p) -{ - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError; - - DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n"); - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - ShbError = kShbOk; - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - DEBUG_LVL_26_TRACE2 - ("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n", - pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData); - if (pShbMemInst->m_pfnSigHndlrNewData != NULL) { // signal handler was set before - int iErr; - //set termination flag in mem header - pShbMemInst->m_iThreadTermFlag = 1; - - // check if thread is still running at all by sending the null-signal to this thread - /* iErr = kill_proc(pShbMemInst->m_tThreadNewDataId, 0, 1); */ - iErr = send_sig(0, pShbMemInst->m_tThreadNewDataId, 1); - if (iErr == 0) { - // wake up thread, because it is still running - wake_up_interruptible(&pShbMemHeader-> - m_WaitQueueNewData); - - //wait for termination of thread - wait_for_completion(&pShbMemInst->m_CompletionNewData); - } - - pShbMemInst->m_pfnSigHndlrNewData = NULL; - pShbMemInst->m_tThreadNewDataId = INVALID_ID; - } - - return ShbError; - -} - -//--------------------------------------------------------------------------- -// Signal new data (called from writing process) -//--------------------------------------------------------------------------- - -tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p) -{ - tShbMemHeader *pShbMemHeader; - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - pShbMemHeader = - ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p)); - //set semaphore - pShbMemHeader->m_fNewData = TRUE; - DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n"); - - wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData); - return (kShbOk); -} - -//--------------------------------------------------------------------------- -// Start signaling for job ready (called from waiting process) -//--------------------------------------------------------------------------- - -tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p, - unsigned long ulTimeOut_p, - tSigHndlrJobReady pfnSignalHandlerJobReady_p) -{ - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbError ShbError; - - if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) { - return (kShbInvalidArg); - } - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - ShbError = kShbOk; - if ((pShbMemInst->m_tThreadJobReadyId != INVALID_ID) - || (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) { - ShbError = kShbAlreadySignaling; - goto Exit; - } - pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p; - pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p; - pShbMemHeader->m_fJobReady = FALSE; - //create thread for signalling new data - pShbMemInst->m_tThreadJobReadyId = - kernel_thread(ShbIpcThreadSignalJobReady, pShbInstance_p, - CLONE_FS | CLONE_FILES); - Exit: - return ShbError; -} - -//--------------------------------------------------------------------------- -// Signal job ready (called from executing process) -//--------------------------------------------------------------------------- - -tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p) -{ - tShbMemHeader *pShbMemHeader; - - DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n"); - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - pShbMemHeader = - ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p)); - //set semaphore - pShbMemHeader->m_fJobReady = TRUE; - DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n"); - - wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady); - return (kShbOk); -} - -//--------------------------------------------------------------------------- -// Get pointer to common used share memory area -//--------------------------------------------------------------------------- - -void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p) -{ - - tShbMemHeader *pShbMemHeader; - void *pShbShMemPtr; - - pShbMemHeader = - ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p)); - if (pShbMemHeader != NULL) { - pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader); - } else { - pShbShMemPtr = NULL; - } - - return (pShbShMemPtr); - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// Get pointer to process local information structure -//--------------------------------------------------------------------------- - -/*tShbMemInst* ShbIpcGetShbMemInst ( - tShbInstance pShbInstance_p) -{ - -tShbMemInst* pShbMemInst; - - pShbMemInst = (tShbMemInst*)pShbInstance_p; - - return (pShbMemInst); - -} -*/ - -//--------------------------------------------------------------------------- -// Get pointer to shared memory header -//--------------------------------------------------------------------------- - -/*tShbMemHeader* ShbIpcGetShbMemHeader ( - tShbMemInst* pShbMemInst_p) -{ - -tShbMemHeader* pShbMemHeader; - - pShbMemHeader = pShbMemInst_p->m_pShbMemHeader; - - return (pShbMemHeader); - -} -*/ - -//--------------------------------------------------------------------------- -// Allocate a memory block from process specific mempool -//--------------------------------------------------------------------------- - -static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p) -{ - tShbError ShbError; - void *pMem; - - DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n"); - //get private mem - pMem = kmalloc(ulMemSize_p, GFP_KERNEL); - if (pMem == NULL) { - //unable to create mem - ShbError = kShbOutOfMem; - goto Exit; - } - Exit: - return (pMem); - -} - -//--------------------------------------------------------------------------- -// Thread for new data signaling -//--------------------------------------------------------------------------- - -int ShbIpcThreadSignalNewData(void *pvThreadParam_p) -{ - tShbInstance pShbInstance; - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - int iRetVal = -1; - int fCallAgain; - - daemonize("ShbND%p", pvThreadParam_p); - allow_signal(SIGTERM); - pShbInstance = (tShbMemInst *) pvThreadParam_p; - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n", pvThreadParam_p); - - set_user_nice(current, pShbMemInst->m_lThreadNewDataNice); - -// DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData); - do { - iRetVal = - wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData, - (pShbMemInst->m_iThreadTermFlag != - 0) - || (pShbMemHeader->m_fNewData != - FALSE)); - - if (iRetVal != 0) { // signal pending - break; - } - - if (pShbMemHeader->m_fNewData != FALSE) { - pShbMemHeader->m_fNewData = FALSE; - do { - fCallAgain = - pShbMemInst-> - m_pfnSigHndlrNewData(pShbInstance); - // call scheduler, which will execute any task with higher priority - schedule(); - } while (fCallAgain != FALSE); - } - } while (pShbMemInst->m_iThreadTermFlag == 0); - DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n"); - //set thread completed - complete_and_exit(&pShbMemInst->m_CompletionNewData, 0); - return 0; -} - -//--------------------------------------------------------------------------- -// Thread for new data Job Ready signaling -//--------------------------------------------------------------------------- - -int ShbIpcThreadSignalJobReady(void *pvThreadParam_p) -{ - tShbInstance pShbInstance; - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - long lTimeOut; - int iRetVal = -1; - - daemonize("ShbJR%p", pvThreadParam_p); - allow_signal(SIGTERM); - pShbInstance = (tShbMemInst *) pvThreadParam_p; - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst); - - DEBUG_LVL_29_TRACE0 - ("ShbIpcThreadSignalJobReady wait for job ready Sem\n"); - if (pShbMemInst->m_ulTimeOutJobReady != 0) { - lTimeOut = (long)pShbMemInst->m_ulTimeOutJobReady; - //wait for job ready semaphore - iRetVal = - wait_event_interruptible_timeout(pShbMemHeader-> - m_WaitQueueJobReady, - (pShbMemHeader-> - m_fJobReady != FALSE), - lTimeOut); - } else { - //wait for job ready semaphore - iRetVal = - wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady, - (pShbMemHeader->m_fJobReady != - FALSE)); - } - - if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) { - //call Handler - pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, - !pShbMemHeader->m_fJobReady); - } - - pShbMemInst->m_pfnSigHndlrJobReady = NULL; - return 0; -} - -//Build the crc table -static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]) -{ - unsigned long ulCrc, ulPoly; - int iIndexI, iIndexJ; - - ulPoly = 0xEDB88320L; - for (iIndexI = 0; iIndexI < 256; iIndexI++) { - ulCrc = iIndexI; - for (iIndexJ = 8; iIndexJ > 0; iIndexJ--) { - if (ulCrc & 1) { - ulCrc = (ulCrc >> 1) ^ ulPoly; - } else { - ulCrc >>= 1; - } - } - aulCrcTable[iIndexI] = ulCrc; - } -} - -//Calculate the crc value -static unsigned long ShbIpcCrc32GetCrc(const char *pcString, - unsigned long aulCrcTable[256]) -{ - unsigned long ulCrc; - int iIndex; - - ulCrc = 0xFFFFFFFF; - for (iIndex = 0; iIndex < strlen(pcString); iIndex++) { - ulCrc = - ((ulCrc >> 8) & 0x00FFFFFF) ^ - aulCrcTable[(ulCrc ^ pcString[iIndex]) & 0xFF]; - } - return (ulCrc ^ 0xFFFFFFFF); - -} - -static void ShbIpcAppendListElement(struct sShbMemTable *psNewMemTableElement) -{ - struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g; - psNewMemTableElement->m_psNextMemTableElement = NULL; - - if (psMemTableElementFirst_g != NULL) { /* sind Elemente vorhanden */ - while (psMemTableElement->m_psNextMemTableElement != NULL) { /* suche das letzte Element */ - psMemTableElement = - psMemTableElement->m_psNextMemTableElement; - } - psMemTableElement->m_psNextMemTableElement = psNewMemTableElement; /* Haenge das Element hinten an */ - } else { /* wenn die liste leer ist, bin ich das erste Element */ - psMemTableElementFirst_g = psNewMemTableElement; - } -} - -static int ShbIpcFindListElement(int iBufferId, - struct sShbMemTable **ppsReturnMemTableElement) -{ - struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g; - while (psMemTableElement != NULL) { - if (psMemTableElement->m_iBufferId == iBufferId) { -//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",psMemTableElement->m_pBuffer,psMemTableElement->m_iBufferId); - *ppsReturnMemTableElement = psMemTableElement; -//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",(*ppsReturnMemTableElement)->m_pBuffer,(*ppsReturnMemTableElement)->m_iBufferId); - return 0; - } - psMemTableElement = psMemTableElement->m_psNextMemTableElement; - } - return -1; -} - -static void ShbIpcDeleteListElement(int iBufferId) -{ - struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g; - struct sShbMemTable *psMemTableElementOld = psMemTableElementFirst_g; - if (psMemTableElement != NULL) { - while ((psMemTableElement != NULL) - && (psMemTableElement->m_iBufferId != iBufferId)) { - psMemTableElementOld = psMemTableElement; - psMemTableElement = - psMemTableElement->m_psNextMemTableElement; - } - if (psMemTableElement != NULL) { - if (psMemTableElement != psMemTableElementFirst_g) { - psMemTableElementOld->m_psNextMemTableElement = - psMemTableElement->m_psNextMemTableElement; - kfree(psMemTableElement); - } else { - kfree(psMemTableElement); - psMemTableElementFirst_g = NULL; - } - - } - } - -} - diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h deleted file mode 100644 index 285f096e771..00000000000 --- a/drivers/staging/epl/ShbIpc.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Declaration of platform specific part for the - shared buffer - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/06/27 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#ifndef _SHBIPC_H_ -#define _SHBIPC_H_ - -//--------------------------------------------------------------------------- -// Type definitions -//--------------------------------------------------------------------------- - -typedef int (*tSigHndlrNewData) (tShbInstance pShbInstance_p); -typedef void (*tSigHndlrJobReady) (tShbInstance pShbInstance_p, - unsigned int fTimeOut_p); - -//--------------------------------------------------------------------------- -// Prototypes -//--------------------------------------------------------------------------- - -tShbError ShbIpcInit(void); -tShbError ShbIpcExit(void); - -tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p); -tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p); - -tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p); -tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p); - -tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p, - tSigHndlrNewData - pfnSignalHandlerNewData_p, - tShbPriority ShbPriority_p); -tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p); -tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p); - -tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p, - unsigned long ulTimeOut_p, - tSigHndlrJobReady - pfnSignalHandlerJobReady_p); -tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p); - -void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p); - -#endif // #ifndef _SHBIPC_H_ diff --git a/drivers/staging/epl/ShbLinuxKernel.h b/drivers/staging/epl/ShbLinuxKernel.h deleted file mode 100644 index 812702add4f..00000000000 --- a/drivers/staging/epl/ShbLinuxKernel.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Declaration of platform specific part for the - shared buffer - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/07/20 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#ifndef _SHBLINUXKERNEL_H_ -#define _SHBLINUXKERNEL_H_ - -struct sShbMemTable { - int m_iBufferId; - void *m_pBuffer; - struct sShbMemTable *m_psNextMemTableElement; -}; - -extern struct sShbMemTable *psMemTableElementFirst_g; - -#endif // _SHBLINUXKERNEL_H_ diff --git a/drivers/staging/epl/SocketLinuxKernel.c b/drivers/staging/epl/SocketLinuxKernel.c deleted file mode 100644 index 562bc4a3e56..00000000000 --- a/drivers/staging/epl/SocketLinuxKernel.c +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Wrapper for BSD socket API for Linux kernel - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: SocketLinuxKernel.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2006/08/25 d.k.: start of implementation - -****************************************************************************/ - -#include -#include -#include "SocketLinuxKernel.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Kernel Module specific Data Structures -//--------------------------------------------------------------------------- - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -SOCKET socket(int af, int type, int protocol) -{ - int rc; - SOCKET socket; - - rc = sock_create_kern(af, type, protocol, &socket); - if (rc < 0) { - socket = NULL; - goto Exit; - } - - Exit: - return socket; -} - -int bind(SOCKET socket_p, const struct sockaddr *addr, int addrlen) -{ - int rc; - - rc = socket_p->ops->bind(socket_p, (struct sockaddr *)addr, addrlen); - - return rc; -} - -int closesocket(SOCKET socket_p) -{ - sock_release(socket_p); - - return 0; -} - -int recvfrom(SOCKET socket_p, char *buf, int len, int flags, - struct sockaddr *from, int *fromlen) -{ - int rc; - struct msghdr msg; - struct kvec iov; - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_name = from; // will be struct sock_addr - msg.msg_namelen = *fromlen; - iov.iov_len = len; - iov.iov_base = buf; - - rc = kernel_recvmsg(socket_p, &msg, &iov, 1, iov.iov_len, 0); - - return rc; -} - -int sendto(SOCKET socket_p, const char *buf, int len, int flags, - const struct sockaddr *to, int tolen) -{ - int rc; - struct msghdr msg; - struct kvec iov; - - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_name = (struct sockaddr *)to; // will be struct sock_addr - msg.msg_namelen = tolen; - msg.msg_flags = 0; - iov.iov_len = len; - iov.iov_base = (char *)buf; - - rc = kernel_sendmsg(socket_p, &msg, &iov, 1, len); - - return rc; -} - -// EOF diff --git a/drivers/staging/epl/SocketLinuxKernel.h b/drivers/staging/epl/SocketLinuxKernel.h deleted file mode 100644 index 6e1d6198960..00000000000 --- a/drivers/staging/epl/SocketLinuxKernel.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for BSD socket API for Linux kernel - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: SocketLinuxKernel.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/08/25 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _SOCKETLINUXKERNEL_H_ -#define _SOCKETLINUXKERNEL_H_ - -#include -#include - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define INVALID_SOCKET 0 - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct socket *SOCKET; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -int bind(SOCKET s, const struct sockaddr *addr, int addrlen); - -int closesocket(SOCKET s); - -int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, - int *fromlen); - -int sendto(SOCKET s, const char *buf, int len, int flags, - const struct sockaddr *to, int tolen); - -SOCKET socket(int af, int type, int protocol); - -#endif // #ifndef _SOCKETLINUXKERNEL_H_ diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c deleted file mode 100644 index d6897de4f14..00000000000 --- a/drivers/staging/epl/TimerHighReskX86.c +++ /dev/null @@ -1,510 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: target specific implementation of - high resolution timer module for X86 under Linux - The Linux kernel has to be compiled with high resolution - timers enabled. This is done by configuring the kernel - with CONFIG_HIGH_RES_TIMERS enabled. - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: TimerHighReskX86.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:38:01 $ - - $State: Exp $ - - Build Environment: - GNU - - ------------------------------------------------------------------------- - - Revision History: - -****************************************************************************/ - -#include "EplInc.h" -#include "kernel/EplTimerHighResk.h" -#include "Benchmark.h" - -//#include -#include -#include -#include - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#define TIMER_COUNT 2 /* max 15 timers selectable */ -#define TIMER_MIN_VAL_SINGLE 5000 /* min 5us */ -#define TIMER_MIN_VAL_CYCLE 100000 /* min 100us */ - -#define PROVE_OVERRUN - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif -#define HRT_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \ - TGT_DBG_POST_TRACE_VALUE((0xE << 28) | (Event_p << 24) \ - | (uiNodeId_p << 16) | wErrorCode_p) - -#define TIMERHDL_MASK 0x0FFFFFFF -#define TIMERHDL_SHIFT 28 -#define HDL_TO_IDX(Hdl) ((Hdl >> TIMERHDL_SHIFT) - 1) -#define HDL_INIT(Idx) ((Idx + 1) << TIMERHDL_SHIFT) -#define HDL_INC(Hdl) (((Hdl + 1) & TIMERHDL_MASK) \ - | (Hdl & ~TIMERHDL_MASK)) - -//--------------------------------------------------------------------------- -// modul global types -//--------------------------------------------------------------------------- - -typedef struct { - tEplTimerEventArg m_EventArg; - tEplTimerkCallback m_pfnCallback; - struct hrtimer m_Timer; - BOOL m_fContinuously; - unsigned long long m_ullPeriod; - -} tEplTimerHighReskTimerInfo; - -typedef struct { - tEplTimerHighReskTimerInfo m_aTimerInfo[TIMER_COUNT]; - -} tEplTimerHighReskInstance; - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -static tEplTimerHighReskInstance EplTimerHighReskInstance_l; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskInit() -// -// Description: initializes the high resolution timer module. -// -// Parameters: void -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimerHighReskInit(void) -{ - tEplKernel Ret; - - Ret = EplTimerHighReskAddInstance(); - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskAddInstance() -// -// Description: initializes the high resolution timer module. -// -// Parameters: void -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimerHighReskAddInstance(void) -{ - tEplKernel Ret; - unsigned int uiIndex; - - Ret = kEplSuccessful; - - EPL_MEMSET(&EplTimerHighReskInstance_l, 0, - sizeof(EplTimerHighReskInstance_l)); - - /* - * Initialize hrtimer structures for all usable timers. - */ - for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) { - tEplTimerHighReskTimerInfo *pTimerInfo; - struct hrtimer *pTimer; - - pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex]; - pTimer = &pTimerInfo->m_Timer; - hrtimer_init(pTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - - pTimer->function = EplTimerHighReskCallback; - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskDelInstance() -// -// Description: shuts down the high resolution timer module. -// -// Parameters: void -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimerHighReskDelInstance(void) -{ - tEplTimerHighReskTimerInfo *pTimerInfo; - tEplKernel Ret; - unsigned int uiIndex; - - Ret = kEplSuccessful; - - for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) { - pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0]; - pTimerInfo->m_pfnCallback = NULL; - pTimerInfo->m_EventArg.m_TimerHdl = 0; - /* - * In this case we can not just try to cancel the timer. - * We actually have to wait until its callback function - * has returned. - */ - hrtimer_cancel(&pTimerInfo->m_Timer); - } - - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskModifyTimerNs() -// -// Description: modifies the timeout of the timer with the specified handle. -// If the handle the pointer points to is zero, the timer must -// be created first. -// If it is not possible to stop the old timer, -// this function always assures that the old timer does not -// trigger the callback function with the same handle as the new -// timer. That means the callback function must check the passed -// handle with the one returned by this function. If these are -// unequal, the call can be discarded. -// -// Parameters: pTimerHdl_p = pointer to timer handle -// ullTimeNs_p = relative timeout in [ns] -// pfnCallback_p = callback function, which is called mutual -// exclusive with the Edrv callback functions -// (Rx and Tx). -// ulArgument_p = user-specific argument -// fContinuously_p = if TRUE, callback function will be called -// continuously; -// otherwise, it is a oneshot timer. -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p, - unsigned long long ullTimeNs_p, - tEplTimerkCallback pfnCallback_p, - unsigned long ulArgument_p, - BOOL fContinuously_p) -{ - tEplKernel Ret; - unsigned int uiIndex; - tEplTimerHighReskTimerInfo *pTimerInfo; - ktime_t RelTime; - - Ret = kEplSuccessful; - - // check pointer to handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - if (*pTimerHdl_p == 0) { // no timer created yet - - // search free timer info structure - pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0]; - for (uiIndex = 0; uiIndex < TIMER_COUNT; - uiIndex++, pTimerInfo++) { - if (pTimerInfo->m_EventArg.m_TimerHdl == 0) { // free structure found - break; - } - } - if (uiIndex >= TIMER_COUNT) { // no free structure found - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - - pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex); - } else { - uiIndex = HDL_TO_IDX(*pTimerHdl_p); - if (uiIndex >= TIMER_COUNT) { // invalid handle - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex]; - } - - /* - * increment timer handle - * (if timer expires right after this statement, the user - * would detect an unknown timer handle and discard it) - */ - pTimerInfo->m_EventArg.m_TimerHdl = - HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl); - *pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl; - - // reject too small time values - if ((fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_CYCLE)) - || (!fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_SINGLE))) { - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - - pTimerInfo->m_EventArg.m_ulArg = ulArgument_p; - pTimerInfo->m_pfnCallback = pfnCallback_p; - pTimerInfo->m_fContinuously = fContinuously_p; - pTimerInfo->m_ullPeriod = ullTimeNs_p; - - /* - * HRTIMER_MODE_REL does not influence general handling of this timer. - * It only sets relative mode for this start operation. - * -> Expire time is calculated by: Now + RelTime - * hrtimer_start also skips pending timer events. - * The state HRTIMER_STATE_CALLBACK is ignored. - * We have to cope with that in our callback function. - */ - RelTime = ktime_add_ns(ktime_set(0, 0), ullTimeNs_p); - hrtimer_start(&pTimerInfo->m_Timer, RelTime, HRTIMER_MODE_REL); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskDeleteTimer() -// -// Description: deletes the timer with the specified handle. Afterward the -// handle is set to zero. -// -// Parameters: pTimerHdl_p = pointer to timer handle -// -// Return: tEplKernel = error code -// -// State: not tested -// -//--------------------------------------------------------------------------- - -tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiIndex; - tEplTimerHighReskTimerInfo *pTimerInfo; - - // check pointer to handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - if (*pTimerHdl_p == 0) { // no timer created yet - goto Exit; - } else { - uiIndex = HDL_TO_IDX(*pTimerHdl_p); - if (uiIndex >= TIMER_COUNT) { // invalid handle - Ret = kEplTimerInvalidHandle; - goto Exit; - } - pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex]; - if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p) { // invalid handle - goto Exit; - } - } - - *pTimerHdl_p = 0; - pTimerInfo->m_EventArg.m_TimerHdl = 0; - pTimerInfo->m_pfnCallback = NULL; - - /* - * Three return cases of hrtimer_try_to_cancel have to be tracked: - * 1 - timer has been removed - * 0 - timer was not active - * We need not do anything. hrtimer timers just consist of - * a hrtimer struct, which we might enqueue in the hrtimers - * event list by calling hrtimer_start(). - * If a timer is not enqueued, it is not present in hrtimers. - * -1 - callback function is running - * In this case we have to ensure that the timer is not - * continuously restarted. This has been done by clearing - * its handle. - */ - hrtimer_try_to_cancel(&pTimerInfo->m_Timer); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimerHighReskCallback() -// -// Description: Callback function commonly used for all timers. -// -// Parameters: pTimer_p = pointer to hrtimer -// -// Return: -// -// State: not tested -// -//--------------------------------------------------------------------------- - -enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p) -{ - unsigned int uiIndex; - tEplTimerHighReskTimerInfo *pTimerInfo; - tEplTimerHdl OrgTimerHdl; - enum hrtimer_restart Ret; - - BENCHMARK_MOD_24_SET(4); - - Ret = HRTIMER_NORESTART; - pTimerInfo = - container_of(pTimer_p, tEplTimerHighReskTimerInfo, m_Timer); - uiIndex = HDL_TO_IDX(pTimerInfo->m_EventArg.m_TimerHdl); - if (uiIndex >= TIMER_COUNT) { // invalid handle - goto Exit; - } - - /* - * We store the timer handle before calling the callback function - * as the timer can be modified inside it. - */ - OrgTimerHdl = pTimerInfo->m_EventArg.m_TimerHdl; - - if (pTimerInfo->m_pfnCallback != NULL) { - pTimerInfo->m_pfnCallback(&pTimerInfo->m_EventArg); - } - - if (pTimerInfo->m_fContinuously) { - ktime_t Interval; -#ifdef PROVE_OVERRUN - ktime_t Now; - unsigned long Overruns; -#endif - - if (OrgTimerHdl != pTimerInfo->m_EventArg.m_TimerHdl) { - /* modified timer has already been restarted */ - goto Exit; - } -#ifdef PROVE_OVERRUN - Now = ktime_get(); - Interval = - ktime_add_ns(ktime_set(0, 0), pTimerInfo->m_ullPeriod); - Overruns = hrtimer_forward(pTimer_p, Now, Interval); - if (Overruns > 1) { - printk - ("EplTimerHighResk: Continuous timer (handle 0x%lX) had to skip %lu interval(s)!\n", - pTimerInfo->m_EventArg.m_TimerHdl, Overruns - 1); - } -#else - pTimer_p->expires = ktime_add_ns(pTimer_p->expires, - pTimerInfo->m_ullPeriod); -#endif - - Ret = HRTIMER_RESTART; - } - - Exit: - BENCHMARK_MOD_24_RESET(4); - return Ret; -} diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c deleted file mode 100644 index 7b7cce1b36e..00000000000 --- a/drivers/staging/epl/VirtualEthernetLinux.c +++ /dev/null @@ -1,348 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Virtual Ethernet Driver for Linux - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: VirtualEthernetLinux.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/11/20 17:06:51 $ - - $State: Exp $ - - Build Environment: - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 -ar: start of the implementation, version 1.00 - - 2006/09/18 d.k.: integration into EPL DLLk module - - ToDo: - - void netif_carrier_off(struct net_device *dev); - void netif_carrier_on(struct net_device *dev); - -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for struct sk_buff */ - -#include "kernel/VirtualEthernet.h" -#include "kernel/EplDllkCal.h" -#include "kernel/EplDllk.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_VETH_TX_TIMEOUT -//#define EPL_VETH_TX_TIMEOUT (2*HZ) -#define EPL_VETH_TX_TIMEOUT 0 // d.k.: we use no timeout -#endif - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static struct net_device *pVEthNetDevice_g = NULL; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static int VEthOpen(struct net_device *pNetDevice_p); -static int VEthClose(struct net_device *pNetDevice_p); -static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p); -static struct net_device_stats *VEthGetStats(struct net_device *pNetDevice_p); -static void VEthTimeout(struct net_device *pNetDevice_p); -static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- - -static int VEthOpen(struct net_device *pNetDevice_p) -{ - tEplKernel Ret = kEplSuccessful; - - //open the device -// struct net_device_stats* pStats = netdev_priv(pNetDevice_p); - - //start the interface queue for the network subsystem - netif_start_queue(pNetDevice_p); - - // register callback function in DLL - Ret = EplDllkRegAsyncHandler(VEthRecvFrame); - - EPL_DBGLVL_VETH_TRACE1 - ("VEthOpen: EplDllkRegAsyncHandler returned 0x%02X\n", Ret); - - return 0; -} - -static int VEthClose(struct net_device *pNetDevice_p) -{ - tEplKernel Ret = kEplSuccessful; - - EPL_DBGLVL_VETH_TRACE0("VEthClose\n"); - - Ret = EplDllkDeregAsyncHandler(VEthRecvFrame); - - //stop the interface queue for the network subsystem - netif_stop_queue(pNetDevice_p); - return 0; -} - -static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p) -{ - tEplKernel Ret = kEplSuccessful; - tEplFrameInfo FrameInfo; - - //transmit function - struct net_device_stats *pStats = netdev_priv(pNetDevice_p); - - //save timestemp - pNetDevice_p->trans_start = jiffies; - - FrameInfo.m_pFrame = (tEplFrame *) pSkb_p->data; - FrameInfo.m_uiFrameSize = pSkb_p->len; - - //call send fkt on DLL - Ret = EplDllkCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric); - if (Ret != kEplSuccessful) { - EPL_DBGLVL_VETH_TRACE1 - ("VEthXmit: EplDllkCalAsyncSend returned 0x%02X\n", Ret); - netif_stop_queue(pNetDevice_p); - goto Exit; - } else { - EPL_DBGLVL_VETH_TRACE0("VEthXmit: frame passed to DLL\n"); - dev_kfree_skb(pSkb_p); - - //set stats for the device - pStats->tx_packets++; - pStats->tx_bytes += FrameInfo.m_uiFrameSize; - } - - Exit: - return NETDEV_TX_OK; - -} - -static struct net_device_stats *VEthGetStats(struct net_device *pNetDevice_p) -{ - EPL_DBGLVL_VETH_TRACE0("VEthGetStats\n"); - - return netdev_priv(pNetDevice_p); -} - -static void VEthTimeout(struct net_device *pNetDevice_p) -{ - EPL_DBGLVL_VETH_TRACE0("VEthTimeout(\n"); - - // $$$ d.k.: move to extra function, which is called by DLL when new space is available in TxFifo - if (netif_queue_stopped(pNetDevice_p)) { - netif_wake_queue(pNetDevice_p); - } -} - -static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p) -{ - tEplKernel Ret = kEplSuccessful; - struct net_device *pNetDevice = pVEthNetDevice_g; - struct net_device_stats *pStats = netdev_priv(pNetDevice); - struct sk_buff *pSkb; - - EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: FrameSize=%u\n", - pFrameInfo_p->m_uiFrameSize); - - pSkb = dev_alloc_skb(pFrameInfo_p->m_uiFrameSize + 2); - if (pSkb == NULL) { - pStats->rx_dropped++; - goto Exit; - } - pSkb->dev = pNetDevice; - - skb_reserve(pSkb, 2); - - memcpy((void *)skb_put(pSkb, pFrameInfo_p->m_uiFrameSize), - pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize); - - pSkb->protocol = eth_type_trans(pSkb, pNetDevice); - pSkb->ip_summed = CHECKSUM_UNNECESSARY; - - // call netif_rx with skb - netif_rx(pSkb); - - EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: SrcMAC=0x%llx\n", - AmiGetQword48FromBe(pFrameInfo_p->m_pFrame-> - m_be_abSrcMac)); - - // update receive statistics - pStats->rx_packets++; - pStats->rx_bytes += pFrameInfo_p->m_uiFrameSize; - - Exit: - return Ret; -} - -static const struct net_device_ops epl_netdev_ops = { - .ndo_open = VEthOpen, - .ndo_stop = VEthClose, - .ndo_get_stats = VEthGetStats, - .ndo_start_xmit = VEthXmit, - .ndo_tx_timeout = VEthTimeout, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) -{ - tEplKernel Ret = kEplSuccessful; - - // allocate net device structure with priv pointing to stats structure - pVEthNetDevice_g = - alloc_netdev(sizeof(struct net_device_stats), EPL_VETH_NAME, - ether_setup); -// pVEthNetDevice_g = alloc_etherdev(sizeof (struct net_device_stats)); - - if (pVEthNetDevice_g == NULL) { - Ret = kEplNoResource; - goto Exit; - } - - pVEthNetDevice_g->netdev_ops = &epl_netdev_ops; - pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT; - pVEthNetDevice_g->destructor = free_netdev; - - // copy own MAC address to net device structure - memcpy(pVEthNetDevice_g->dev_addr, pInitParam_p->m_be_abSrcMac, 6); - - //register VEth to the network subsystem - if (register_netdev(pVEthNetDevice_g)) { - EPL_DBGLVL_VETH_TRACE0 - ("VEthAddInstance: Could not register VEth...\n"); - } else { - EPL_DBGLVL_VETH_TRACE0 - ("VEthAddInstance: Register VEth successfull...\n"); - } - - Exit: - return Ret; -} - -tEplKernel VEthDelInstance(void) -{ - tEplKernel Ret = kEplSuccessful; - - if (pVEthNetDevice_g != NULL) { - //unregister VEth from the network subsystem - unregister_netdev(pVEthNetDevice_g); - // destructor was set to free_netdev, - // so we do not need to call free_netdev here - pVEthNetDevice_g = NULL; - } - - return Ret; -} - -#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c deleted file mode 100644 index d40ad918d3b..00000000000 --- a/drivers/staging/epl/amix86.c +++ /dev/null @@ -1,861 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Abstract Memory Interface for x86 compatible - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: amix86.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - ... - - ------------------------------------------------------------------------- - - Revision History: - - r.s.: first implemetation - - 2006-06-13 d.k.: duplicate functions for little endian and big endian - -****************************************************************************/ - -//#include "global.h" -//#include "EplAmi.h" -#include "EplInc.h" - -//--------------------------------------------------------------------------- -// typedef -//--------------------------------------------------------------------------- - -typedef struct { - u16 m_wWord; - -} twStruct; - -typedef struct { - u32 m_dwDword; - -} tdwStruct; - -typedef struct { - u64 m_qwQword; - -} tqwStruct; - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: AmiSetXXXToBe() -// -// Description: writes the specified value to the absolute address in -// big endian -// -// Parameters: pAddr_p = absolute address -// xXXXVal_p = value -// -// Returns: (none) -// -// State: -// -//--------------------------------------------------------------------------- - -//------------< write u8 in big endian >-------------------------- -/* -void AmiSetByteToBe (void *pAddr_p, u8 bByteVal_p) -{ - - *(u8 *)pAddr_p = bByteVal_p; - -} -*/ - -//------------< write u16 in big endian >-------------------------- - -void AmiSetWordToBe(void * pAddr_p, u16 wWordVal_p) -{ - twStruct *pwStruct; - twStruct wValue; - - wValue.m_wWord = (u16) ((wWordVal_p & 0x00FF) << 8); //LSB to MSB - wValue.m_wWord |= (u16) ((wWordVal_p & 0xFF00) >> 8); //MSB to LSB - - pwStruct = (twStruct *) pAddr_p; - pwStruct->m_wWord = wValue.m_wWord; - -} - -//------------< write u32 in big endian >------------------------- - -void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p) -{ - tdwStruct *pdwStruct; - tdwStruct dwValue; - - dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF) << 24); //LSB to MSB - dwValue.m_dwDword |= ((dwDwordVal_p & 0x0000FF00) << 8); - dwValue.m_dwDword |= ((dwDwordVal_p & 0x00FF0000) >> 8); - dwValue.m_dwDword |= ((dwDwordVal_p & 0xFF000000) >> 24); //MSB to LSB - - pdwStruct = (tdwStruct *) pAddr_p; - pdwStruct->m_dwDword = dwValue.m_dwDword; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetXXXToLe() -// -// Description: writes the specified value to the absolute address in -// little endian -// -// Parameters: pAddr_p = absolute address -// xXXXVal_p = value -// -// Returns: (none) -// -// State: -// -//--------------------------------------------------------------------------- - -//------------< write u8 in little endian >-------------------------- -/* -void AmiSetByteToLe (void *pAddr_p, u8 bByteVal_p) -{ - - *(u8 *)pAddr_p = bByteVal_p; - -} -*/ - -//------------< write u16 in little endian >-------------------------- - -void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p) -{ - twStruct *pwStruct; - - pwStruct = (twStruct *) pAddr_p; - pwStruct->m_wWord = wWordVal_p; - -} - -//------------< write u32 in little endian >------------------------- - -void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p) -{ - tdwStruct *pdwStruct; - - pdwStruct = (tdwStruct *) pAddr_p; - pdwStruct->m_dwDword = dwDwordVal_p; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetXXXFromBe() -// -// Description: reads the specified value from the absolute address in -// big endian -// -// Parameters: pAddr_p = absolute address -// -// Returns: XXX = value -// -// State: -// -//--------------------------------------------------------------------------- - -//------------< read u8 in big endian >--------------------------- -/* -u8 AmiGetByteFromBe (void *pAddr_p) -{ - - return ( *(u8 *)pAddr_p ); - -} -*/ - -//------------< read u16 in big endian >--------------------------- - -u16 AmiGetWordFromBe(void *pAddr_p) -{ - twStruct *pwStruct; - twStruct wValue; - - pwStruct = (twStruct *) pAddr_p; - - wValue.m_wWord = (u16) ((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB - wValue.m_wWord |= (u16) ((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB - - return (wValue.m_wWord); - -} - -//------------< read u32 in big endian >-------------------------- - -u32 AmiGetDwordFromBe(void *pAddr_p) -{ - tdwStruct *pdwStruct; - tdwStruct dwValue; - - pdwStruct = (tdwStruct *) pAddr_p; - - dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF) << 24); //LSB to MSB - dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x0000FF00) << 8); - dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x00FF0000) >> 8); - dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0xFF000000) >> 24); //MSB to LSB - - return (dwValue.m_dwDword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetXXXFromLe() -// -// Description: reads the specified value from the absolute address in -// little endian -// -// Parameters: pAddr_p = absolute address -// -// Returns: XXX = value -// -// State: -// -//--------------------------------------------------------------------------- - -//------------< read u8 in little endian >--------------------------- -/* -u8 AmiGetByteFromLe (void *pAddr_p) -{ - - return ( *(u8 *)pAddr_p ); - -} -*/ - -//------------< read u16 in little endian >--------------------------- - -u16 AmiGetWordFromLe(void *pAddr_p) -{ - twStruct *pwStruct; - - pwStruct = (twStruct *) pAddr_p; - return (pwStruct->m_wWord); -} - -//------------< read u32 in little endian >-------------------------- - -u32 AmiGetDwordFromLe(void *pAddr_p) -{ - tdwStruct *pdwStruct; - - pdwStruct = (tdwStruct *) pAddr_p; - return (pdwStruct->m_dwDword); -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetDword24ToBe() -// -// Description: sets a 24 bit value to a buffer in big endian -// -// Parameters: pAddr_p = pointer to destination buffer -// dwDwordVal_p = value to set -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p) -{ - ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[2]; - ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1]; - ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[0]; -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetDword24ToLe() -// -// Description: sets a 24 bit value to a buffer in little endian -// -// Parameters: pAddr_p = pointer to destination buffer -// dwDwordVal_p = value to set -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p) -{ - ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[0]; - ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1]; - ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[2]; -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetDword24FromBe() -// -// Description: reads a 24 bit value from a buffer in big endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u32 = read value -// -// State: not tested -// -//--------------------------------------------------------------------------- -u32 AmiGetDword24FromBe(void *pAddr_p) -{ - tdwStruct dwStruct; - - dwStruct.m_dwDword = AmiGetDwordFromBe(pAddr_p); - dwStruct.m_dwDword >>= 8; - - return (dwStruct.m_dwDword); -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetDword24FromLe() -// -// Description: reads a 24 bit value from a buffer in little endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u32 = read value -// -// State: not tested -// -//--------------------------------------------------------------------------- -u32 AmiGetDword24FromLe(void *pAddr_p) -{ - tdwStruct dwStruct; - - dwStruct.m_dwDword = AmiGetDwordFromLe(pAddr_p); - dwStruct.m_dwDword &= 0x00FFFFFF; - - return (dwStruct.m_dwDword); -} - -//#ifdef USE_VAR64 - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword64ToBe() -// -// Description: sets a 64 bit value to a buffer in big endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- -void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p) -{ - ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[7]; - ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[6]; - ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[5]; - ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[4]; - ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[3]; - ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[2]; - ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[1]; - ((u8 *) pAddr_p)[7] = ((u8 *) & qwQwordVal_p)[0]; -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword64ToLe() -// -// Description: sets a 64 bit value to a buffer in little endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- -void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p) -{ - u64 *pqwDst; - - pqwDst = (u64 *) pAddr_p; - *pqwDst = qwQwordVal_p; -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword64FromBe() -// -// Description: reads a 64 bit value from a buffer in big endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- -u64 AmiGetQword64FromBe(void *pAddr_p) -{ - tqwStruct qwStruct; - - ((u8 *) & qwStruct.m_qwQword)[0] = ((u8 *) pAddr_p)[7]; - ((u8 *) & qwStruct.m_qwQword)[1] = ((u8 *) pAddr_p)[6]; - ((u8 *) & qwStruct.m_qwQword)[2] = ((u8 *) pAddr_p)[5]; - ((u8 *) & qwStruct.m_qwQword)[3] = ((u8 *) pAddr_p)[4]; - ((u8 *) & qwStruct.m_qwQword)[4] = ((u8 *) pAddr_p)[3]; - ((u8 *) & qwStruct.m_qwQword)[5] = ((u8 *) pAddr_p)[2]; - ((u8 *) & qwStruct.m_qwQword)[6] = ((u8 *) pAddr_p)[1]; - ((u8 *) & qwStruct.m_qwQword)[7] = ((u8 *) pAddr_p)[0]; - - return (qwStruct.m_qwQword); -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword64FromLe() -// -// Description: reads a 64 bit value from a buffer in little endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- -u64 AmiGetQword64FromLe(void *pAddr_p) -{ - tqwStruct *pqwStruct; - tqwStruct qwStruct; - - pqwStruct = (tqwStruct *) pAddr_p; - qwStruct.m_qwQword = pqwStruct->m_qwQword; - - return (qwStruct.m_qwQword); -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword40ToBe() -// -// Description: sets a 40 bit value to a buffer in big endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[4]; - ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[3]; - ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[2]; - ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[1]; - ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[0]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword40ToLe() -// -// Description: sets a 40 bit value to a buffer in little endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0]; - ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[4]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword40FromBe() -// -// Description: reads a 40 bit value from a buffer in big endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword40FromBe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p); - qwStruct.m_qwQword >>= 24; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword40FromLe() -// -// Description: reads a 40 bit value from a buffer in little endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword40FromLe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p); - qwStruct.m_qwQword &= 0x000000FFFFFFFFFFLL; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword48ToBe() -// -// Description: sets a 48 bit value to a buffer in big endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[5]; - ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[4]; - ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[3]; - ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[2]; - ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[1]; - ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[0]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword48ToLe() -// -// Description: sets a 48 bit value to a buffer in little endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0]; - ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword48FromBe() -// -// Description: reads a 48 bit value from a buffer in big endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword48FromBe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p); - qwStruct.m_qwQword >>= 16; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword48FromLe() -// -// Description: reads a 48 bit value from a buffer in little endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword48FromLe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p); - qwStruct.m_qwQword &= 0x0000FFFFFFFFFFFFLL; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword56ToBe() -// -// Description: sets a 56 bit value to a buffer in big endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[6]; - ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[5]; - ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[4]; - ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[3]; - ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[2]; - ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[1]; - ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[0]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetQword56ToLe() -// -// Description: sets a 56 bit value to a buffer in little endian -// -// Parameters: pAddr_p = pointer to destination buffer -// qwQwordVal_p = quadruple word value -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p) -{ - - ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0]; - ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2]; - ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[6]; - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword56FromBe() -// -// Description: reads a 56 bit value from a buffer in big endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword56FromBe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p); - qwStruct.m_qwQword >>= 8; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetQword56FromLe() -// -// Description: reads a 56 bit value from a buffer in little endian -// -// Parameters: pAddr_p = pointer to source buffer -// -// Return: u64 -// -// State: not tested -// -//--------------------------------------------------------------------------- - -u64 AmiGetQword56FromLe(void *pAddr_p) -{ - - tqwStruct qwStruct; - - qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p); - qwStruct.m_qwQword &= 0x00FFFFFFFFFFFFFFLL; - - return (qwStruct.m_qwQword); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiSetTimeOfDay() -// -// Description: sets a TIME_OF_DAY (CANopen) value to a buffer -// -// Parameters: pAddr_p = pointer to destination buffer -// pTimeOfDay_p = pointer to struct TIME_OF_DAY -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p) -{ - - AmiSetDwordToLe(((u8 *) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF); - AmiSetWordToLe(((u8 *) pAddr_p) + 4, pTimeOfDay_p->m_wDays); - -} - -//--------------------------------------------------------------------------- -// -// Function: AmiGetTimeOfDay() -// -// Description: reads a TIME_OF_DAY (CANopen) value from a buffer -// -// Parameters: pAddr_p = pointer to source buffer -// pTimeOfDay_p = pointer to struct TIME_OF_DAY -// -// Return: void -// -// State: not tested -// -//--------------------------------------------------------------------------- - -void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p) -{ - - pTimeOfDay_p->m_dwMs = AmiGetDwordFromLe(((u8 *) pAddr_p)) & 0x0FFFFFFF; - pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((u8 *) pAddr_p) + 4); - -} - -// EOF - -// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler -// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder). diff --git a/drivers/staging/epl/demo_main.c b/drivers/staging/epl/demo_main.c deleted file mode 100644 index 7ad10fc2b1d..00000000000 --- a/drivers/staging/epl/demo_main.c +++ /dev/null @@ -1,947 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: demoapplication for EPL MN (with SDO over UDP) - under Linux on X86 with RTL8139 Ethernet controller - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: demo_main.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.10 $ $Date: 2008/11/19 18:11:43 $ - - $State: Exp $ - - Build Environment: - GCC - - ------------------------------------------------------------------------- - - Revision History: - - 2006/09/01 d.k.: start of implementation - -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Epl.h" -#include "proc_fs.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -// Metainformation -MODULE_LICENSE("Dual BSD/GPL"); -#ifdef MODULE_AUTHOR -MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com"); -MODULE_DESCRIPTION("EPL MN demo"); -#endif - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#endif - -#define NODEID 0xF0 //=> MN -#define CYCLE_LEN 5000 // [us] -#define IP_ADDR 0xc0a86401 // 192.168.100.1 -#define SUBNET_MASK 0xFFFFFF00 // 255.255.255.0 -#define HOSTNAME "SYS TEC electronic EPL Stack " -#define IF_ETH EPL_VETH_NAME - -// LIGHT EFFECT -#define DEFAULT_MAX_CYCLE_COUNT 20 // 6 is very fast -#define APP_DEFAULT_MODE 0x01 -#define APP_LED_COUNT 5 // number of LEDs in one row -#define APP_LED_MASK ((1 << APP_LED_COUNT) - 1) -#define APP_DOUBLE_LED_MASK ((1 << (APP_LED_COUNT * 2)) - 1) -#define APP_MODE_COUNT 5 -#define APP_MODE_MASK ((1 << APP_MODE_COUNT) - 1) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -static u8 bVarIn1_l; -static u8 bVarOut1_l; -static u8 bVarOut1Old_l; -static u8 bModeSelect_l; // state of the pushbuttons to select the mode -static u8 bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed -static u8 bSpeedSelectOld_l; // old state of the pushbuttons -static u32 dwLeds_l; // current state of all LEDs -static u8 bLedsRow1_l; // current state of the LEDs in row 1 -static u8 bLedsRow2_l; // current state of the LEDs in row 2 -static u8 abSelect_l[3]; // pushbuttons from CNs - -static u32 dwMode_l; // current mode -static int iCurCycleCount_l; // current cycle count -static int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step) -static int iToggle; // indicates the light movement direction - -//static u8 abDomain_l[3000]; - -static wait_queue_head_t WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff -static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE); - -static u32 dw_le_CycleLen_g; - -static uint uiNodeId_g = EPL_C_ADR_INVALID; -module_param_named(nodeid, uiNodeId_g, uint, 0); - -static uint uiCycleLen_g = CYCLE_LEN; -module_param_named(cyclelen, uiCycleLen_g, uint, 0); - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -// This function is the entry point for your object dictionary. It is defined -// in OBJDICT.C by define EPL_OBD_INIT_RAM_NAME. Use this function name to define -// this function prototype here. If you want to use more than one Epl -// instances then the function name of each object dictionary has to differ. - -tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p); - -tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p); - -tEplKernel AppCbSync(void); - - -//--------------------------------------------------------------------------- -// Kernel Module specific Data Structures -//--------------------------------------------------------------------------- - -//module_init(EplLinInit); -//module_exit(EplLinExit); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: -// -// Description: -// -// -// -// Parameters: -// -// -// Returns: -// -// -// State: -// -//--------------------------------------------------------------------------- -#if 0 -static int __init EplLinInit(void) -{ - tEplKernel EplRet; - int iRet; - static tEplApiInitParam EplApiInitParam = { 0 }; - char *sHostname = HOSTNAME; - char *argv[4], *envp[3]; - char sBuffer[16]; - unsigned int uiVarEntries; - tEplObdSize ObdSize; - - atomic_set(&AtomicShutdown_g, TRUE); - - // get node ID from insmod command line - EplApiInitParam.m_uiNodeId = uiNodeId_g; - - if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set - // set default node ID - EplApiInitParam.m_uiNodeId = NODEID; - } - - uiNodeId_g = EplApiInitParam.m_uiNodeId; - - // calculate IP address - EplApiInitParam.m_dwIpAddress = - (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; - - EplApiInitParam.m_fAsyncOnly = FALSE; - - EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam); - EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, - sizeof(EplApiInitParam.m_abMacAddress)); -// EplApiInitParam.m_abMacAddress[5] = (u8) EplApiInitParam.m_uiNodeId; - EplApiInitParam.m_dwFeatureFlags = -1; - EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection - EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const - EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const - EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes - EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes) - EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) - EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes - EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection - EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size - EplApiInitParam.m_uiPrescaler = 2; // required for sync - EplApiInitParam.m_dwLossOfFrameTolerance = 500000; - EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; - EplApiInitParam.m_dwWaitSocPreq = 150000; - EplApiInitParam.m_dwDeviceType = -1; // NMT_DeviceType_U32 - EplApiInitParam.m_dwVendorId = -1; // NMT_IdentityObject_REC.VendorId_U32 - EplApiInitParam.m_dwProductCode = -1; // NMT_IdentityObject_REC.ProductCode_U32 - EplApiInitParam.m_dwRevisionNumber = -1; // NMT_IdentityObject_REC.RevisionNo_U32 - EplApiInitParam.m_dwSerialNumber = -1; // NMT_IdentityObject_REC.SerialNo_U32 - EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; - EplApiInitParam.m_dwDefaultGateway = 0; - EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, - sizeof(EplApiInitParam.m_sHostname)); - - // currently unset parameters left at default value 0 - //EplApiInitParam.m_qwVendorSpecificExt1; - //EplApiInitParam.m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32 - //EplApiInitParam.m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32 - //EplApiInitParam.m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device - //EplApiInitParam.m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device - //EplApiInitParam.m_abVendorSpecificExt2[48]; - - // set callback functions - EplApiInitParam.m_pfnCbEvent = AppCbEvent; - EplApiInitParam.m_pfnCbSync = AppCbSync; - - printk - ("\n\n Hello, I'm a simple POWERLINK node running as %s!\n (build: %s / %s)\n\n", - (uiNodeId_g == - EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"), - __DATE__, __TIME__); - - // initialize the Linux a wait queue for shutdown of this module - init_waitqueue_head(&WaitQueueShutdown_g); - - // initialize the procfs device - EplRet = EplLinProcInit(); - if (EplRet != kEplSuccessful) { - goto Exit; - } - // initialize POWERLINK stack - EplRet = EplApiInitialize(&EplApiInitParam); - if (EplRet != kEplSuccessful) { - goto Exit; - } - // link process variables used by CN to object dictionary - ObdSize = sizeof(bVarIn1_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x6000, &bVarIn1_l, &uiVarEntries, &ObdSize, 0x01); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - ObdSize = sizeof(bVarOut1_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x6200, &bVarOut1_l, &uiVarEntries, &ObdSize, - 0x01); - if (EplRet != kEplSuccessful) { - goto Exit; - } - // link process variables used by MN to object dictionary -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - ObdSize = sizeof(bLedsRow1_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x2000, &bLedsRow1_l, &uiVarEntries, &ObdSize, - 0x01); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - ObdSize = sizeof(bLedsRow2_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x2000, &bLedsRow2_l, &uiVarEntries, &ObdSize, - 0x02); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - ObdSize = sizeof(bSpeedSelect_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x2000, &bSpeedSelect_l, &uiVarEntries, &ObdSize, - 0x03); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - ObdSize = sizeof(bSpeedSelectOld_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x2000, &bSpeedSelectOld_l, &uiVarEntries, - &ObdSize, 0x04); - if (EplRet != kEplSuccessful) { - goto Exit; - } - - ObdSize = sizeof(abSelect_l[0]); - uiVarEntries = sizeof(abSelect_l); - EplRet = - EplApiLinkObject(0x2200, &abSelect_l[0], &uiVarEntries, &ObdSize, - 0x01); - if (EplRet != kEplSuccessful) { - goto Exit; - } -#endif - - // link a DOMAIN to object 0x6100, but do not exit, if it is missing - ObdSize = sizeof(abDomain_l); - uiVarEntries = 1; - EplRet = - EplApiLinkObject(0x6100, &abDomain_l, &uiVarEntries, &ObdSize, - 0x00); - if (EplRet != kEplSuccessful) { - printk("EplApiLinkObject(0x6100): returns 0x%X\n", EplRet); - } - // reset old process variables - bVarOut1Old_l = 0; - bSpeedSelectOld_l = 0; - dwMode_l = APP_DEFAULT_MODE; - iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT; - - // configure IP address of virtual network interface - // for TCP/IP communication over the POWERLINK network - sprintf(sBuffer, "%u.%u.%u.%u", - (EplApiInitParam.m_dwIpAddress >> 24), - ((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF), - ((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF), - (EplApiInitParam.m_dwIpAddress & 0xFF)); - /* set up a minimal environment */ - iRet = 0; - envp[iRet++] = "HOME=/"; - envp[iRet++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - envp[iRet] = NULL; - - /* set up the argument list */ - iRet = 0; - argv[iRet++] = "/sbin/ifconfig"; - argv[iRet++] = IF_ETH; - argv[iRet++] = sBuffer; - argv[iRet] = NULL; - - /* call ifconfig to configure the virtual network interface */ - iRet = call_usermodehelper(argv[0], argv, envp, 1); - printk("ifconfig %s %s returned %d\n", argv[1], argv[2], iRet); - - // start the NMT state machine - EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); - atomic_set(&AtomicShutdown_g, FALSE); - - Exit: - printk("EplLinInit(): returns 0x%X\n", EplRet); - return EplRet; -} - -static void __exit EplLinExit(void) -{ - tEplKernel EplRet; - - // halt the NMT state machine - // so the processing of POWERLINK frames stops - EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); - - // wait until NMT state machine is shut down - wait_event_interruptible(WaitQueueShutdown_g, - (atomic_read(&AtomicShutdown_g) == TRUE)); -/* if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL)) - { // waiting was interrupted by signal or application called wrong function - EplRet = kEplShutdown; - }*/ - // delete instance for all modules - EplRet = EplApiShutdown(); - printk("EplApiShutdown(): 0x%X\n", EplRet); - - // deinitialize proc fs - EplRet = EplLinProcFree(); - printk("EplLinProcFree(): 0x%X\n", EplRet); - -} -#endif -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: AppCbEvent -// -// Description: event callback function called by EPL API layer within -// user part (low priority). -// -// Parameters: EventType_p = event type -// pEventArg_p = pointer to union, which describes -// the event in detail -// pUserArg_p = user specific argument -// -// Returns: tEplKernel = error code, -// kEplSuccessful = no error -// kEplReject = reject further processing -// otherwise = post error event to API layer -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p) -{ - tEplKernel EplRet = kEplSuccessful; - - // check if NMT_GS_OFF is reached - switch (EventType_p) { - case kEplApiEventNmtStateChange: - { - switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) { - case kEplNmtGsOff: - { // NMT state machine was shut down, - // because of user signal (CTRL-C) or critical EPL stack error - // -> also shut down EplApiProcess() and main() - EplRet = kEplShutdown; - - printk - ("AppCbEvent(kEplNmtGsOff) originating event = 0x%X\n", - pEventArg_p->m_NmtStateChange. - m_NmtEvent); - - // wake up EplLinExit() - atomic_set(&AtomicShutdown_g, TRUE); - wake_up_interruptible - (&WaitQueueShutdown_g); - break; - } - - case kEplNmtGsResetCommunication: - { - u32 dwBuffer; - - // configure OD for MN in state ResetComm after reseting the OD - // TODO: setup your own network configuration here - dwBuffer = (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS); // 0x00000003L - EplRet = - EplApiWriteLocalObject(0x1F81, 0x01, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x02, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x03, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x04, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x05, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x06, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x07, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x08, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x20, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0xFE, - &dwBuffer, - 4); - EplRet = - EplApiWriteLocalObject(0x1F81, 0x6E, - &dwBuffer, - 4); - -// dwBuffer |= EPL_NODEASSIGN_MANDATORY_CN; // 0x0000000BL -// EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4); - dwBuffer = (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS); // 0x00010001L - EplRet = - EplApiWriteLocalObject(0x1F81, 0xF0, - &dwBuffer, - 4); - - // continue - } - - case kEplNmtGsResetConfiguration: - { - unsigned int uiSize; - - // fetch object 0x1006 NMT_CycleLen_U32 from local OD (in little endian byte order) - // for configuration of remote CN - uiSize = 4; - EplRet = - EplApiReadObject(NULL, 0, 0x1006, - 0x00, - &dw_le_CycleLen_g, - &uiSize, - kEplSdoTypeAsnd, - NULL); - if (EplRet != kEplSuccessful) { // local OD access failed - break; - } - // continue - } - - case kEplNmtMsPreOperational1: - { - printk - ("AppCbEvent(0x%X) originating event = 0x%X\n", - pEventArg_p->m_NmtStateChange. - m_NewNmtState, - pEventArg_p->m_NmtStateChange. - m_NmtEvent); - - // continue - } - - case kEplNmtGsInitialising: - case kEplNmtGsResetApplication: - case kEplNmtMsNotActive: - case kEplNmtCsNotActive: - case kEplNmtCsPreOperational1: - { - break; - } - - case kEplNmtCsOperational: - case kEplNmtMsOperational: - { - break; - } - - default: - { - break; - } - } - -/* - switch (pEventArg_p->m_NmtStateChange.m_NmtEvent) - { - case kEplNmtEventSwReset: - case kEplNmtEventResetNode: - case kEplNmtEventResetCom: - case kEplNmtEventResetConfig: - case kEplNmtEventInternComError: - case kEplNmtEventNmtCycleError: - { - printk("AppCbEvent(0x%X) originating event = 0x%X\n", - pEventArg_p->m_NmtStateChange.m_NewNmtState, - pEventArg_p->m_NmtStateChange.m_NmtEvent); - break; - } - - default: - { - break; - } - } -*/ - break; - } - - case kEplApiEventCriticalError: - case kEplApiEventWarning: - { // error or warning occured within the stack or the application - // on error the API layer stops the NMT state machine - - printk - ("AppCbEvent(Err/Warn): Source=%02X EplError=0x%03X", - pEventArg_p->m_InternalError.m_EventSource, - pEventArg_p->m_InternalError.m_EplError); - // check additional argument - switch (pEventArg_p->m_InternalError.m_EventSource) { - case kEplEventSourceEventk: - case kEplEventSourceEventu: - { // error occured within event processing - // either in kernel or in user part - printk(" OrgSource=%02X\n", - pEventArg_p->m_InternalError. - m_Arg.m_EventSource); - break; - } - - case kEplEventSourceDllk: - { // error occured within the data link layer (e.g. interrupt processing) - // the u32 argument contains the DLL state and the NMT event - printk(" val=%X\n", - pEventArg_p->m_InternalError. - m_Arg.m_dwArg); - break; - } - - default: - { - printk("\n"); - break; - } - } - break; - } - - case kEplApiEventNode: - { -// printk("AppCbEvent(Node): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError); - // check additional argument - switch (pEventArg_p->m_Node.m_NodeEvent) { - case kEplNmtNodeEventCheckConf: - { - tEplSdoComConHdl SdoComConHdl; - // update object 0x1006 on CN - EplRet = - EplApiWriteObject(&SdoComConHdl, - pEventArg_p-> - m_Node.m_uiNodeId, - 0x1006, 0x00, - &dw_le_CycleLen_g, - 4, - kEplSdoTypeAsnd, - NULL); - if (EplRet == kEplApiTaskDeferred) { // SDO transfer started - EplRet = kEplReject; - } else if (EplRet == kEplSuccessful) { // local OD access (should not occur) - printk - ("AppCbEvent(Node) write to local OD\n"); - } else { // error occured - TGT_DBG_SIGNAL_TRACE_POINT(1); - - EplRet = - EplApiFreeSdoChannel - (SdoComConHdl); - SdoComConHdl = 0; - - EplRet = - EplApiWriteObject - (&SdoComConHdl, - pEventArg_p->m_Node. - m_uiNodeId, 0x1006, 0x00, - &dw_le_CycleLen_g, 4, - kEplSdoTypeAsnd, NULL); - if (EplRet == kEplApiTaskDeferred) { // SDO transfer started - EplRet = kEplReject; - } else { - printk - ("AppCbEvent(Node): EplApiWriteObject() returned 0x%02X\n", - EplRet); - } - } - - break; - } - - default: - { - break; - } - } - break; - } - - case kEplApiEventSdo: - { // SDO transfer finished - EplRet = - EplApiFreeSdoChannel(pEventArg_p->m_Sdo. - m_SdoComConHdl); - if (EplRet != kEplSuccessful) { - break; - } -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - if (pEventArg_p->m_Sdo.m_SdoComConState == kEplSdoComTransferFinished) { // continue boot-up of CN with NMT command Reset Configuration - EplRet = - EplApiMnTriggerStateChange(pEventArg_p-> - m_Sdo.m_uiNodeId, - kEplNmtNodeCommandConfReset); - } else { // indicate configuration error CN - EplRet = - EplApiMnTriggerStateChange(pEventArg_p-> - m_Sdo.m_uiNodeId, - kEplNmtNodeCommandConfErr); - } -#endif - - break; - } - - default: - break; - } - - return EplRet; -} - -//--------------------------------------------------------------------------- -// -// Function: AppCbSync -// -// Description: sync event callback function called by event module within -// kernel part (high priority). -// This function sets the outputs, reads the inputs and runs -// the control loop. -// -// Parameters: void -// -// Returns: tEplKernel = error code, -// kEplSuccessful = no error -// otherwise = post error event to API layer -// -// State: -// -//--------------------------------------------------------------------------- - -tEplKernel AppCbSync(void) -{ - tEplKernel EplRet = kEplSuccessful; - - if (bVarOut1Old_l != bVarOut1_l) { // output variable has changed - bVarOut1Old_l = bVarOut1_l; - // set LEDs - -// printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (u16) bVarIn_l, (u16) bVarOut_l); - } - if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) { - bVarIn1_l++; - } - - if (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID) { // we are the master and must run the control loop - - // collect inputs from CNs and own input - bSpeedSelect_l = (bVarIn1_l | abSelect_l[0]) & 0x07; - - bModeSelect_l = abSelect_l[1] | abSelect_l[2]; - - if ((bModeSelect_l & APP_MODE_MASK) != 0) { - dwMode_l = bModeSelect_l & APP_MODE_MASK; - } - - iCurCycleCount_l--; - - if (iCurCycleCount_l <= 0) { - if ((dwMode_l & 0x01) != 0) { // fill-up - if (iToggle) { - if ((dwLeds_l & APP_DOUBLE_LED_MASK) == - 0x00) { - dwLeds_l = 0x01; - } else { - dwLeds_l <<= 1; - dwLeds_l++; - if (dwLeds_l >= - APP_DOUBLE_LED_MASK) { - iToggle = 0; - } - } - } else { - dwLeds_l <<= 1; - if ((dwLeds_l & APP_DOUBLE_LED_MASK) == - 0x00) { - iToggle = 1; - } - } - bLedsRow1_l = - (unsigned char)(dwLeds_l & APP_LED_MASK); - bLedsRow2_l = - (unsigned char)((dwLeds_l >> APP_LED_COUNT) - & APP_LED_MASK); - } - - else if ((dwMode_l & 0x02) != 0) { // running light forward - dwLeds_l <<= 1; - if ((dwLeds_l > APP_DOUBLE_LED_MASK) - || (dwLeds_l == 0x00000000L)) { - dwLeds_l = 0x01; - } - bLedsRow1_l = - (unsigned char)(dwLeds_l & APP_LED_MASK); - bLedsRow2_l = - (unsigned char)((dwLeds_l >> APP_LED_COUNT) - & APP_LED_MASK); - } - - else if ((dwMode_l & 0x04) != 0) { // running light backward - dwLeds_l >>= 1; - if ((dwLeds_l > APP_DOUBLE_LED_MASK) - || (dwLeds_l == 0x00000000L)) { - dwLeds_l = 1 << (APP_LED_COUNT * 2); - } - bLedsRow1_l = - (unsigned char)(dwLeds_l & APP_LED_MASK); - bLedsRow2_l = - (unsigned char)((dwLeds_l >> APP_LED_COUNT) - & APP_LED_MASK); - } - - else if ((dwMode_l & 0x08) != 0) { // Knightrider - if (bLedsRow1_l == 0x00) { - bLedsRow1_l = 0x01; - iToggle = 1; - } else if (iToggle) { - bLedsRow1_l <<= 1; - if (bLedsRow1_l >= - (1 << (APP_LED_COUNT - 1))) { - iToggle = 0; - } - } else { - bLedsRow1_l >>= 1; - if (bLedsRow1_l <= 0x01) { - iToggle = 1; - } - } - bLedsRow2_l = bLedsRow1_l; - } - - else if ((dwMode_l & 0x10) != 0) { // Knightrider - if ((bLedsRow1_l == 0x00) - || (bLedsRow2_l == 0x00) - || ((bLedsRow2_l & ~APP_LED_MASK) != 0)) { - bLedsRow1_l = 0x01; - bLedsRow2_l = - (1 << (APP_LED_COUNT - 1)); - iToggle = 1; - } else if (iToggle) { - bLedsRow1_l <<= 1; - bLedsRow2_l >>= 1; - if (bLedsRow1_l >= - (1 << (APP_LED_COUNT - 1))) { - iToggle = 0; - } - } else { - bLedsRow1_l >>= 1; - bLedsRow2_l <<= 1; - if (bLedsRow1_l <= 0x01) { - iToggle = 1; - } - } - } - // set own output - bVarOut1_l = bLedsRow1_l; -// bVarOut1_l = (bLedsRow1_l & 0x03) | (bLedsRow2_l << 2); - - // restart cycle counter - iCurCycleCount_l = iMaxCycleCount_l; - } - - if (bSpeedSelectOld_l == 0) { - if ((bSpeedSelect_l & 0x01) != 0) { - if (iMaxCycleCount_l < 200) { - iMaxCycleCount_l++; - } - bSpeedSelectOld_l = bSpeedSelect_l; - } else if ((bSpeedSelect_l & 0x02) != 0) { - if (iMaxCycleCount_l > 1) { - iMaxCycleCount_l--; - } - bSpeedSelectOld_l = bSpeedSelect_l; - } else if ((bSpeedSelect_l & 0x04) != 0) { - iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT; - bSpeedSelectOld_l = bSpeedSelect_l; - } - } else if (bSpeedSelect_l == 0) { - bSpeedSelectOld_l = 0; - } - } - - TGT_DBG_SIGNAL_TRACE_POINT(1); - - return EplRet; -} - -// EOF diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h deleted file mode 100644 index 62b4e77e069..00000000000 --- a/drivers/staging/epl/edrv.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: interface for ethernetdriver - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: edrv.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2005/08/01 m.b.: start of implementation - -****************************************************************************/ - -#ifndef _EDRV_H_ -#define _EDRV_H_ - -#include "EplInc.h" -#include "EplFrame.h" - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- -// -------------------------------------------------------------------------- -#define MAX_ETH_DATA_SIZE 1500 -#define MIN_ETH_DATA_SIZE 46 - -#define ETH_HDR_OFFSET 0 // Ethernet header at the top of the frame -#define ETH_HDR_SIZE 14 // size of Ethernet header -#define MIN_ETH_SIZE (MIN_ETH_DATA_SIZE + ETH_HDR_SIZE) // without CRC - -#define ETH_CRC_SIZE 4 // size of Ethernet CRC, i.e. FCS - -//--------------------------------------------------------------------------- -// types -//--------------------------------------------------------------------------- - -// position of a buffer in an ethernet-frame -typedef enum { - kEdrvBufferFirstInFrame = 0x01, // first data buffer in an ethernet frame - kEdrvBufferMiddleInFrame = 0x02, // a middle data buffer in an ethernet frame - kEdrvBufferLastInFrame = 0x04 // last data buffer in an ethernet frame -} tEdrvBufferInFrame; - -// format of a tx-buffer -typedef struct _tEdrvTxBuffer { - tEplMsgType m_EplMsgType; // IN: type of EPL message, set by calling function - unsigned int m_uiTxMsgLen; // IN: length of message to be send (set for each transmit call) - // ---------------------- - unsigned int m_uiBufferNumber; // OUT: number of the buffer, set by ethernetdriver - u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver - tEplNetTime m_NetTime; // OUT: Timestamp of end of transmission, set by ethernetdriver - // ---------------------- - unsigned int m_uiMaxBufferLen; // IN/OUT: maximum length of the buffer -} tEdrvTxBuffer; - -// format of a rx-buffer -typedef struct _tEdrvRxBuffer { - tEdrvBufferInFrame m_BufferInFrame; // OUT position of received buffer in an ethernet-frame - unsigned int m_uiRxMsgLen; // OUT: length of received buffer (without CRC) - u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver - tEplNetTime m_NetTime; // OUT: Timestamp of end of receiption - -} tEdrvRxBuffer; - -//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, tBufferDescr * pbBuffer_p); -//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, u8 * pbEthernetData_p, u16 wDataLen_p); -typedef void (*tEdrvRxHandler) (tEdrvRxBuffer * pRxBuffer_p); -typedef void (*tEdrvTxHandler) (tEdrvTxBuffer * pTxBuffer_p); - -// format of init structure -typedef struct { - u8 m_abMyMacAddr[6]; // the own MAC address - -// u8 m_bNoOfRxBuffDescr; // number of entries in rx bufferdescriptor table -// tBufferDescr * m_pRxBuffDescrTable; // rx bufferdescriptor table -// u16 m_wRxBufferSize; // size of the whole rx buffer - - tEdrvRxHandler m_pfnRxHandler; - tEdrvTxHandler m_pfnTxHandler; - -} tEdrvInitParam; - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p); - -tEplKernel EdrvShutdown(void); - -tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p); -tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p); - -//tEplKernel EdrvDefineUnicastEntry (u8 * pbUCEntry_p); -//tEplKernel EdrvUndfineUnicastEntry (u8 * pbUCEntry_p); - -tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p); -tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p); - -//tEplKernel EdrvWriteMsg (tBufferDescr * pbBuffer_p); -tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p); -tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p); -tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p); - -//tEplKernel EdrvReadMsg (void); - -// interrupt handler called by target specific interrupt handler -void EdrvInterruptHandler(void); - -#endif // #ifndef _EDRV_H_ diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h deleted file mode 100644 index 8c52d97ec9c..00000000000 --- a/drivers/staging/epl/global.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** - - global project definition file - - 12.06.1998 -rs - 11.02.2002 r.d. Erweiterungen, Ergaenzungen - 20.08.2002 SYS TEC electronic -as - Definition Schluesselwort 'GENERIC' - fuer das Erzeugen von Generic Pointer - 28.08.2002 r.d. erweiterter SYS TEC Debug Code - 16.09.2002 r.d. komplette Uebersetzung in Englisch - 11.04.2003 f.j. Ergaenzung fuer Mitsubishi NC30 Compiler - 17.06.2003 -rs Definition von Basistypen in <#ifndef _WINDEF_> gesetzt - 16.04.2004 r.d. Ergaenzung fuer Borland C++ Builder - 30.08.2004 -rs TRACE5 eingefügt - 23.12.2005 d.k. Definitions for IAR compiler - - $Id: global.h,v 1.6 2008/11/07 13:55:56 D.Krueger Exp $ - -****************************************************************************/ - -#ifndef _GLOBAL_H_ -#define _GLOBAL_H_ - - -#define TRACE printk - -// --- logic types --- -#ifndef BOOL -#define BOOL unsigned char -#endif - -// --- alias types --- -#ifndef TRUE -#define TRUE 0xFF -#endif -#ifndef FALSE -#define FALSE 0x00 -#endif -#ifndef _TIME_OF_DAY_DEFINED_ -typedef struct { - unsigned long int m_dwMs; - unsigned short int m_wDays; - -} tTimeOfDay; - -#define _TIME_OF_DAY_DEFINED_ - -#endif - -//--------------------------------------------------------------------------- -// Definition von TRACE -//--------------------------------------------------------------------------- - -#ifndef NDEBUG - -#ifndef TRACE0 -#define TRACE0(p0) TRACE(p0) -#endif - -#ifndef TRACE1 -#define TRACE1(p0, p1) TRACE(p0, p1) -#endif - -#ifndef TRACE2 -#define TRACE2(p0, p1, p2) TRACE(p0, p1, p2) -#endif - -#ifndef TRACE3 -#define TRACE3(p0, p1, p2, p3) TRACE(p0, p1, p2, p3) -#endif - -#ifndef TRACE4 -#define TRACE4(p0, p1, p2, p3, p4) TRACE(p0, p1, p2, p3, p4) -#endif - -#ifndef TRACE5 -#define TRACE5(p0, p1, p2, p3, p4, p5) TRACE(p0, p1, p2, p3, p4, p5) -#endif - -#ifndef TRACE6 -#define TRACE6(p0, p1, p2, p3, p4, p5, p6) TRACE(p0, p1, p2, p3, p4, p5, p6) -#endif - -#else - -#ifndef TRACE0 -#define TRACE0(p0) -#endif - -#ifndef TRACE1 -#define TRACE1(p0, p1) -#endif - -#ifndef TRACE2 -#define TRACE2(p0, p1, p2) -#endif - -#ifndef TRACE3 -#define TRACE3(p0, p1, p2, p3) -#endif - -#ifndef TRACE4 -#define TRACE4(p0, p1, p2, p3, p4) -#endif - -#ifndef TRACE5 -#define TRACE5(p0, p1, p2, p3, p4, p5) -#endif - -#ifndef TRACE6 -#define TRACE6(p0, p1, p2, p3, p4, p5, p6) -#endif - -#endif - -//--------------------------------------------------------------------------- -// definition of ASSERT -//--------------------------------------------------------------------------- - -#ifndef ASSERT -#define ASSERT(p) -#endif - -//--------------------------------------------------------------------------- -// SYS TEC extensions -//--------------------------------------------------------------------------- - -// This macro doesn't print out C-file and line number of the failed assertion -// but a string, which exactly names the mistake. -#ifndef NDEBUG - -#define ASSERTMSG(expr,string) if (!(expr)) {\ - PRINTF0 ("Assertion failed: " string );\ - while (1);} -#else -#define ASSERTMSG(expr,string) -#endif - -//--------------------------------------------------------------------------- - -#endif // #ifndef _GLOBAL_H_ - -// Please keep an empty line at the end of this file. diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h deleted file mode 100644 index a97920ab884..00000000000 --- a/drivers/staging/epl/kernel/EplDllk.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernelspace DLL module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/08 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLLK_H_ -#define _EPL_DLLK_H_ - -#include "../EplDll.h" -#include "../EplEvent.h" - -typedef tEplKernel(*tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p); - -typedef struct { - u8 m_be_abSrcMac[6]; - -} tEplDllkInitParam; - -// forward declaration -struct _tEdrvTxBuffer; - -struct _tEplDllkNodeInfo { - struct _tEplDllkNodeInfo *m_pNextNodeInfo; - struct _tEdrvTxBuffer *m_pPreqTxBuffer; - unsigned int m_uiNodeId; - u32 m_dwPresTimeout; - unsigned long m_ulDllErrorEvents; - tEplNmtState m_NmtState; - u16 m_wPresPayloadLimit; - u8 m_be_abMacAddr[6]; - u8 m_bSoaFlag1; - BOOL m_fSoftDelete; // delete node after error and ignore error - -}; - -typedef struct _tEplDllkNodeInfo tEplDllkNodeInfo; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p); - -tEplKernel EplDllkDelInstance(void); - -// called before NMT_GS_COMMUNICATING will be entered to configure fixed parameters -tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p); - -// set identity of local node (may be at any time, e.g. in case of hostname change) -tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p); - -// process internal events and do work that cannot be done in interrupt-context -tEplKernel EplDllkProcess(tEplEvent * pEvent_p); - -// registers handler for non-EPL frames -tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p); - -// deregisters handler for non-EPL frames -tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p); - -// register C_DLL_MULTICAST_ASND in ethernet driver if any AsndServiceId is registered -tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, - tEplDllAsndFilter Filter_p); - -// creates the buffer for a Tx frame and registers it to the ethernet driver -tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p, - tEplFrame ** ppFrame_p, - unsigned int *puiFrameSize_p, - tEplMsgType MsgType_p, - tEplDllAsndServiceId ServiceId_p); - -tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p); - -tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p); - -tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p); - -tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p); - -tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p); - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -#endif // #ifndef _EPL_DLLK_H_ diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h deleted file mode 100644 index ddec1d5e8cc..00000000000 --- a/drivers/staging/epl/kernel/EplDllkCal.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernelspace DLL Communication Abstraction Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllkCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/11/13 17:13:09 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/13 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLLKCAL_H_ -#define _EPL_DLLKCAL_H_ - -#include "../EplDll.h" -#include "../EplEvent.h" - -typedef struct { - unsigned long m_ulCurTxFrameCountGen; - unsigned long m_ulCurTxFrameCountNmt; - unsigned long m_ulCurRxFrameCount; - unsigned long m_ulMaxTxFrameCountGen; - unsigned long m_ulMaxTxFrameCountNmt; - unsigned long m_ulMaxRxFrameCount; - -} tEplDllkCalStatistics; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -tEplKernel EplDllkCalAddInstance(void); - -tEplKernel EplDllkCalDelInstance(void); - -tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, - unsigned int *puiCount_p); -tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p, - unsigned int *puiFrameSize_p, - tEplDllAsyncReqPriority Priority_p); -// only frames with registered AsndServiceIds are passed to CAL -tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p); - -tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, - tEplDllAsyncReqPriority Priority_p); - -tEplKernel EplDllkCalAsyncClearBuffer(void); - -tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics); - -tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -tEplKernel EplDllkCalAsyncClearQueues(void); - -tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, - unsigned int uiNodeId_p, u8 bSoaFlag1_p); - -tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p, - unsigned int *puiNodeId_p); - -tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, - tEplDllAsyncReqPriority - AsyncReqPrio_p, - unsigned int uiCount_p); - -#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) - -#endif // #ifndef _EPL_DLLKCAL_H_ diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h deleted file mode 100644 index 185b597d6e5..00000000000 --- a/drivers/staging/epl/kernel/EplErrorHandlerk.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernel error handler module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplErrorHandlerk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/10/02 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_ERRORHANDLERK_H_ -#define _EPL_ERRORHANDLERK_H_ - -#include "../EplEvent.h" - -// init function -tEplKernel EplErrorHandlerkInit(void); - -// add instance -tEplKernel EplErrorHandlerkAddInstance(void); - -// delete instance -tEplKernel EplErrorHandlerkDelInstance(void); - -// processes error events -tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p); - -#endif // #ifndef _EPL_ERRORHANDLERK_H_ diff --git a/drivers/staging/epl/kernel/EplEventk.h b/drivers/staging/epl/kernel/EplEventk.h deleted file mode 100644 index 0c2a60f7207..00000000000 --- a/drivers/staging/epl/kernel/EplEventk.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernel event module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplEventk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_EVENTK_H_ -#define _EPL_EVENTK_H_ - -#include "../EplEvent.h" - -// init function -tEplKernel EplEventkInit(tEplSyncCb fpSyncCb); - -// add instance -tEplKernel EplEventkAddInstance(tEplSyncCb fpSyncCb); - -// delete instance -tEplKernel EplEventkDelInstance(void); - -// Kernelthread that dispatches events in kernelspace -tEplKernel EplEventkProcess(tEplEvent *pEvent_p); - -// post events from kernelspace -tEplKernel EplEventkPost(tEplEvent *pEvent_p); - -// post errorevents from kernelspace -tEplKernel EplEventkPostError(tEplEventSource EventSource_p, - tEplKernel EplError_p, - unsigned int uiArgSize_p, void *pArg_p); - -#endif // #ifndef _EPL_EVENTK_H_ diff --git a/drivers/staging/epl/kernel/EplNmtk.h b/drivers/staging/epl/kernel/EplNmtk.h deleted file mode 100644 index 5dc8a373159..00000000000 --- a/drivers/staging/epl/kernel/EplNmtk.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for NMT-Kernelspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMTK_H_ -#define _EPLNMTK_H_ - -#include "../EplNmt.h" -#include "EplEventk.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) -tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR); - -tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR); - -tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR); - -tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p); - -tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR); - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) - -#endif // #ifndef _EPLNMTK_H_ diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h deleted file mode 100644 index 78c4d961342..00000000000 --- a/drivers/staging/epl/kernel/EplObdk.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Epl-Obd-Kernel-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObdk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.8 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLOBDK_H_ -#define _EPLOBDK_H_ - -#include "../EplObd.h" - -extern u8 abEplObdTrashObject_g[8]; - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) -// --------------------------------------------------------------------- -tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR); - -// --------------------------------------------------------------------- -tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p, - tEplObdDir Direction_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p); - -// --------------------------------------------------------------------- -void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p); -// --------------------------------------------------------------------- -tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p); - -// --------------------------------------------------------------------- -void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p, - tEplObdType Type_p, tEplObdSize ObdSize_p); - -// --------------------------------------------------------------------- -tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p); - -// --------------------------------------------------------------------- -unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR); - -// --------------------------------------------------------------------- -tEplKernel EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiNodeId_p, - tEplObdNodeIdType NodeIdType_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, BOOL *pfEntryNumerical); -// --------------------------------------------------------------------- -tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - tEplObdSize Size_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p); - -// --------------------------------------------------------------------- -tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p); - -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) - -#endif // #ifndef _EPLOBDK_H_ diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h deleted file mode 100644 index 24bfc3f73e9..00000000000 --- a/drivers/staging/epl/kernel/EplPdok.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernel PDO module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdok.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/06/23 14:56:33 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_PDOK_H_ -#define _EPL_PDOK_H_ - -#include "../EplPdo.h" -#include "../EplEvent.h" -#include "../EplDll.h" - -// process events from queue (PDOs/frames and SoA for synchronization) -tEplKernel EplPdokProcess(tEplEvent * pEvent_p); - -// copies RPDO to event queue for processing -// is called by DLL in NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL -// PDO needs not to be valid -tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p); - -// posts pointer and size of TPDO to event queue -// is called by DLL in NMT_CS_PRE_OPERATIONAL_2, -// NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL -tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p); - -// posts SoA event to queue -tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p); - -tEplKernel EplPdokAddInstance(void); - -tEplKernel EplPdokDelInstance(void); - -#endif // #ifndef _EPL_PDOK_H_ diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h deleted file mode 100644 index 8a31edfdb4f..00000000000 --- a/drivers/staging/epl/kernel/EplPdokCal.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernel PDO Communication Abstraction Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdokCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_PDOKCAL_H_ -#define _EPL_PDOKCAL_H_ - -#include "../EplInc.h" - -tEplKernel EplPdokCalAddInstance(void); - -tEplKernel EplPdokCalDelInstance(void); - -// sets flag for validity of TPDOs in shared memory -tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p); - -// gets flag for validity of TPDOs from shared memory -tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p); - -#endif // #ifndef _EPL_PDOKCAL_H_ diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h deleted file mode 100644 index a2124ee49f7..00000000000 --- a/drivers/staging/epl/kernel/EplTimerHighResk.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL high resolution Timermodule - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimerHighResk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/09/29 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLTIMERHIGHRESK_H_ -#define _EPLTIMERHIGHRESK_H_ - -#include "../EplTimer.h" - -tEplKernel EplTimerHighReskInit(void); - -tEplKernel EplTimerHighReskAddInstance(void); - -tEplKernel EplTimerHighReskDelInstance(void); - -tEplKernel EplTimerHighReskSetTimerNs(tEplTimerHdl *pTimerHdl_p, - unsigned long long ullTimeNs_p, - tEplTimerkCallback pfnCallback_p, - unsigned long ulArgument_p, - BOOL fContinuously_p); - -tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p, - unsigned long long ullTimeNs_p, - tEplTimerkCallback pfnCallback_p, - unsigned long ulArgument_p, - BOOL fContinuously_p); - -tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p); - -#endif // #ifndef _EPLTIMERHIGHRESK_H_ diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h deleted file mode 100644 index 47c5f47b8aa..00000000000 --- a/drivers/staging/epl/kernel/EplTimerk.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for EPL Kernel-Timermodule - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimerk.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/06 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLTIMERK_H_ -#define _EPLTIMERK_H_ - -#include "../EplTimer.h" -#include "../user/EplEventu.h" - -#if EPL_TIMER_USE_USER != FALSE -#include "../user/EplTimeru.h" -#endif - - -#if EPL_TIMER_USE_USER != FALSE -#define EplTimerkInit EplTimeruInit -#define EplTimerkAddInstance EplTimeruAddInstance -#define EplTimerkDelInstance EplTimeruDelInstance -#define EplTimerkSetTimerMs EplTimeruSetTimerMs -#define EplTimerkModifyTimerMs EplTimeruModifyTimerMs -#define EplTimerkDeleteTimer EplTimeruDeleteTimer -#endif - -#if EPL_TIMER_USE_USER == FALSE -tEplKernel EplTimerkInit(void); - -tEplKernel EplTimerkAddInstance(void); - -tEplKernel EplTimerkDelInstance(void); - -tEplKernel EplTimerkSetTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p); - -tEplKernel EplTimerkModifyTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p); - -tEplKernel EplTimerkDeleteTimer(tEplTimerHdl *pTimerHdl_p); -#endif -#endif // #ifndef _EPLTIMERK_H_ diff --git a/drivers/staging/epl/kernel/VirtualEthernet.h b/drivers/staging/epl/kernel/VirtualEthernet.h deleted file mode 100644 index 4a42cce66ca..00000000000 --- a/drivers/staging/epl/kernel/VirtualEthernet.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for virtual ethernet driver module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: VirtualEthernet.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/09/19 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_VETH_H_ -#define _EPL_VETH_H_ - -#include "EplDllk.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - -tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p); - -tEplKernel VEthDelInstance(void); - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0) - -#endif // #ifndef _EPL_VETH_H_ diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c deleted file mode 100644 index e48949d9ddf..00000000000 --- a/drivers/staging/epl/proc_fs.c +++ /dev/null @@ -1,410 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: proc fs entry with diagnostic information under Linux - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: proc_fs.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.13 $ $Date: 2008/11/07 13:55:56 $ - - $State: Exp $ - - Build Environment: - GNU - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/31 d.k.: start of implementation - -****************************************************************************/ - -#include "kernel/EplNmtk.h" -#include "user/EplNmtu.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) -#include "user/EplNmtMnu.h" -#endif - -#include "kernel/EplDllkCal.h" - -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_COLDFIRE -#include -#include "fec.h" -#endif - -#include "proc_fs.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EPL_PROC_DEV_NAME -#define EPL_PROC_DEV_NAME "epl" -#endif - -#ifndef DBG_TRACE_POINTS -#define DBG_TRACE_POINTS 23 // # of supported debug trace points -#endif - -#ifndef DBG_TRACE_VALUES -#define DBG_TRACE_VALUES 24 // # of supported debug trace values (size of circular buffer) -#endif - -//--------------------------------------------------------------------------- -// modul global types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -#ifdef _DBG_TRACE_POINTS_ -atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS]; -u32 adwDbgTraceValue_l[DBG_TRACE_VALUES]; -u32 dwDbgTraceValueOld_l; -unsigned int uiDbgTraceValuePos_l; -spinlock_t spinlockDbgTraceValue_l; -unsigned long ulDbTraceValueFlags_l; -#endif - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static int EplLinProcRead(char *pcBuffer_p, char **ppcStart_p, off_t Offset_p, - int nBufferSize_p, int *pEof_p, void *pData_p); -static int EplLinProcWrite(struct file *file, const char __user * buffer, - unsigned long count, void *data); - -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); - -extern u32 EplIdentuGetRunningRequests(void); - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -tEplKernel EplLinProcInit(void) -{ - struct proc_dir_entry *pProcDirEntry; - pProcDirEntry = create_proc_entry(EPL_PROC_DEV_NAME, S_IRUGO, NULL); - if (pProcDirEntry != NULL) { - pProcDirEntry->read_proc = EplLinProcRead; - pProcDirEntry->write_proc = EplLinProcWrite; - pProcDirEntry->data = NULL; // device number or something else - - } else { - return kEplNoResource; - } - -#ifdef _DBG_TRACE_POINTS_ - // initialize spinlock and circular buffer position - spin_lock_init(&spinlockDbgTraceValue_l); - uiDbgTraceValuePos_l = 0; - dwDbgTraceValueOld_l = 0; -#endif - - return kEplSuccessful; -} - -tEplKernel EplLinProcFree(void) -{ - remove_proc_entry(EPL_PROC_DEV_NAME, NULL); - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// Target specific event signaling (FEC Tx-/Rx-Interrupt, used by Edrv) -//--------------------------------------------------------------------------- - -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p) -{ - - if (bTracePointNumber_p >= - ARRAY_SIZE(aatmDbgTracePoint_l)) { - goto Exit; - } - - atomic_inc(&aatmDbgTracePoint_l[bTracePointNumber_p]); - - Exit: - - return; - -} - -void TgtDbgPostTraceValue(u32 dwTraceValue_p) -{ - - spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l); - if (dwDbgTraceValueOld_l != dwTraceValue_p) { - adwDbgTraceValue_l[uiDbgTraceValuePos_l] = dwTraceValue_p; - uiDbgTraceValuePos_l = - (uiDbgTraceValuePos_l + 1) % DBG_TRACE_VALUES; - dwDbgTraceValueOld_l = dwTraceValue_p; - } - spin_unlock_irqrestore(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l); - - return; - -} -#endif - -//--------------------------------------------------------------------------- -// Read function for PROC-FS read access -//--------------------------------------------------------------------------- - -static int EplLinProcRead(char *pcBuffer_p, - char **ppcStart_p, - off_t Offset_p, - int nBufferSize_p, int *pEof_p, void *pData_p) -{ - - int nSize; - int Eof; - tEplDllkCalStatistics *pDllkCalStats; - - nSize = 0; - Eof = 0; - - // count calls of this function -#ifdef _DBG_TRACE_POINTS_ - TgtDbgSignalTracePoint(0); -#endif - - //--------------------------------------------------------------- - // generate static information - //--------------------------------------------------------------- - - // ---- Driver information ---- - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "%s %s (c) 2006 %s\n", - EPL_PRODUCT_NAME, EPL_PRODUCT_VERSION, - EPL_PRODUCT_MANUFACTURER); - - //--------------------------------------------------------------- - // generate process information - //--------------------------------------------------------------- - - // ---- EPL state ---- - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "NMT state: 0x%04X\n", - (u16) EplNmtkGetNmtState()); - - EplDllkCalGetStatistics(&pDllkCalStats); - - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "CurAsyncTxGen=%lu CurAsyncTxNmt=%lu CurAsyncRx=%lu\nMaxAsyncTxGen=%lu MaxAsyncTxNmt=%lu MaxAsyncRx=%lu\n", - pDllkCalStats->m_ulCurTxFrameCountGen, - pDllkCalStats->m_ulCurTxFrameCountNmt, - pDllkCalStats->m_ulCurRxFrameCount, - pDllkCalStats->m_ulMaxTxFrameCountGen, - pDllkCalStats->m_ulMaxTxFrameCountNmt, - pDllkCalStats->m_ulMaxRxFrameCount); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - // fetch running IdentRequests - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "running IdentRequests: 0x%08X\n", - EplIdentuGetRunningRequests()); - - // fetch state of NmtMnu module - { - unsigned int uiMandatorySlaveCount; - unsigned int uiSignalSlaveCount; - u16 wFlags; - - EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount, - &uiSignalSlaveCount, &wFlags); - - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "MN MandSlaveCount: %u SigSlaveCount: %u Flags: 0x%X\n", - uiMandatorySlaveCount, uiSignalSlaveCount, - wFlags); - - } -#endif - - // ---- FEC state ---- -#ifdef CONFIG_COLDFIRE - { - // Receive the base address - unsigned long base_addr; -#if (EDRV_USED_ETH_CTRL == 0) - // Set the base address of FEC0 - base_addr = FEC_BASE_ADDR_FEC0; -#else - // Set the base address of FEC1 - base_addr = FEC_BASE_ADDR_FEC1; -#endif - - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "FEC_ECR = 0x%08X FEC_EIR = 0x%08X FEC_EIMR = 0x%08X\nFEC_TCR = 0x%08X FECTFSR = 0x%08X FECRFSR = 0x%08X\n", - FEC_ECR(base_addr), FEC_EIR(base_addr), - FEC_EIMR(base_addr), FEC_TCR(base_addr), - FEC_FECTFSR(base_addr), - FEC_FECRFSR(base_addr)); - } -#endif - - // ---- DBG: TracePoints ---- -#ifdef _DBG_TRACE_POINTS_ - { - int nNum; - - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "DbgTracePoints:\n"); - for (nNum = 0; - nNum < ARRAY_SIZE(aatmDbgTracePoint_l); - nNum++) { - nSize += - snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - " TracePoint[%2d]: %d\n", (int)nNum, - atomic_read(&aatmDbgTracePoint_l[nNum])); - } - - nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "DbgTraceValues:\n"); - for (nNum = 0; nNum < DBG_TRACE_VALUES; nNum++) { - if (nNum == uiDbgTraceValuePos_l) { // next value will be stored at that position - nSize += - snprintf(pcBuffer_p + nSize, - nBufferSize_p - nSize, "*%08lX", - adwDbgTraceValue_l[nNum]); - } else { - nSize += - snprintf(pcBuffer_p + nSize, - nBufferSize_p - nSize, " %08lX", - adwDbgTraceValue_l[nNum]); - } - if ((nNum & 0x00000007) == 0x00000007) { // 8 values printed -> end of line reached - nSize += - snprintf(pcBuffer_p + nSize, - nBufferSize_p - nSize, "\n"); - } - } - if ((nNum & 0x00000007) != 0x00000007) { // number of values printed is not a multiple of 8 -> print new line - nSize += - snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize, - "\n"); - } - } -#endif - - Eof = 1; - goto Exit; - - Exit: - - *pEof_p = Eof; - - return (nSize); - -} - -//--------------------------------------------------------------------------- -// Write function for PROC-FS write access -//--------------------------------------------------------------------------- - -static int EplLinProcWrite(struct file *file, const char __user * buffer, - unsigned long count, void *data) -{ - char abBuffer[count + 1]; - int iErr; - int iVal = 0; - tEplNmtEvent NmtEvent; - - if (count > 0) { - iErr = copy_from_user(abBuffer, buffer, count); - if (iErr != 0) { - return count; - } - abBuffer[count] = '\0'; - - iErr = sscanf(abBuffer, "%i", &iVal); - } - if ((iVal <= 0) || (iVal > 0x2F)) { - NmtEvent = kEplNmtEventSwReset; - } else { - NmtEvent = (tEplNmtEvent) iVal; - } - // execute specified NMT command on write access of /proc/epl - EplNmtuNmtEvent(NmtEvent); - - return count; -} diff --git a/drivers/staging/epl/proc_fs.h b/drivers/staging/epl/proc_fs.h deleted file mode 100644 index 0586f499553..00000000000 --- a/drivers/staging/epl/proc_fs.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: interface for proc fs entry under Linux - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: proc_fs.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:33 $ - - $State: Exp $ - - Build Environment: - GNU - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/31 d.k.: start of implementation - -****************************************************************************/ - -#ifndef _EPLPROCFS_H_ -#define _EPLPROCFS_H_ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// function prototypes -//--------------------------------------------------------------------------- - -tEplKernel EplLinProcInit(void); -tEplKernel EplLinProcFree(void); - -#endif // #ifndef _EPLPROCFS_H_ diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h deleted file mode 100644 index 4ac770f1310..00000000000 --- a/drivers/staging/epl/user/EplCfgMau.h +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Epl Configuration Manager Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplCfgMau.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - VC7 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/14 k.t.: start of the implementation - -> based on CANopen CfgMa-Modul (CANopen version 5.34) - -****************************************************************************/ - -#ifndef _EPLCFGMA_H_ -#define _EPLCFGMA_H_ - -#include "../EplInc.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0) - -#include "EplObdu.h" -#include "EplSdoComu.h" - -//define max number of timeouts for configuration of 1 device -#define EPL_CFGMA_MAX_TIMEOUT 3 - -//callbackfunction, called if configuration is finished -typedef void (* tfpEplCfgMaCb)(unsigned int uiNodeId_p, - tEplKernel Errorstate_p); - -//State for configuartion manager Statemachine -typedef enum { - // general states - kEplCfgMaIdle = 0x0000, // Configurationsprocess - // is idle - kEplCfgMaWaitForSdocEvent = 0x0001, // wait until the last - // SDOC is finisched - kEplCfgMaSkipMappingSub0 = 0x0002, // write Sub0 of mapping - // parameter with 0 - - kEplCfgMaFinished = 0x0004 // configuartion is finished -} tEplCfgState; - -typedef enum { - kEplCfgMaDcfTypSystecSeg = 0x00, - kEplCfgMaDcfTypConDcf = 0x01, - kEplCfgMaDcfTypDcf = 0x02, // not supported - kEplCfgMaDcfTypXdc = 0x03 // not supported -} tEplCfgMaDcfTyp; - -typedef enum { - kEplCfgMaCommon = 0, // all other index - kEplCfgMaPdoComm = 1, // communication index - kEplCfgMaPdoMapp = 2, // mapping index - kEplCfgMaPdoCommAfterMapp = 3, // write PDO Cob-Id after mapping subindex 0(set PDO valid) - -} tEplCfgMaIndexType; - -//bitcoded answer about the last sdo transfer saved in m_SdocState -// also used to singal start of the State Maschine -typedef enum { - kEplCfgMaSdocBusy = 0x00, // SDOC activ - kEplCfgMaSdocReady = 0x01, // SDOC finished - kEplCfgMaSdocTimeout = 0x02, // SDOC Timeout - kEplCfgMaSdocAbortReceived = 0x04, // SDOC Abort, see Abortcode - kEplCfgMaSdocStart = 0x08 // start State Mschine -} tEplSdocState; - -//internal structure (instancetable for modul configuration manager) -typedef struct { - tEplCfgState m_CfgState; // state of the configuration state maschine - tEplSdoComConHdl m_SdoComConHdl; // handle for sdo connection - u32 m_dwLastAbortCode; - unsigned int m_uiLastIndex; // last index of configuration, to compair with actual index - u8 *m_pbConcise; // Ptr to concise DCF - u8 *m_pbActualIndex; // Ptr to actual index in the DCF segment - tfpEplCfgMaCb m_pfnCfgMaCb; // Ptr to CfgMa Callback, is call if configuration finished - tEplKernel m_EplKernelError; // errorcode - u32 m_dwNumValueCopy; // numeric values are copied in this variable - unsigned int m_uiPdoNodeId; // buffer for PDO node id - u8 m_bNrOfMappedObject; // number of mapped objects - unsigned int m_uiNodeId; // Epl node addresse - tEplSdocState m_SdocState; // bitcoded state of the SDO transfer - unsigned int m_uiLastSubIndex; // last subindex of configuration - BOOL m_fOneTranferOk; // atleased one transfer was successful - u8 m_bEventFlag; // for Eventsignaling to the State Maschine - u32 m_dwCntObjectInDcf; // number of Objects in DCF - tEplCfgMaIndexType m_SkipCfg; // TRUE if a adsitional Configurationprocess - // have to insert e.g. PDO-mapping - u16 m_wTimeOutCnt; // Timeout Counter, break configuration is - // m_wTimeOutCnt == CFGMA_MAX_TIMEOUT - -} tEplCfgMaNode; - -//--------------------------------------------------------------------------- -// Function: EplCfgMaInit() -// -// Description: Function creates first instance of Configuration Manager -// -// Parameters: -// -// Returns: tEplKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaInit(void); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaAddInstance() -// -// Description: Function creates additional instance of Configuration Manager -// -// Parameters: -// -// Returns: tEplKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaAddInstance(void); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaDelInstance() -// -// Description: Function delete instance of Configuration Manager -// -// Parameters: -// -// Returns: tEplKernel = error code -//--------------------------------------------------------------------------- -tEplKernel plCfgMaDelInstance(void); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaStartConfig() -// -// Description: Function starts the configuration process -// initialization the statemachine for CfgMa- process -// -// Parameters: uiNodeId_p = NodeId of the node to configure -// pbConcise_p = pointer to DCF -// fpCfgMaCb_p = pointer to callback function (should not be NULL) -// SizeOfConcise_p = size of DCF in u8 -> for future use -// DcfType_p = type of the DCF -// -// Returns: tCopKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaStartConfig(unsigned int uiNodeId_p, - u8 * pbConcise_p, - tfpEplCfgMaCb fpCfgMaCb_p, - tEplObdSize SizeOfConcise_p, - tEplCfgMaDcfTyp DcfType_p); - -//--------------------------------------------------------------------------- -// Function: CfgMaStartConfigurationNode() -// -// Description: Function started the configuration process -// with the DCF from according OD-entry Subindex == bNodeId_p -// -// Parameters: uiNodeId_p = NodeId of the node to configure -// fpCfgMaCb_p = pointer to callback function (should not be NULL) -// DcfType_p = type of the DCF -// -// Returns: tCopKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaStartConfigNode(unsigned int uiNodeId_p, - tfpEplCfgMaCb fpCfgMaCb_p, - tEplCfgMaDcfTyp DcfType_p); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaStartConfigNodeDcf() -// -// Description: Function starts the configuration process -// and links the configuration data to the OD -// -// Parameters: uiNodeId_p = NodeId of the node to configure -// pbConcise_p = pointer to DCF -// fpCfgMaCb_p = pointer to callback function (should not be NULL) -// SizeOfConcise_p = size of DCF in u8 -> for future use -// DcfType_p = type of the DCF -// -// Returns: tCopKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p, - u8 * pbConcise_p, - tfpEplCfgMaCb fpCfgMaCb_p, - tEplObdSize SizeOfConcise_p, - tEplCfgMaDcfTyp DcfType_p); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaLinkDcf() -// -// Description: Function links the configuration data to the OD -// -// Parameters: uiNodeId_p = NodeId of the node to configure -// pbConcise_p = pointer to DCF -// SizeOfConcise_p = size of DCF in u8 -> for future use -// DcfType_p = type of the DCF -// -// Returns: tCopKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaLinkDcf(unsigned int uiNodeId_p, - u8 * pbConcise_p, - tEplObdSize SizeOfConcise_p, - tEplCfgMaDcfTyp DcfType_p); - -//--------------------------------------------------------------------------- -// Function: EplCfgMaCheckDcf() -// -// Description: Function check if there is allready a configuration file linked -// to the OD (type is given by DcfType_p) -// -// Parameters: uiNodeId_p = NodeId -// DcfType_p = type of the DCF -// -// Returns: tCopKernel = error code -//--------------------------------------------------------------------------- -tEplKernel EplCfgMaCheckDcf(unsigned int uiNodeId_p, tEplCfgMaDcfTyp DcfType_p); - -#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0) - -#endif // _EPLCFGMA_H_ - -// EOF diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h deleted file mode 100644 index 890f83759ca..00000000000 --- a/drivers/staging/epl/user/EplDllu.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for userspace DLL module for asynchronous communication - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDllu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLLU_H_ -#define _EPL_DLLU_H_ - -#include "../EplDll.h" - -typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - -tEplKernel EplDlluAddInstance(void); - -tEplKernel EplDlluDelInstance(void); - -tEplKernel EplDlluRegAsndService(tEplDllAsndServiceId ServiceId_p, - tEplDlluCbAsnd pfnDlluCbAsnd_p, - tEplDllAsndFilter Filter_p); - -tEplKernel EplDlluAsyncSend(tEplFrameInfo * pFrameInfo_p, - tEplDllAsyncReqPriority Priority_p); - -// processes asynch frames -tEplKernel EplDlluProcess(tEplFrameInfo * pFrameInfo_p); - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) - -#endif // #ifndef _EPL_DLLU_H_ diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h deleted file mode 100644 index bc9126b1627..00000000000 --- a/drivers/staging/epl/user/EplDlluCal.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for DLL Communication Abstraction Layer module in EPL user part - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplDlluCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/20 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_DLLUCAL_H_ -#define _EPL_DLLUCAL_H_ - -#include "../EplDll.h" -#include "../EplEvent.h" - - -typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p); - -tEplKernel EplDlluCalAddInstance(void); - -tEplKernel EplDlluCalDelInstance(void); - -tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p, - tEplDlluCbAsnd pfnDlluCbAsnd_p, - tEplDllAsndFilter Filter_p); - -tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo, - tEplDllAsyncReqPriority Priority_p); - -tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p); - -tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p); - -tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p); - -tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p, - unsigned int uiNodeId_p, u8 bSoaFlag1_p); - -#endif - -#endif // #ifndef _EPL_DLLUCAL_H_ diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h deleted file mode 100644 index ab85205b239..00000000000 --- a/drivers/staging/epl/user/EplEventu.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for kernel event module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplEventu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/12 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_EVENTU_H_ -#define _EPL_EVENTU_H_ - -#include "../EplEvent.h" - -// init function -tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p); - -// add instance -tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p); - -// delete instance -tEplKernel EplEventuDelInstance(void); - -// Task that dispatches events in userspace -tEplKernel EplEventuProcess(tEplEvent * pEvent_p); - -// post events from userspace -tEplKernel EplEventuPost(tEplEvent * pEvent_p); - -// post errorevents from userspace -tEplKernel EplEventuPostError(tEplEventSource EventSource_p, - tEplKernel EplError_p, - unsigned int uiArgSize_p, void *pArg_p); - -#endif // #ifndef _EPL_EVENTU_H_ diff --git a/drivers/staging/epl/user/EplIdentu.h b/drivers/staging/epl/user/EplIdentu.h deleted file mode 100644 index 057c9029e98..00000000000 --- a/drivers/staging/epl/user/EplIdentu.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Identu-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplIdentu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/11/15 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLIDENTU_H_ -#define _EPLIDENTU_H_ - -#include "../EplDll.h" - -typedef tEplKernel(* tEplIdentuCbResponse) (unsigned int uiNodeId_p, - tEplIdentResponse * - pIdentResponse_p); - -tEplKernel EplIdentuInit(void); - -tEplKernel EplIdentuAddInstance(void); - -tEplKernel EplIdentuDelInstance(void); - -tEplKernel EplIdentuReset(void); - -tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p, - tEplIdentResponse **ppIdentResponse_p); - -tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p, - tEplIdentuCbResponse pfnCbResponse_p); - -#endif // #ifndef _EPLIDENTU_H_ diff --git a/drivers/staging/epl/user/EplLedu.h b/drivers/staging/epl/user/EplLedu.h deleted file mode 100644 index ca9eb431100..00000000000 --- a/drivers/staging/epl/user/EplLedu.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for status and error LED user part module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplLedu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.1 $ $Date: 2008/11/17 16:40:39 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2008/11/17 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLLEDU_H_ -#define _EPLLEDU_H_ - -#include "../EplLed.h" -#include "../EplNmt.h" -#include "EplEventu.h" - -typedef tEplKernel(* tEplLeduStateChangeCallback) (tEplLedType LedType_p, - BOOL fOn_p); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - -tEplKernel EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p); - -tEplKernel EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p); - -tEplKernel EplLeduDelInstance(void); - -tEplKernel EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p); - -tEplKernel EplLeduProcessEvent(tEplEvent * pEplEvent_p); - -#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) - -#endif // #ifndef _EPLLEDU_H_ diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h deleted file mode 100644 index 7d230297f43..00000000000 --- a/drivers/staging/epl/user/EplNmtCnu.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for NMT-CN-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtCnu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMTCNU_H_ -#define _EPLNMTCNU_H_ - -#include "EplNmtu.h" -#include "../EplDll.h" -#include "../EplFrame.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - -tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p); - -tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p); - -tEplKernel EplNmtCnuDelInstance(void); - -tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, tEplNmtCommand NmtCommand_p); - -tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p); - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) - -#endif // #ifndef _EPLNMTCNU_H_ diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h deleted file mode 100644 index 5e5e0cda324..00000000000 --- a/drivers/staging/epl/user/EplNmtMnu.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for NMT-MN-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtMnu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMTMNU_H_ -#define _EPLNMTMNU_H_ - -#include "EplNmtu.h" - -typedef tEplKernel(* tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p, - tEplNmtNodeEvent NodeEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p, - BOOL fMandatory_p); - -typedef tEplKernel(* tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p, - tEplNmtState NmtState_p, - u16 wErrorCode_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) - -tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p, - tEplNmtMnuCbBootEvent pfnCbBootEvent_p); - -tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p, - tEplNmtMnuCbBootEvent pfnCbBootEvent_p); - -tEplKernel EplNmtMnuDelInstance(void); - -tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p); - -tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p, - tEplNmtCommand NmtCommand_p); - -tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p, - tEplNmtNodeCommand NodeCommand_p); - -tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange - NmtStateChange_p); - -tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p); - -tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int - *puiMandatorySlaveCount_p, - unsigned int - *puiSignalSlaveCount_p, - u16 * pwFlags_p); - -#endif - -#endif // #ifndef _EPLNMTMNU_H_ diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h deleted file mode 100644 index c1fca80f5a0..00000000000 --- a/drivers/staging/epl/user/EplNmtu.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for NMT-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/09 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMTU_H_ -#define _EPLNMTU_H_ - -#include "../EplNmt.h" -#include "EplEventu.h" - -// nmt commands -typedef enum { - // requestable ASnd ServiceIds 0x01..0x1F - kEplNmtCmdIdentResponse = 0x01, - kEplNmtCmdStatusResponse = 0x02, - // plain NMT state commands 0x20..0x3F - kEplNmtCmdStartNode = 0x21, - kEplNmtCmdStopNode = 0x22, - kEplNmtCmdEnterPreOperational2 = 0x23, - kEplNmtCmdEnableReadyToOperate = 0x24, - kEplNmtCmdResetNode = 0x28, - kEplNmtCmdResetCommunication = 0x29, - kEplNmtCmdResetConfiguration = 0x2A, - kEplNmtCmdSwReset = 0x2B, - // extended NMT state commands 0x40..0x5F - kEplNmtCmdStartNodeEx = 0x41, - kEplNmtCmdStopNodeEx = 0x42, - kEplNmtCmdEnterPreOperational2Ex = 0x43, - kEplNmtCmdEnableReadyToOperateEx = 0x44, - kEplNmtCmdResetNodeEx = 0x48, - kEplNmtCmdResetCommunicationEx = 0x49, - kEplNmtCmdResetConfigurationEx = 0x4A, - kEplNmtCmdSwResetEx = 0x4B, - // NMT managing commands 0x60..0x7F - kEplNmtCmdNetHostNameSet = 0x62, - kEplNmtCmdFlushArpEntry = 0x63, - // NMT info services 0x80..0xBF - kEplNmtCmdPublishConfiguredCN = 0x80, - kEplNmtCmdPublishActiveCN = 0x90, - kEplNmtCmdPublishPreOperational1 = 0x91, - kEplNmtCmdPublishPreOperational2 = 0x92, - kEplNmtCmdPublishReadyToOperate = 0x93, - kEplNmtCmdPublishOperational = 0x94, - kEplNmtCmdPublishStopped = 0x95, - kEplNmtCmdPublishEmergencyNew = 0xA0, - kEplNmtCmdPublishTime = 0xB0, - - kEplNmtCmdInvalidService = 0xFF -} tEplNmtCommand; - -typedef tEplKernel(* tEplNmtuStateChangeCallback) (tEplEventNmtStateChange NmtStateChange_p); - -typedef tEplKernel(* tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - -tEplKernel EplNmtuInit(void); - -tEplKernel EplNmtuAddInstance(void); - -tEplKernel EplNmtuDelInstance(void); - -tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p); - -tEplNmtState EplNmtuGetNmtState(void); - -tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p); - -tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p); - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) - -#endif // #ifndef _EPLNMTU_H_ diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h deleted file mode 100644 index b9850372a4a..00000000000 --- a/drivers/staging/epl/user/EplNmtuCal.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for communication abstraction layer of the - NMT-Userspace-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplNmtuCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/16 -k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLNMTUCAL_H_ -#define _EPLNMTUCAL_H_ - -#include "EplNmtu.h" -#include "../kernel/EplNmtk.h" - -tEplNmtState EplNmtkCalGetNmtState(void); - -#endif // #ifndef _EPLNMTUCAL_H_ diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h deleted file mode 100644 index 086371276cf..00000000000 --- a/drivers/staging/epl/user/EplObdu.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Epl-Obd-Userspace-module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObdu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLOBDU_H_ -#define _EPLOBDU_H_ - -#include "../EplObd.h" - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - -#if EPL_OBD_USE_KERNEL != FALSE -#error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE" -#endif - -tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduReadEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p); - -// --------------------------------------------------------------------- -void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p); - -// --------------------------------------------------------------------- -void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, - tEplObdSize ObdSize_p); - -// --------------------------------------------------------------------- -tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, - unsigned int uiSubIndex_p); - -// --------------------------------------------------------------------- -unsigned int EplObduGetNodeId(void); - -// --------------------------------------------------------------------- -tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, - tEplObdNodeIdType NodeIdType_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduGetAccessType(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p); -// --------------------------------------------------------------------- -tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, tEplObdSize *pSize_p); -// --------------------------------------------------------------------- -tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, tEplObdSize Size_p); - -// --------------------------------------------------------------------- -tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p); - -#elif EPL_OBD_USE_KERNEL != FALSE -#include "../kernel/EplObdk.h" - -#define EplObduWriteEntry EplObdWriteEntry - -#define EplObduReadEntry EplObdReadEntry - -#define EplObduAccessOdPart EplObdAccessOdPart - -#define EplObduDefineVar EplObdDefineVar - -#define EplObduGetObjectDataPtr EplObdGetObjectDataPtr - -#define EplObduRegisterUserOd EplObdRegisterUserOd - -#define EplObduInitVarEntry EplObdInitVarEntry - -#define EplObduGetDataSize EplObdGetDataSize - -#define EplObduGetNodeId EplObdGetNodeId - -#define EplObduSetNodeId EplObdSetNodeId - -#define EplObduGetAccessType EplObdGetAccessType - -#define EplObduReadEntryToLe EplObdReadEntryToLe - -#define EplObduWriteEntryFromLe EplObdWriteEntryFromLe - -#define EplObduSearchVarEntry EplObdSearchVarEntry - -#define EplObduIsNumerical EplObdIsNumerical - -#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) - -#endif // #ifndef _EPLOBDU_H_ diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h deleted file mode 100644 index 07277777219..00000000000 --- a/drivers/staging/epl/user/EplObduCal.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for communication abstraction layer - for the Epl-Obd-Userspace-Modul - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplObduCal.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/19 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLOBDUCAL_H_ -#define _EPLOBDUCAL_H_ - -#include "../EplObd.h" - -tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - tEplObdSize Size_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, - tEplObdDir Direction_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p); -//--------------------------------------------------------------------------- -void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, - unsigned int uiSubIndex_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p); -//--------------------------------------------------------------------------- -void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p, - u8 bType_p, tEplObdSize ObdSize_p); -//--------------------------------------------------------------------------- -tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p, - unsigned int uiSubIndex_p); -//--------------------------------------------------------------------------- -unsigned int EplObduCalGetNodeId(void); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p, - tEplObdNodeIdType NodeIdType_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - tEplObdAccess *pAccessTyp_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pDstData_p, - tEplObdSize *pSize_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p, - unsigned int uiSubIndex_p, - void *pSrcData_p, - tEplObdSize Size_p); -//--------------------------------------------------------------------------- -tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, - unsigned int uiSubindex_p, - tEplObdVarEntry **ppVarEntry_p); - -#endif // #ifndef _EPLOBDUCAL_H_ diff --git a/drivers/staging/epl/user/EplPdou.h b/drivers/staging/epl/user/EplPdou.h deleted file mode 100644 index b8c832b09db..00000000000 --- a/drivers/staging/epl/user/EplPdou.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for userspace PDO module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplPdou.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/11/19 17:14:38 $ - - $State: Exp $ - - Build Environment: - - ------------------------------------------------------------------------- - - Revision History: - - 2006/05/22 d.k.: start of the implementation, version 1.00 - -****************************************************************************/ - -#ifndef _EPL_PDOU_H_ -#define _EPL_PDOU_H_ - -#include "../EplPdo.h" - -tEplKernel EplPdouAddInstance(void); - -tEplKernel EplPdouDelInstance(void); - -#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0) -tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p); -#else -#define EplPdouCbObdAccess NULL -#endif - -// returns error if bPdoId_p is already valid -/* -tEplKernel EplPdouSetMapping( - u8 bPdoId_p, BOOL fTxRx_p, u8 bNodeId, u8 bMappingVersion, - tEplPdoMapping * pMapping_p, u8 bMaxEntries_p); - -tEplKernel EplPdouGetMapping( - u8 bPdoId_p, BOOL fTxRx_p, u8 * pbNodeId, u8 * pbMappingVersion, - tEplPdoMapping * pMapping_p, u8 * pbMaxEntries_p); -*/ - -#endif // #ifndef _EPL_PDOU_H_ diff --git a/drivers/staging/epl/user/EplSdoAsndu.h b/drivers/staging/epl/user/EplSdoAsndu.h deleted file mode 100644 index a62d4c97870..00000000000 --- a/drivers/staging/epl/user/EplSdoAsndu.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for SDO/Asnd-Protocolabstractionlayer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoAsndu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/07 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLSDOASNDU_H_ -#define _EPLSDOASNDU_H_ - -#include "../EplSdo.h" -#include "../EplDll.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - -tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p); - -tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p); - -tEplKernel EplSdoAsnduDelInstance(void); - -tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p, - unsigned int uiTargetNodeId_p); - -tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p, - tEplFrame *pSrcData_p, - u32 dwDataSize_p); - -tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p); - -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0) - -#endif // #ifndef _EPLSDOASNDU_H_ diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h deleted file mode 100644 index cc862de1a5b..00000000000 --- a/drivers/staging/epl/user/EplSdoAsySequ.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for asychrionus SDO Sequence Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoAsySequ.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLSDOASYSEQU_H_ -#define _EPLSDOASYSEQU_H_ - -#include "../EplSdo.h" -#include "EplSdoUdpu.h" -#include "EplSdoAsndu.h" -#include "../EplEvent.h" -#include "EplTimeru.h" - -tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p); - -tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p, - tEplSdoComConCb fpSdoComConCb_p); - -tEplKernel EplSdoAsySeqDelInstance(void); - -tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p, - unsigned int uiNodeId_p, - tEplSdoType SdoType); - -tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p, - unsigned int uiDataSize_p, - tEplFrame *pData_p); - -tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p); - -tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p); - -#endif // #ifndef _EPLSDOASYSEQU_H_ diff --git a/drivers/staging/epl/user/EplSdoComu.h b/drivers/staging/epl/user/EplSdoComu.h deleted file mode 100644 index 4eee6fa6974..00000000000 --- a/drivers/staging/epl/user/EplSdoComu.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for SDO Command Layer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoComu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLSDOCOMU_H_ -#define _EPLSDOCOMU_H_ - -#include "../EplSdo.h" -#include "../EplObd.h" -#include "../EplSdoAc.h" -#include "EplObdu.h" -#include "EplSdoAsySequ.h" - -tEplKernel EplSdoComInit(void); - -tEplKernel EplSdoComAddInstance(void); - -tEplKernel EplSdoComDelInstance(void); - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) - -tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p, - unsigned int uiTargetNodeId_p, - tEplSdoType ProtType_p); - -tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p); - -tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p); - -tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p, - tEplSdoComFinished *pSdoComFinished_p); - -tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p, - u32 dwAbortCode_p); - -#endif - -// for future extention -/* -tEplKernel EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p); - -tEplKernel EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p); - -tEplKernel EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p); - -*/ - -#endif // #ifndef _EPLSDOCOMU_H_ diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h deleted file mode 100644 index 13e2a278c11..00000000000 --- a/drivers/staging/epl/user/EplSdoUdpu.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for SDO/UDP-Protocollabstractionlayer module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplSdoUdpu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/10/17 15:32:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/06/26 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLSDOUDPU_H_ -#define _EPLSDOUDPU_H_ - -#include "../EplSdo.h" - -#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - -tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p); - -tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p); - -tEplKernel EplSdoUdpuDelInstance(void); - -tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, - unsigned int uiPort_p); - -tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p, - unsigned int uiTargetNodeId_p); - -tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p, - tEplFrame *pSrcData_p, u32 dwDataSize_p); - -tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p); - -#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) - -#endif // #ifndef _EPLSDOUDPU_H_ diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h deleted file mode 100644 index 0fd3ebb76dc..00000000000 --- a/drivers/staging/epl/user/EplStatusu.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Statusu-Module - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplStatusu.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/11/15 d.k.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLSTATUSU_H_ -#define _EPLSTATUSU_H_ - -#include "../EplDll.h" - -typedef tEplKernel(* tEplStatusuCbResponse) (unsigned int uiNodeId_p, - tEplStatusResponse *pStatusResponse_p); - -tEplKernel EplStatusuInit(void); - -tEplKernel EplStatusuAddInstance(void); - -tEplKernel EplStatusuDelInstance(void); - -tEplKernel EplStatusuReset(void); - -tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p, - tEplStatusuCbResponse pfnCbResponse_p); - -#endif // #ifndef _EPLSTATUSU_H_ diff --git a/drivers/staging/epl/user/EplTimeru.h b/drivers/staging/epl/user/EplTimeru.h deleted file mode 100644 index 5c447485245..00000000000 --- a/drivers/staging/epl/user/EplTimeru.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: include file for Epl Userspace-Timermodule - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimeru.h,v $ - - $Author: D.Krueger $ - - $Revision: 1.5 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/06 k.t.: start of the implementation - -****************************************************************************/ - -#ifndef _EPLTIMERU_H_ -#define _EPLTIMERU_H_ - -#include "../EplTimer.h" -#include "EplEventu.h" - -tEplKernel EplTimeruInit(void); - -tEplKernel EplTimeruAddInstance(void); - -tEplKernel EplTimeruDelInstance(void); - -tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p); - -tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p); - -tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p); - -BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p); - -#endif // #ifndef _EPLTIMERU_H_ -- cgit v1.2.3 From 249c033c29ed4eccd24b52959747f2663deaa02f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 29 Jul 2009 06:54:11 -0700 Subject: Staging: pata_rdc: remove the driver from the staging tree Now that a "real" driver is in the libata tree for this hardware, we need to remove the staging driver as it is no longer needed. Cc: Kevin Huang Cc: Tomy Wang Cc: Alan Cox Cc: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/pata_rdc/Kconfig | 6 - drivers/staging/pata_rdc/Makefile | 2 - drivers/staging/pata_rdc/pata_rdc.c | 955 ------------------------------------ drivers/staging/pata_rdc/pata_rdc.h | 144 ------ 6 files changed, 1110 deletions(-) delete mode 100644 drivers/staging/pata_rdc/Kconfig delete mode 100644 drivers/staging/pata_rdc/Makefile delete mode 100644 drivers/staging/pata_rdc/pata_rdc.c delete mode 100644 drivers/staging/pata_rdc/pata_rdc.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 7b500a88060..979de8fb32c 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -129,8 +129,6 @@ source "drivers/staging/vt6656/Kconfig" source "drivers/staging/cpc-usb/Kconfig" -source "drivers/staging/pata_rdc/Kconfig" - source "drivers/staging/udlfb/Kconfig" source "drivers/staging/hv/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 1ac7c8f23d0..c80d05006dc 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -46,7 +46,6 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_USB_CPC) += cpc-usb/ -obj-$(CONFIG_RDC_17F3101X) += pata_rdc/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ diff --git a/drivers/staging/pata_rdc/Kconfig b/drivers/staging/pata_rdc/Kconfig deleted file mode 100644 index 7a406b02305..00000000000 --- a/drivers/staging/pata_rdc/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config RDC_17F3101X - tristate "RDC_17F3101X IDE support" - depends on PCI && ATA && ATA_SFF - ---help--- - This is an experimental driver for RDC_17F31011 and - RDC_17F31012 IDE driver. diff --git a/drivers/staging/pata_rdc/Makefile b/drivers/staging/pata_rdc/Makefile deleted file mode 100644 index f952c16f4b2..00000000000 --- a/drivers/staging/pata_rdc/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_RDC_17F3101X) += pata_rdc.o - diff --git a/drivers/staging/pata_rdc/pata_rdc.c b/drivers/staging/pata_rdc/pata_rdc.c deleted file mode 100644 index 6252745250e..00000000000 --- a/drivers/staging/pata_rdc/pata_rdc.c +++ /dev/null @@ -1,955 +0,0 @@ -#include -#include -#include - -#include -#include - -#include -#include - -#include "pata_rdc.h" - -static const struct pci_device_id rdc_pata_id_table[] = { - { PCI_DEVICE(0x17F3, 0x1011), RDC_17F31011}, - { PCI_DEVICE(0x17F3, 0x1012), RDC_17F31012}, - { } /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, rdc_pata_id_table); - -/* see ATA Host Adapters Standards. */ -static struct pci_bits ATA_Decode_Enable_Bits[] = { - { 0x41U, 1U, 0x80UL, 0x80UL }, /* port (Channel) 0 */ - { 0x43U, 1U, 0x80UL, 0x80UL }, /* port (Channel) 1 */ -}; - -static uint PCIDeviceIO_ReadPCIConfiguration(struct pci_dev *pdev, uint Offset, uint Length, void *pBuffer) -{ - uint funcresult; - unchar *pchar; - uint i; - - funcresult = TRUE; - - pchar = pBuffer; - - for (i = 0; i < Length; i++) { - pci_read_config_byte(pdev, Offset, pchar); - Offset++; - pchar++; - } - - funcresult = TRUE; - - goto funcexit; -funcexit: - - return funcresult; -} - -static uint PCIDeviceIO_WritePCIConfiguration(struct pci_dev *pdev, uint Offset, uint Length, void *pBuffer) -{ - uint funcresult; - unchar *pchar; - uint i; - - funcresult = TRUE; - - pchar = pBuffer; - - for (i = 0; i < Length; i++) { - pci_write_config_byte(pdev, Offset, *pchar); - Offset++; - pchar++; - } - - funcresult = TRUE; - - goto funcexit; -funcexit: - - return funcresult; -} - -static uint ATAHostAdapter_SetPrimaryPIO(struct pci_dev *pdev, uint DeviceID, - uint PIOTimingMode, uint DMAEnable, - uint PrefetchPostingEnable) -{ - uint funcresult; - uint result; - uint ATATimingRegister; - uint Device1TimingRegister; - - funcresult = TRUE; - - ATATimingRegister = 0; - Device1TimingRegister = 0; - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_PrimaryTiming_Size, - &ATATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_Device1Timing_Size, - &Device1TimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable; - - switch (DeviceID) { - case 0: - /* mask clear */ - ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable | - ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable | - ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable | - ATAConfiguration_PrimaryTiming_Device0DMATimingEnable | - ATAConfiguration_PrimaryTiming_Device0RecoveryMode | - ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode); - - if (PIOTimingMode > PIO0) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable; - - if (PIOTimingMode >= PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable; - - if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable; - - if (DMAEnable == TRUE && PIOTimingMode >= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable; - - if (PIOTimingMode <= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0; - else if (PIOTimingMode == PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1; - else if (PIOTimingMode == PIO4) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3; - - if (PIOTimingMode <= PIO1) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0; - else if (PIOTimingMode == PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1; - else if (PIOTimingMode <= PIO4) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2; - break; - case 1: - ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable | - ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable | - ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable | - ATAConfiguration_PrimaryTiming_Device1DMATimingEnable); - - if (PIOTimingMode > PIO0) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable; - - if (PIOTimingMode >= PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable; - - if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable; - - if (DMAEnable == TRUE && PIOTimingMode >= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable; - - Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_PrimaryRecoveryMode | - ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode); - - if (PIOTimingMode <= PIO2) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0; - else if (PIOTimingMode == PIO3) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1; - else if (PIOTimingMode == PIO4) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3; - - if (PIOTimingMode <= PIO1) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0; - else if (PIOTimingMode == PIO2) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1; - else if (PIOTimingMode <= PIO4) - Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2; - break; - default: - funcresult = FALSE; - goto funcexit; - break; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_PrimaryTiming_Size, - &ATATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_Device1Timing_Size, - &Device1TimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - goto funcexit; -funcexit: - - return funcresult; -} - -static uint ATAHostAdapter_SetSecondaryPIO(struct pci_dev *pdev, uint DeviceID, - uint PIOTimingMode, uint DMAEnable, - uint PrefetchPostingEnable) -{ - uint funcresult; - uint result; - uint ATATimingRegister; - uint Device1TimingRegister; - - funcresult = TRUE; - - ATATimingRegister = 0; - Device1TimingRegister = 0; - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_SecondaryTiming_Size, - &ATATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_Device1Timing_Size, - &Device1TimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable; - - switch (DeviceID) { - case 0: - /* mask clear */ - ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable | - ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable | - ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable | - ATAConfiguration_PrimaryTiming_Device0DMATimingEnable | - ATAConfiguration_PrimaryTiming_Device0RecoveryMode | - ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode); - - if (PIOTimingMode > PIO0) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable; - - if (PIOTimingMode >= PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable; - - if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable; - - if (DMAEnable == TRUE && PIOTimingMode >= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable; - - if (PIOTimingMode <= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0; - else if (PIOTimingMode == PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1; - else if (PIOTimingMode == PIO4) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3; - - if (PIOTimingMode <= PIO1) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0; - else if (PIOTimingMode == PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1; - else if (PIOTimingMode <= PIO4) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2; - break; - case 1: - ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable | - ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable | - ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable | - ATAConfiguration_PrimaryTiming_Device1DMATimingEnable); - - if (PIOTimingMode > PIO0) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable; - - if (PIOTimingMode >= PIO3) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable; - - if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable; - - if (DMAEnable == TRUE && PIOTimingMode >= PIO2) - ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable; - - Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_SecondaryRecoveryMode | - ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode); - - if (PIOTimingMode <= PIO2) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0; - else if (PIOTimingMode == PIO3) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1; - else if (PIOTimingMode == PIO4) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3; - - if (PIOTimingMode <= PIO1) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0; - else if (PIOTimingMode == PIO2) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1; - else if (PIOTimingMode <= PIO4) - Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2; - break; - default: - funcresult = FALSE; - goto funcexit; - break; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_SecondaryTiming_Size, - &ATATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_Device1Timing_Size, - &Device1TimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - goto funcexit; -funcexit: - return funcresult; -} - -static uint ATAHostAdapter_SetPrimaryUDMA(struct pci_dev *pdev, uint DeviceID, - uint UDMAEnable, uint UDMATimingMode) -{ - uint funcresult; - uint result; - uint UDMAControlRegister; - uint UDMATimingRegister; - ulong IDEIOConfigurationRegister; - - funcresult = TRUE; - UDMAControlRegister = 0; - UDMATimingRegister = 0; - IDEIOConfigurationRegister = 0; - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMAControl_Size, - &UDMAControlRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMATiming_Size, - &UDMATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_IDEIOConfiguration_Size, - &IDEIOConfigurationRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - /*Rom Code will determine the device cable type and ATA 100.*/ - /*IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report;*/ - /*IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported;*/ - - switch (DeviceID) { - case 0: - UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable); - if (UDMAEnable == TRUE) - UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable; - - IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable | - ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable); - - if (UDMATimingMode >= UDMA5) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable; - else if (UDMATimingMode >= UDMA3) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable; - - /* if 80 cable report */ - UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime); - - if (UDMATimingMode == UDMA0) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0; - } else if (UDMATimingMode == UDMA1 || - UDMATimingMode == UDMA3 || - UDMATimingMode == UDMA5) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1; - } else if (UDMATimingMode == UDMA2 || - UDMATimingMode == UDMA4) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2; - } - break; - case 1: - UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable); - if (UDMAEnable == TRUE) - UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable; - - IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable | - ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable); - - if (UDMATimingMode >= UDMA5) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable; - else if (UDMATimingMode >= UDMA3) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable; - - /* if 80 cable report */ - UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime); - - if (UDMATimingMode == UDMA0) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0; - } else if (UDMATimingMode == UDMA1 || - UDMATimingMode == UDMA3 || - UDMATimingMode == UDMA5) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1; - } else if (UDMATimingMode == UDMA2 || - UDMATimingMode == UDMA4) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2; - } - break; - default: - funcresult = FALSE; - goto funcexit; - break; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMAControl_Size, - &UDMAControlRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMATiming_Size, - &UDMATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_IDEIOConfiguration_Size, - &IDEIOConfigurationRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - goto funcexit; -funcexit: - return funcresult; -} - -static uint ATAHostAdapter_SetSecondaryUDMA(struct pci_dev *pdev, uint DeviceID, - uint UDMAEnable, uint UDMATimingMode) -{ - uint funcresult; - uint result; - uint UDMAControlRegister; - uint UDMATimingRegister; - ulong IDEIOConfigurationRegister; - - funcresult = TRUE; - - UDMAControlRegister = 0; - UDMATimingRegister = 0; - IDEIOConfigurationRegister = 0; - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMAControl_Size, - &UDMAControlRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMATiming_Size, - &UDMATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_ReadPCIConfiguration(pdev, - ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_IDEIOConfiguration_Size, - &IDEIOConfigurationRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - /* Rom Code will determine the device cable type and ATA 100. */ - /* IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report; */ - /* IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported; */ - - switch (DeviceID) { - case 0: - UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable); - if (UDMAEnable == TRUE) - UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable; - - IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable | - ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable); - - if (UDMATimingMode >= UDMA5) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable; - else if (UDMATimingMode >= UDMA3) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable; - - /* if 80 cable report */ - UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime); - - if (UDMATimingMode == UDMA0) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0; - } else if (UDMATimingMode == UDMA1 || - UDMATimingMode == UDMA3 || - UDMATimingMode == UDMA5) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1; - } else if (UDMATimingMode == UDMA2 || - UDMATimingMode == UDMA4) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2; - } - break; - case 1: - UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable); - if (UDMAEnable == TRUE) - UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable; - - IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable | - ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable); - - if (UDMATimingMode >= UDMA5) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable; - else if (UDMATimingMode >= UDMA3) - IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable; - - /* if 80 cable report */ - UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime); - - if (UDMATimingMode == UDMA0) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0; - } else if (UDMATimingMode == UDMA1 || - UDMATimingMode == UDMA3 || - UDMATimingMode == UDMA5) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1; - } else if (UDMATimingMode == UDMA2 || - UDMATimingMode == UDMA4) { - UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2; - } - break; - default: - funcresult = FALSE; - goto funcexit; - break; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMAControl_Size, - &UDMAControlRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_UDMATiming_Size, - &UDMATimingRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - result = PCIDeviceIO_WritePCIConfiguration(pdev, - ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, - ATAConfiguration_ID_IDEIOConfiguration_Size, - &IDEIOConfigurationRegister); - if (result == FALSE) { - funcresult = FALSE; - goto funcexit; - } - - goto funcexit; -funcexit: - return funcresult; -} - -static int rdc_pata_port_start(struct ata_port *ap) -{ - uint Channel; - - Channel = ap->port_no; - dev_dbg(ap->dev, "%s: Channel: %u\n", __func__, Channel); - if (ap->ioaddr.bmdma_addr) { - return ata_port_start(ap); - } else { - dev_dbg(ap->dev, "%s: return 0!!!\n", __func__); - return 0; - } -} - -static void rdc_pata_port_stop(struct ata_port *ap) -{ - uint Channel; - - Channel = ap->port_no; - - dev_dbg(ap->dev, "%s Channel: %u\n", __func__, Channel); -} - -static int rdc_pata_prereset(struct ata_link *link, unsigned long deadline) -{ - struct pci_dev *pdev; - struct ata_port *ap; - uint Channel; - - dev_dbg(link->ap->dev, "%s\n", __func__); - - ap = link->ap; - pdev = to_pci_dev(ap->host->dev); - - Channel = ap->port_no; - - /* test ATA Decode Enable Bits, should be enable. */ - if (!pci_test_config_bits(pdev, &ATA_Decode_Enable_Bits[Channel])) { - dev_dbg(link->ap->dev, "%s: Channel: %u, Decode Disable\n", - __func__, Channel); - return -ENOENT; - } else { - dev_dbg(link->ap->dev, "%s: Channel: %u, Decode Enable\n", - __func__, Channel); - return ata_std_prereset(link, deadline); - } -} - -static int rdc_pata_cable_detect(struct ata_port *ap) -{ - struct pci_dev *pdev; - uint Channel; - uint Mask; - u32 u32Value; - - dev_dbg(ap->dev, "%s\n", __func__); - - pdev = to_pci_dev(ap->host->dev); - - Channel = ap->port_no; - - if (Channel == 0) - Mask = ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report; - else - Mask = ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report; - - /* check BIOS cable detect results */ - pci_read_config_dword(pdev, ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, &u32Value); - - if ((u32Value & Mask) == 0) { - dev_dbg(ap->dev, "%s: Channel: %u, PATA40 \n", - __func__, Channel); - return ATA_CBL_PATA40; - } else { - dev_dbg(ap->dev, "%s: Channel: %u, PATA80 \n", - __func__, Channel); - return ATA_CBL_PATA80; - } -} - -static void rdc_pata_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - struct pci_dev *pdev; - uint Channel; - uint DeviceID; - uint PIOTimingMode; - uint PrefetchPostingEnable; - - dev_dbg(ap->dev, "%s\n", __func__); - - pdev = to_pci_dev(ap->host->dev); - - Channel = ap->port_no; - DeviceID = adev->devno; - /* - * piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1, - * XFER_PIO_2, XFER_PIO_3... - */ - PIOTimingMode = adev->pio_mode - XFER_PIO_0; - - if (adev->class == ATA_DEV_ATA) { - PrefetchPostingEnable = TRUE; - } else { - /* ATAPI, CD DVD Rom */ - PrefetchPostingEnable = FALSE; - } - - /* PIO configuration clears DTE unconditionally. It will be - * programmed in set_dmamode which is guaranteed to be called - * after set_piomode if any DMA mode is available. - */ - - /* Ensure the UDMA bit is off - it will be turned back on if UDMA is - * selected */ - - if (Channel == 0) { - ATAHostAdapter_SetPrimaryPIO( - pdev, - DeviceID, - PIOTimingMode, - TRUE, - PrefetchPostingEnable - ); - - ATAHostAdapter_SetPrimaryUDMA( - pdev, - DeviceID, - FALSE, - UDMA0 - ); - } else { - ATAHostAdapter_SetSecondaryPIO( - pdev, - DeviceID, - PIOTimingMode, - TRUE, - PrefetchPostingEnable - ); - - ATAHostAdapter_SetSecondaryUDMA( - pdev, - DeviceID, - FALSE, - UDMA0 - ); - } - dev_dbg(ap->dev, "%s: Channel: %u, DeviceID: %u, PIO: %d\n", - __func__, Channel, DeviceID, PIOTimingMode); -} - -static void rdc_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - struct pci_dev *pdev; - uint Channel; - uint DeviceID; - uint PIOTimingMode; - uint PrefetchPostingEnable; - uint DMATimingMode; - uint UDMAEnable; - - dev_dbg(ap->dev, "%s\n", __func__); - - pdev = to_pci_dev(ap->host->dev); - - Channel = ap->port_no; - DeviceID = adev->devno; - PIOTimingMode = adev->pio_mode - XFER_PIO_0; /* piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3... */ - DMATimingMode = adev->dma_mode; /* UDMA or MDMA */ - - if (adev->class == ATA_DEV_ATA) { - PrefetchPostingEnable = TRUE; - } else { - /* ATAPI, CD DVD Rom */ - PrefetchPostingEnable = FALSE; - } - - if (ap->udma_mask == 0) { - /* ata_port dont support udma. depend on hardware spec. */ - UDMAEnable = FALSE; - } else { - UDMAEnable = TRUE; - } - - if (Channel == 0) { - if (DMATimingMode >= XFER_UDMA_0) { - /* UDMA */ - ATAHostAdapter_SetPrimaryPIO(pdev, - DeviceID, - PIOTimingMode, - TRUE, - PrefetchPostingEnable); - - ATAHostAdapter_SetPrimaryUDMA(pdev, - DeviceID, - UDMAEnable, - DMATimingMode - XFER_UDMA_0); - dev_dbg(ap->dev, - "%s: Channel: %u, DeviceID: %u, UDMA: %u\n", - __func__, Channel, DeviceID, - (uint)(DMATimingMode - XFER_UDMA_0)); - } else { - /* MDMA */ - ATAHostAdapter_SetPrimaryPIO(pdev, - DeviceID, - (DMATimingMode - XFER_MW_DMA_0) + PIO2, /* MDMA0 = PIO2 */ - TRUE, - PrefetchPostingEnable); - - ATAHostAdapter_SetPrimaryUDMA(pdev, - DeviceID, - FALSE, - UDMA0); - dev_dbg(ap->dev, - "%s: Channel: %u, DeviceID: %u, MDMA: %u\n", - __func__, Channel, DeviceID, - (uint)(DMATimingMode - XFER_MW_DMA_0)); - } - } else { - if (DMATimingMode >= XFER_UDMA_0) { - /* UDMA */ - ATAHostAdapter_SetSecondaryPIO(pdev, - DeviceID, - PIOTimingMode, - TRUE, - PrefetchPostingEnable); - - ATAHostAdapter_SetSecondaryUDMA(pdev, - DeviceID, - UDMAEnable, - DMATimingMode - XFER_UDMA_0); - dev_dbg(ap->dev, - "%s: Channel: %u, DeviceID: %u, UDMA: %u\n", - __func__, Channel, DeviceID, - (uint)(DMATimingMode - XFER_UDMA_0)); - } else { - /* MDMA */ - ATAHostAdapter_SetSecondaryPIO(pdev, - DeviceID, - (DMATimingMode - XFER_MW_DMA_0) + PIO2, /* MDMA0 = PIO2 */ - TRUE, - PrefetchPostingEnable); - - ATAHostAdapter_SetSecondaryUDMA(pdev, - DeviceID, - FALSE, - UDMA0); - dev_dbg(ap->dev, - "%s: Channel: %u, DeviceID: %u, MDMA: %u \n", - __func__, Channel, DeviceID, - (uint)(DMATimingMode - XFER_MW_DMA_0)); - } - } -} - -static struct scsi_host_template rdc_pata_sht = { - ATA_BMDMA_SHT(KBUILD_MODNAME), -}; - -static struct ata_port_operations rdc_pata_ops = { - .inherits = &ata_bmdma_port_ops, - - .port_start = rdc_pata_port_start, - .port_stop = rdc_pata_port_stop, - .prereset = rdc_pata_prereset, - .cable_detect = rdc_pata_cable_detect, - .set_piomode = rdc_pata_set_piomode, - .set_dmamode = rdc_pata_set_dmamode, -}; - -static struct ata_port_info rdc_pata_port_info[] = { - [RDC_17F31011] = { - .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = ATA_UDMA5, /* udma0-5 */ - .port_ops = &rdc_pata_ops, - }, - - [RDC_17F31012] = { - .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = ATA_UDMA5, /* udma0-5 */ - .port_ops = &rdc_pata_ops, - }, -}; - -static int __devinit rdc_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct ata_port_info port_info[2]; - const struct ata_port_info *ppinfo[] = { &port_info[0], &port_info[1] }; - - int rc; - - dev_dbg(&pdev->dev, "%s\n", __func__); - - port_info[0] = rdc_pata_port_info[ent->driver_data]; - port_info[1] = rdc_pata_port_info[ent->driver_data]; - - rc = pci_enable_device(pdev); - if (rc) { - dev_dbg(&pdev->dev, "%s pci_enable_device failed\n", __func__); - return rc; - } - pci_intx(pdev, 1); - - return ata_pci_sff_init_one(pdev, ppinfo, &rdc_pata_sht, NULL); -} - -static struct pci_driver rdc_pata_driver = { - .name = KBUILD_MODNAME, - .id_table = rdc_pata_id_table, - .probe = rdc_init_one, - .remove = ata_pci_remove_one, -#ifdef CONFIG_PM - .suspend = ata_pci_device_suspend, - .resume = ata_pci_device_resume, -#endif -}; - -static int __init pata_rdc_init(void) -{ - return pci_register_driver(&rdc_pata_driver); -} - -static void __exit pata_rdc_exit(void) -{ - pci_unregister_driver(&rdc_pata_driver); -} - -module_init(pata_rdc_init); -module_exit(pata_rdc_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("RDC PCI IDE Driver"); diff --git a/drivers/staging/pata_rdc/pata_rdc.h b/drivers/staging/pata_rdc/pata_rdc.h deleted file mode 100644 index a833339886d..00000000000 --- a/drivers/staging/pata_rdc/pata_rdc.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef pata_rdc_H -#define pata_rdc_H - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* ATA Configuration Register ID offset address size */ -#define ATAConfiguration_PCIOffset 0x40 -#define ATAConfiguration_ID_PrimaryTiming 0x00 -#define ATAConfiguration_ID_SecondaryTiming 0x02 -#define ATAConfiguration_ID_Device1Timing 0x04 -#define ATAConfiguration_ID_UDMAControl 0x08 -#define ATAConfiguration_ID_UDMATiming 0x0A -#define ATAConfiguration_ID_IDEIOConfiguration 0x14 - -#define ATAConfiguration_ID_PrimaryTiming_Size 2 -#define ATAConfiguration_ID_SecondaryTiming_Size 2 -#define ATAConfiguration_ID_Device1Timing_Size 1 -#define ATAConfiguration_ID_UDMAControl_Size 1 -#define ATAConfiguration_ID_UDMATiming_Size 2 -#define ATAConfiguration_ID_IDEIOConfiguration_Size 4 - -/* ATA Configuration Register bit define */ -#define ATAConfiguration_PrimaryTiming_Device0FastTimingEnable 0x0001 -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable 0x0002 /* PIO 3 or greater */ -#define ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable 0x0004 /* PIO 2 or greater */ -#define ATAConfiguration_PrimaryTiming_Device0DMATimingEnable 0x0008 -#define ATAConfiguration_PrimaryTiming_Device1FastTimingEnable 0x0010 -#define ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable 0x0020 /* PIO 3 or greater */ -#define ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable 0x0040 /* PIO 2 or greater */ -#define ATAConfiguration_PrimaryTiming_Device1DMATimingEnable 0x0080 -#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode 0x0300 -#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0 0x0000 /* PIO 0, PIO 2, MDMA 0 */ -#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1 0x0100 /* PIO 3, MDMA 1 */ -#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_2 0x0200 /* X */ -#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3 0x0300 /* PIO 4, MDMA 2 */ -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode 0x3000 -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0 0x0000 /* PIO 0 */ -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1 0x1000 /* PIO 2, MDMA 0 */ -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2 0x2000 /* PIO 3, PIO 4, MDMA 1, MDMA 2 */ -#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_3 0x3000 /* X */ -#define ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable 0x4000 -#define ATAConfiguration_PrimaryTiming_IDEDecodeEnable 0x8000 - -#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode 0x0003 -#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0 0x0000 -#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1 0x0001 -#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_2 0x0002 -#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3 0x0003 -#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode 0x000C -#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0 0x0000 -#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1 0x0004 -#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2 0x0008 -#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_3 0x000C -#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode 0x0030 -#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0 0x0000 -#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1 0x0010 -#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_2 0x0020 -#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3 0x0030 -#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode 0x00C0 -#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0 0x0000 -#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1 0x0040 -#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2 0x0080 -#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_3 0x00C0 - -#define ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable 0x0001 -#define ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable 0x0002 -#define ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable 0x0004 -#define ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable 0x0008 - -#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime 0x0003 -#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0 0x0000 /* UDMA 0 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1 0x0001 /* UDMA 1, UDMA 3, UDMA 5 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2 0x0002 /* UDMA 2, UDMA 4 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_3 0x0003 /* X */ -#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime 0x0030 -#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0 0x0000 /* UDMA 0 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1 0x0010 /* UDMA 1, UDMA 3, UDMA 5 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2 0x0020 /* UDMA 2, UDMA 4 */ -#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_3 0x0030 /* X */ -#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime 0x0300 -#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0 0x0000 /* UDMA 0 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1 0x0100 /* UDMA 1, UDMA 3, UDMA 5 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2 0x0200 /* UDMA 2, UDMA 4 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_3 0x0300 /* X */ -#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime 0x3000 -#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0 0x0000 /* UDMA 0 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1 0x1000 /* UDMA 1, UDMA 3, UDMA 5 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2 0x2000 /* UDMA 2, UDMA 4 */ -#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_3 0x3000 /* X */ - -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable 0x00000001 /* UDMA 3, UDMA 4 */ -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable 0x00000002 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable 0x00000004 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable 0x00000008 -#define ATAConfiguration_IDEIOConfiguration_DeviceCable80Report 0x000000F0 -#define ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report 0x00000030 -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0Cable80Report 0x00000010 /* UDMA 3, UDMA 4, UDMA 5 */ -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1Cable80Report 0x00000020 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report 0x000000C0 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0Cable80Report 0x00000040 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1Cable80Report 0x00000080 -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable 0x00001000 /* UDMA 5 */ -#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable 0x00002000 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable 0x00004000 -#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable 0x00008000 -#define ATAConfiguration_IDEIOConfiguration_ATA100IsSupported 0x00F00000 - -enum _PIOTimingMode { - PIO0 = 0, - PIO1, - PIO2, /* MDMA 0 */ - PIO3, /* MDMA 1 */ - PIO4 /* MDMA 2 */ -}; - -enum _DMATimingMode { - MDMA0 = 0, - MDMA1, - MDMA2 -}; - -enum _UDMATimingMode { - UDMA0 = 0, - UDMA1, - UDMA2, - UDMA3, - UDMA4, - UDMA5 -}; - - -enum rdc_controller_ids { - /* controller IDs */ - RDC_17F31011, - RDC_17F31012 -}; - -#endif -- cgit v1.2.3 From cd1bb431d8b183e2d063267419984cc9bbe22b0b Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 6 Aug 2009 20:43:59 +0100 Subject: Staging: sep: Upstream revision 3 of the security processor kernel driver Upstream revision 3 of the security processor kernel driver; now located in drivers/staging This revision adds an initial TODO file This driver no longer requires to have the firmware compiled in it with the CONFIG_EXTRA_FIRMWARE configuration option. Furthermore, we now have the right to distribute the firmware binaries. This is the Linux kernel driver for the Security Processor, which is a hardware device the provides cryptographic, secure storage, and key management services. Please be aware that this patch does not contain any encryption algorithm. It only transports data to and from user space applications to the security processor. Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/sep/Kconfig | 9 + drivers/staging/sep/Makefile | 3 + drivers/staging/sep/TODO | 8 + drivers/staging/sep/sep_driver_api.h | 545 ++++ drivers/staging/sep/sep_driver_config.h | 305 ++ drivers/staging/sep/sep_driver_ext_api.h | 106 + drivers/staging/sep/sep_driver_hw_defs.h | 240 ++ drivers/staging/sep/sep_ext_with_pci_driver.c | 631 ++++ drivers/staging/sep/sep_main_mod.c | 3919 +++++++++++++++++++++++++ 11 files changed, 5769 insertions(+) create mode 100644 drivers/staging/sep/Kconfig create mode 100644 drivers/staging/sep/Makefile create mode 100644 drivers/staging/sep/TODO create mode 100644 drivers/staging/sep/sep_driver_api.h create mode 100644 drivers/staging/sep/sep_driver_config.h create mode 100644 drivers/staging/sep/sep_driver_ext_api.h create mode 100644 drivers/staging/sep/sep_driver_hw_defs.h create mode 100644 drivers/staging/sep/sep_ext_with_pci_driver.c create mode 100644 drivers/staging/sep/sep_main_mod.c (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 979de8fb32c..2860bd5704f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -135,5 +135,7 @@ source "drivers/staging/hv/Kconfig" source "drivers/staging/vme/Kconfig" +source "drivers/staging/sep/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c80d05006dc..ce6523c02f9 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -49,3 +49,4 @@ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ +obj-$(CONFIG_DX_SEP) += sep/ diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig new file mode 100644 index 00000000000..1a4514d3a7a --- /dev/null +++ b/drivers/staging/sep/Kconfig @@ -0,0 +1,9 @@ +config DX_SEP + tristate "Discretix SEP driver" + depends on MRST + default y + help + Discretix SEP driver + + If unsure say M. The compiled module will be + called sep_driver.ko diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile new file mode 100644 index 00000000000..e2528e80e28 --- /dev/null +++ b/drivers/staging/sep/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS += -DLITTLE__ENDIAN -DDX_CC5_SEP_PLAT -DCRYS_NO_EXT_IF_MODE_SUPPORT +obj-$(CONFIG_DX_SEP) := sep_driver.o +sep_driver-objs := sep_main_mod.o sep_ext_with_pci_driver.o diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO new file mode 100644 index 00000000000..ff0e931dab6 --- /dev/null +++ b/drivers/staging/sep/TODO @@ -0,0 +1,8 @@ +Todo's so far (from Alan Cox) +- Fix firmware loading +- Get firmware into firmware git tree +- Review and tidy each algorithm function +- Check whether it can be plugged into any of the kernel crypto API + interfaces +- Do something about the magic shared memory interface and replace it + with something saner (in Linux terms) diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h new file mode 100644 index 00000000000..6a3be5dbfff --- /dev/null +++ b/drivers/staging/sep/sep_driver_api.h @@ -0,0 +1,545 @@ +/* + * + * sep_driver_api.h - Security Processor Driver api definitions + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#ifndef __SEP_DRIVER_API_H__ +#define __SEP_DRIVER_API_H__ + + + +/*---------------------------------------------------------------- + IOCTL command defines + -----------------------------------------------------------------*/ + +/* magic number 1 of the sep IOCTL command */ +#define SEP_IOC_MAGIC_NUMBER 's' + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0) + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1) + +/* allocate memory in data pool */ +#define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2) + +/* write to pre-allocated memory in data pool */ +#define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3) + +/* read from pre-allocated memory in data pool */ +#define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4) + +/* create sym dma lli tables */ +#define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5) + +/* create flow dma lli tables */ +#define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6) + +/* free dynamic data aalocated during table creation */ +#define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7) + +/* get the static pool area addersses (physical and virtual) */ +#define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8) + +/* set flow id command */ +#define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9) + +/* add tables to the dynamic flow */ +#define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10) + +/* add flow add tables message */ +#define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11) + +/* start sep command */ +#define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12) + +/* init sep command */ +#define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13) + +/* set non blocking mode */ +#define SEP_IOCSETAPIMODE _IO(SEP_IOC_MAGIC_NUMBER , 14) + +/* end transaction command */ +#define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15) + +/* reallocate cache and resident */ +#define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16) + +/* get the offset of the address starting from the beginnnig of the map area */ +#define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17) + +/* get time address and value */ +#define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19) + +/*------------------------------------------- + TYPEDEFS +----------------------------------------------*/ + +/* + init command struct +*/ +struct sep_driver_init_t { + /* start of the 1G of the host memory address that SEP can access */ + unsigned long message_addr; + + /* start address of resident */ + unsigned long message_size_in_words; + +}; + + +/* + realloc cache resident command +*/ +struct sep_driver_realloc_cache_resident_t { + /* base address */ + unsigned long base_addr; + + /* current cache address */ + unsigned long cache_addr; + + /* cache size in bytes*/ + unsigned long cache_size_in_bytes; + + /* current resident address */ + unsigned long resident_addr; + + /* resident size in bytes*/ + unsigned long resident_size_in_bytes; + + /* new cache address */ + unsigned long new_cache_addr; + + /* new resident address */ + unsigned long new_resident_addr; + + /* new resident address */ + unsigned long new_shared_area_addr; + + /* new base address */ + unsigned long new_base_addr; +}; + +/* + set api mode command struct +*/ +struct sep_driver_set_api_mode_t { + /* mode to set - 1 - blocking, 0 - non-blocking */ + unsigned long mode; +}; + +struct sep_driver_alloc_t { + /* virtual address of allocated space */ + unsigned long offset; + + /* physical address of allocated space */ + unsigned long phys_address; + + /* number of bytes to allocate */ + unsigned long num_bytes; +}; + +/* + */ +struct sep_driver_write_t { + /* application space address */ + unsigned long app_address; + + /* address of the data pool */ + unsigned long datapool_address; + + /* number of bytes to write */ + unsigned long num_bytes; +}; + +/* + */ +struct sep_driver_read_t { + /* application space address */ + unsigned long app_address; + + /* address of the data pool */ + unsigned long datapool_address; + + /* number of bytes to read */ + unsigned long num_bytes; +}; + +/* +*/ +struct sep_driver_build_sync_table_t { + /* address value of the data in */ + unsigned long app_in_address; + + /* size of data in */ + unsigned long data_in_size; + + /* address of the data out */ + unsigned long app_out_address; + + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + unsigned long block_size; + + /* the physical address of the first input DMA table */ + unsigned long in_table_address; + + /* number of entries in the first input DMA table */ + unsigned long in_table_num_entries; + + /* the physical address of the first output DMA table */ + unsigned long out_table_address; + + /* number of entries in the first output DMA table */ + unsigned long out_table_num_entries; + + /* data in the first input table */ + unsigned long table_data_size; + + /* distinct user/kernel layout */ + bool isKernelVirtualAddress; + +}; + +/* +*/ +struct sep_driver_build_flow_table_t { + /* flow type */ + unsigned long flow_type; + + /* flag for input output */ + unsigned long input_output_flag; + + /* address value of the data in */ + unsigned long virt_buff_data_addr; + + /* size of data in */ + unsigned long num_virtual_buffers; + + /* the physical address of the first input DMA table */ + unsigned long first_table_addr; + + /* number of entries in the first input DMA table */ + unsigned long first_table_num_entries; + + /* data in the first input table */ + unsigned long first_table_data_size; + + /* distinct user/kernel layout */ + bool isKernelVirtualAddress; +}; + + +struct sep_driver_add_flow_table_t { + /* flow id */ + unsigned long flow_id; + + /* flag for input output */ + unsigned long inputOutputFlag; + + /* address value of the data in */ + unsigned long virt_buff_data_addr; + + /* size of data in */ + unsigned long num_virtual_buffers; + + /* address of the first table */ + unsigned long first_table_addr; + + /* number of entries in the first table */ + unsigned long first_table_num_entries; + + /* data size of the first table */ + unsigned long first_table_data_size; + + /* distinct user/kernel layout */ + bool isKernelVirtualAddress; + +}; + +/* + command struct for set flow id +*/ +struct sep_driver_set_flow_id_t { + /* flow id to set */ + unsigned long flow_id; +}; + + +/* command struct for add tables message */ +struct sep_driver_add_message_t { + /* flow id to set */ + unsigned long flow_id; + + /* message size in bytes */ + unsigned long message_size_in_bytes; + + /* address of the message */ + unsigned long message_address; +}; + +/* command struct for static pool addresses */ +struct sep_driver_static_pool_addr_t { + /* physical address of the static pool */ + unsigned long physical_static_address; + + /* virtual address of the static pool */ + unsigned long virtual_static_address; +}; + +/* command struct for getiing offset of the physical address from + the start of the mapped area */ +struct sep_driver_get_mapped_offset_t { + /* physical address of the static pool */ + unsigned long physical_address; + + /* virtual address of the static pool */ + unsigned long offset; +}; + +/* command struct for getting time value and address */ +struct sep_driver_get_time_t { + /* physical address of stored time */ + unsigned long time_physical_address; + + /* value of the stored time */ + unsigned long time_value; +}; + + +/* + structure that represent one entry in the DMA LLI table +*/ +struct sep_lli_entry_t { + /* physical address */ + unsigned long physical_address; + + /* block size */ + unsigned long block_size; +}; + +/* + structure that reperesents data needed for lli table construction +*/ +struct sep_lli_prepare_table_data_t { + /* pointer to the memory where the first lli entry to be built */ + struct sep_lli_entry_t *lli_entry_ptr; + + /* pointer to the array of lli entries from which the table is to be built */ + struct sep_lli_entry_t *lli_array_ptr; + + /* number of elements in lli array */ + int lli_array_size; + + /* number of entries in the created table */ + int num_table_entries; + + /* number of array entries processed during table creation */ + int num_array_entries_processed; + + /* the totatl data size in the created table */ + int lli_table_total_data_size; +}; + +/* + structure that represent tone table - it is not used in code, jkust + to show what table looks like +*/ +struct sep_lli_table_t { + /* number of pages mapped in this tables. If 0 - means that the table + is not defined (used as a valid flag)*/ + unsigned long num_pages; + /* + pointer to array of page pointers that represent the mapping of the + virtual buffer defined by the table to the physical memory. If this + pointer is NULL, it means that the table is not defined + (used as a valid flag) + */ + struct page **table_page_array_ptr; + + /* maximum flow entries in table */ + struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE]; +}; + + +/* + structure for keeping the mapping of the virtual buffer into physical pages +*/ +struct sep_flow_buffer_data { + /* pointer to the array of page structs pointers to the pages of the + virtual buffer */ + struct page **page_array_ptr; + + /* number of pages taken by the virtual buffer */ + unsigned long num_pages; + + /* this flag signals if this page_array is the last one among many that were + sent in one setting to SEP */ + unsigned long last_page_array_flag; +}; + +/* + struct that keeps all the data for one flow +*/ +struct sep_flow_context_t { + /* + work struct for handling the flow done interrupt in the workqueue + this structure must be in the first place, since it will be used + forcasting to the containing flow context + */ + struct work_struct flow_wq; + + /* flow id */ + unsigned long flow_id; + + /* additional input tables exists */ + unsigned long input_tables_flag; + + /* additional output tables exists */ + unsigned long output_tables_flag; + + /* data of the first input file */ + struct sep_lli_entry_t first_input_table; + + /* data of the first output table */ + struct sep_lli_entry_t first_output_table; + + /* last input table data */ + struct sep_lli_entry_t last_input_table; + + /* last output table data */ + struct sep_lli_entry_t last_output_table; + + /* first list of table */ + struct sep_lli_entry_t input_tables_in_process; + + /* output table in process (in sep) */ + struct sep_lli_entry_t output_tables_in_process; + + /* size of messages in bytes */ + unsigned long message_size_in_bytes; + + /* message */ + unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES]; +}; + + + +/* + this function locks SEP by locking the semaphore +*/ +int sep_lock(void); + +/* + this function unlocks SEP +*/ +void sep_unlock(void); + +/* + this function returns the address of the message shared area +*/ +void sep_map_shared_area(unsigned long *mappedAddr_ptr); + + +/* + this function returns the address of the message shared area +*/ +void sep_send_msg_rdy_cmd(void); + + +/* + This function releases all the application virtual + buffer physical pages, that were previously locked +*/ +int sep_free_dma_pages(struct page **page_array_ptr, + unsigned long num_pages, + unsigned long dirtyFlag); + +/* + This function creates the input and output dma tables for + symmetric operations (AES/DES) according to the block size + from LLI arays +*/ +int sep_construct_dma_tables_from_lli( + struct sep_lli_entry_t *lli_in_array, + unsigned long sep_in_lli_entries, + struct sep_lli_entry_t *lli_out_array, + unsigned long sep_out_lli_entries, + unsigned long block_size, + unsigned long *lli_table_in_ptr, + unsigned long *lli_table_out_ptr, + unsigned long *in_num_entries_ptr, + unsigned long *out_num_entries_ptr, + unsigned long *table_data_size_ptr); + +/* + This function builds input and output DMA tables for synhronic symmetric + operations (AES, DES) It also checks that each table is of the modular + block size +*/ +int sep_prepare_input_output_dma_table(unsigned long app_virt_in_addr, + unsigned long app_virt_out_addr, + unsigned long data_size, + unsigned long block_size, + unsigned long *lli_table_in_ptr, + unsigned long *lli_table_out_ptr, + unsigned long *in_num_entries_ptr, + unsigned long *out_num_entries_ptr, + unsigned long *table_data_size_ptr, + bool isKernelVirtualAddress); + +/* + This function prepares only input DMA table for synhronic symmetric + operations (HASH) +*/ +int sep_prepare_input_dma_table(unsigned long app_virt_addr, + unsigned long data_size, + unsigned long block_size, + unsigned long *lli_table_ptr, + unsigned long *num_entries_ptr, + unsigned long *table_data_size_ptr, + bool isKernelVirtualAddress); + +/* this functions frees all the resources that were allocated for the building + of the LLI DMA tables */ +void sep_free_dma_resources(void); + + +/* poll(suspend) , until reply from sep */ +void sep_driver_poll(void); + +/* + this function handles the request for freeing dma table for + synhronic actions +*/ +int sep_free_dma_table_data_handler(void); + + +#endif diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h new file mode 100644 index 00000000000..a796c4970a0 --- /dev/null +++ b/drivers/staging/sep/sep_driver_config.h @@ -0,0 +1,305 @@ +/* + * + * sep_driver_config.h - Security Processor Driver configuration + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#ifndef __SEP_DRIVER_CONFIG_H__ +#define __SEP_DRIVER_CONFIG_H__ + + +/*-------------------------------------- + DRIVER CONFIGURATION FLAGS + -------------------------------------*/ + +/* if flag is on , then the driver is running in polling and + not interrupt mode */ +#define SEP_DRIVER_POLLING_MODE 1 + +/* flag which defines if the shared area address should be + reconfiged (send to SEP anew) during init of the driver */ +#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 + +/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ +#define SEP_DRIVER_ARM_DEBUG_MODE 0 + +/*------------------------------------------- + INTERNAL DATA CONFIGURATION + -------------------------------------------*/ + +/* flag for the input array */ +#define SEP_DRIVER_IN_FLAG 0 + +/* flag for output array */ +#define SEP_DRIVER_OUT_FLAG 1 + +/* maximum number of entries in one LLI tables */ +#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8 + + +/*-------------------------------------------------------- + SHARED AREA memory total size is 36K + it is divided is following: + + SHARED_MESSAGE_AREA 8K } + } + STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K) + } + DATA_POOL_AREA 12K } + + SYNCHRONIC_DMA_TABLES_AREA 5K + + FLOW_DMA_TABLES_AREA 4K + + SYSTEM_MEMORY_AREA 3k + + SYSTEM_MEMORY total size is 3k + it is divided as following: + + TIME_MEMORY_AREA 8B +-----------------------------------------------------------*/ + + + +/* + the maximum length of the message - the rest of the message shared + area will be dedicated to the dma lli tables +*/ +#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024) + +/* the size of the message shared area in pages */ +#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024) + +/* the size of the data pool static area in pages */ +#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024) + +/* the size of the data pool shared area size in pages */ +#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024) + +/* the size of the message shared area in pages */ +#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5) + + +/* the size of the data pool shared area size in pages */ +#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) + +/* system data (time, caller id etc') pool */ +#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100 + + +/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and + DATA POOL areas. area must be module 4k */ +#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24) + + +/*----------------------------------------------- + offsets of the areas starting from the shared area start address +*/ + +/* message area offset */ +#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0 + +/* static pool area offset */ +#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) + +/* data pool area offset */ +#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) + +/* synhronic dma tables area offset */ +#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) + +/* sep driver flow dma tables area offset */ +#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES) + +/* system memory offset in bytes */ +#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \ + (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES) + +/* offset of the time area */ +#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \ + (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES) + + + +/* start physical address of the SEP registers memory in HOST */ +#define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000 + +/* size of the SEP registers memory region in HOST (for now 100 registers) */ +#define SEP_IO_MEM_REGION_SIZE (2 * 0x100000) + +/* define the number of IRQ for SEP interrupts */ +#define SEP_DIRVER_IRQ_NUM 1 + +/* maximum number of add buffers */ +#define SEP_MAX_NUM_ADD_BUFFERS 100 + +/* number of flows */ +#define SEP_DRIVER_NUM_FLOWS 4 + +/* maximum number of entries in flow table */ +#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25 + +/* offset of the num entries in the block length entry of the LLI */ +#define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24 + +/* offset of the interrupt flag in the block length entry of the LLI */ +#define SEP_INT_FLAG_OFFSET_IN_BITS 31 + +/* mask for extracting data size from LLI */ +#define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF + +/* mask for entries after being shifted left */ +#define SEP_NUM_ENTRIES_MASK 0x7F + +/* default flow id */ +#define SEP_FREE_FLOW_ID 0xFFFFFFFF + +/* temp flow id used during cretiong of new flow until receiving + real flow id from sep */ +#define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1) + +/* maximum add buffers message length in bytes */ +#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4) + +/* maximum number of concurrent virtual buffers */ +#define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100 + +/* the token that defines the start of time address */ +#define SEP_TIME_VAL_TOKEN 0x12345678 +/* DEBUG LEVEL MASKS */ +#define SEP_DEBUG_LEVEL_BASIC 0x1 + +#define SEP_DEBUG_LEVEL_REGISTERS 0x2 + +#define SEP_DEBUG_LEVEL_EXTENDED 0x4 + + +/* FUNCTIONAL MACROS */ + +/* debug macro without paramaters */ +#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ +do { \ + if (DEBUG_LEVEL & sepDebug) \ + printk(KERN_WARNING info); \ +} while (0) + +/* debug macro with 1 paramater */ +#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ +do { \ + if (DEBUG_LEVEL & sepDebug) \ + printk(KERN_WARNING info, param1); \ +} while (0) + +/* debug macro with 2 paramaters */ +#define DEBUG_PRINT_2(DEBUG_LEVEL, info, param1, param2) \ +do { \ + if (DEBUG_LEVEL & sepDebug) \ + printk(KERN_WARNING info , param1, param2); \ +} while (0) + +/* debug macro with 3 paramaters */ +#define DEBUG_PRINT_3(DEBUG_LEVEL, info, param1, param2, param3) \ +do { \ + if (DEBUG_LEVEL & sepDebug) \ + printk(KERN_WARNING info , param1, param2 , param3); \ +} while (0) + +/* debug macro with 4 paramaters */ +#define DEBUG_PRINT_4(DEBUG_LEVEL, info, param1, param2, param3, param4) \ +do { \ + if (DEBUG_LEVEL & sepDebug) \ + printk(KERN_WARNING info, param1, param2, param3, param4); \ +} while (0) + +#if 0 +/* write register macro with option for debug print */ +#define SEP_WRITE_REGISTER(address, value) \ +do { \ + if (sepDebug & SEP_DEBUG_LEVEL_REGISTERS) \ + printk(KERN_WARNING "Write Register: address %lu value %lu\n", \ + (unsigned long)(address), (unsigned long)(value)); \ + writel((value), (void *)(address)); \ +} while (0) + +/* read register macro with option for debug print */ +#define SEP_READ_REGISTER(address , value) \ +do { \ + (value) = readl((void *)(address)); \ + if (sepDebug & SEP_DEBUG_LEVEL_REGISTERS) \ + printk(KERN_WARNING "Read Register: address %lu value %lu\n", \ + (address), (value)); \ +} while (0) +#else + +#if 1 + +#define SEP_WRITE_REGISTER(address, value) writel((value), (void *)(address)) +#define SEP_READ_REGISTER(address, value) (value) = readl((void *)(address)) +#endif + +#endif + +#if 0 +#define SEP_WRITE_ROM(address, value) writel((value), (void *)(address)) + +#define SEP_WRITE_REGISTER(address, value) \ +do { \ + unsigned long i; \ + for (i = 0; i < 1000; i++); \ + writel((value), (void *)(address)); \ +} while (0) + + +#define SEP_READ_REGISTER(address , value) \ +do { \ + unsigned long i; \ + for (i = 0; i < 1000; i++); \ + (value) = readl((void *) (address)); \ +} while (0) + +#endif + +/* wait for SRAM write complete(indirect write */ +#define SEP_WAIT_SRAM_WRITE_COMPLETE() \ +do { \ + unsigned long reg_val; \ + do { \ + SEP_READ_REGISTER(g_sep_reg_base_address + \ + HW_SRAM_DATA_READY_REG_ADDR, (reg_val)); \ + } while (!(reg_val & 0x1)); \ +} while (0) + +#endif diff --git a/drivers/staging/sep/sep_driver_ext_api.h b/drivers/staging/sep/sep_driver_ext_api.h new file mode 100644 index 00000000000..3bc3b4de99c --- /dev/null +++ b/drivers/staging/sep/sep_driver_ext_api.h @@ -0,0 +1,106 @@ +/* + * + * sep_driver_ext_api.h - Security Processor Driver external api definitions + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#ifndef __SEP_DRIVER_EXT_API_H__ +#define __SEP_DRIVER_EXT_API_H__ + + +/* shared variables */ +extern int sepDebug; + +extern unsigned long g_sep_reg_base_address; + +/* +this function loads the ROM code in SEP (needed only in the debug mode on FPGA) +*/ +void sep_load_rom_code(void); + +/* +This functions locks the area of the resident and cache sep code (if possible) +*/ +void sep_lock_cache_resident_area(void); + +/* +This functions copies the cache and resident from their source location into +destination memory, which is external to Linux VM and is given as physical +address +*/ +int sep_copy_cache_resident_to_area(unsigned long src_cache_addr, + unsigned long cache_size_in_bytes, + unsigned long src_resident_addr, + unsigned long resident_size_in_bytes, + unsigned long *dst_new_cache_addr_ptr, + unsigned long *dst_new_resident_addr_ptr); + +/* +This functions maps and allocates the shared area on the external +RAM (device) The input is shared_area_size - the size of the memory +to allocate. The outputs are kernel_shared_area_addr_ptr - the kerenl +address of the mapped and allocated shared area, and +phys_shared_area_addr_ptr - the physical address of the shared area +*/ +int sep_map_and_alloc_shared_area(unsigned long shared_area_size, + unsigned long *kernel_shared_area_addr_ptr, + unsigned long *phys_shared_area_addr_ptr); + +/* +This functions unmaps and deallocates the shared area on the external +RAM (device) The input is shared_area_size - the size of the memory to +deallocate,kernel_shared_area_addr_ptr - the kernel address of the +mapped and allocated shared area,phys_shared_area_addr_ptr - the physical +address of the shared area +*/ +void sep_unmap_and_free_shared_area(unsigned long shared_area_size, + unsigned long kernel_shared_area_addr, + unsigned long phys_shared_area_addr); + + +/* +This functions returns the physical address inside shared area according +to the virtual address. It can be either on the externa RAM device +(ioremapped), or on the system RAM +*/ +unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address); + +/* +This functions returns the vitrual address inside shared area according +to the physical address. It can be either on the externa RAM device +(ioremapped), or on the system RAM This implementation is for the external RAM +*/ +unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address); + +/* +This function registers th driver to the device +subsystem (either PCI, USB, etc) +*/ +int sep_register_driver_to_device(void); + +#endif /*__SEP_DRIVER_EXT_API_H__*/ diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h new file mode 100644 index 00000000000..df831be2645 --- /dev/null +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -0,0 +1,240 @@ +/* + * + * sep_driver_hw_defs.h - Security Processor Driver hardware definitions + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#ifndef SEP_DRIVER_HW_DEFS__H +#define SEP_DRIVER_HW_DEFS__H + +/*--------------------------------------------------------------------------*/ +/* Abstract: HW Registers Defines. */ +/* */ +/* Note: This file was automatically created !!! */ +/* DO NOT EDIT THIS FILE !!! */ +/*--------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* cf registers */ +#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL +#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL +#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL +#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL +#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL +#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL +#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL +#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL +#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL +#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL +#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL +#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL +#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL +#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL +#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL +#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL +#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL +#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL +#define HW_R3B_REG_ADDR 0x00C0UL +#define HW_R4B_REG_ADDR 0x0100UL +#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL +#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL +#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL +#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL +#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL +#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL +#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL +#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL +#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL +#define HW_CSA_REG_ADDR 0x0140UL +#define HW_SINB_REG_ADDR 0x0180UL +#define HW_SOUTB_REG_ADDR 0x0184UL +#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL +#define HW_PKI_STATUS_REG_ADDR 0x01C4UL +#define HW_PKI_BUSY_REG_ADDR 0x01C8UL +#define HW_PKI_A_1025_REG_ADDR 0x01CCUL +#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL +#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL +#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL +#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL +#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL +#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL +#define HW_PKI_CLR_REG_ADDR 0x01E8UL +#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL +#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL +#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL +#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL +#define HW_DES_KEY_0_REG_ADDR 0x0208UL +#define HW_DES_KEY_1_REG_ADDR 0x020CUL +#define HW_DES_KEY_2_REG_ADDR 0x0210UL +#define HW_DES_KEY_3_REG_ADDR 0x0214UL +#define HW_DES_KEY_4_REG_ADDR 0x0218UL +#define HW_DES_KEY_5_REG_ADDR 0x021CUL +#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL +#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL +#define HW_DES_IV_0_REG_ADDR 0x0228UL +#define HW_DES_IV_1_REG_ADDR 0x022CUL +#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL +#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL +#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL +#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL +#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL +#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL +#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL +#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL +#define HW_AES_KEY_0_REG_ADDR 0x0400UL +#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL +#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL +#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL +#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL +#define HW_AES_IV_0_REG_ADDR 0x0440UL +#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL +#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL +#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL +#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL +#define HW_AES_CTR1_REG_ADDR 0x0460UL +#define HW_AES_SK_REG_ADDR 0x0478UL +#define HW_AES_MAC_OK_REG_ADDR 0x0480UL +#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL +#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL +#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL +#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL +#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL +#define HW_AES_CONTROL_REG_ADDR 0x04C0UL +#define HW_HASH_H0_REG_ADDR 0x0640UL +#define HW_HASH_H1_REG_ADDR 0x0644UL +#define HW_HASH_H2_REG_ADDR 0x0648UL +#define HW_HASH_H3_REG_ADDR 0x064CUL +#define HW_HASH_H4_REG_ADDR 0x0650UL +#define HW_HASH_H5_REG_ADDR 0x0654UL +#define HW_HASH_H6_REG_ADDR 0x0658UL +#define HW_HASH_H7_REG_ADDR 0x065CUL +#define HW_HASH_H8_REG_ADDR 0x0660UL +#define HW_HASH_H9_REG_ADDR 0x0664UL +#define HW_HASH_H10_REG_ADDR 0x0668UL +#define HW_HASH_H11_REG_ADDR 0x066CUL +#define HW_HASH_H12_REG_ADDR 0x0670UL +#define HW_HASH_H13_REG_ADDR 0x0674UL +#define HW_HASH_H14_REG_ADDR 0x0678UL +#define HW_HASH_H15_REG_ADDR 0x067CUL +#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL +#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL +#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL +#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL +#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL +#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL +#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL +#define HW_HASH_PARAM_REG_ADDR 0x07DCUL +#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL +#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL +#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL +#define HW_HASH_DATA_REG_ADDR 0x07ECUL +#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL +#define HW_DRNG_VALID_REG_ADDR 0x0804UL +#define HW_DRNG_DATA_REG_ADDR 0x0808UL +#define HW_RND_SRC_EN_REG_ADDR 0x080CUL +#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL +#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL +#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL +#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL +#define HW_CLK_STATUS_REG_ADDR 0x0824UL +#define HW_CLK_ENABLE_REG_ADDR 0x0828UL +#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL +#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL +#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL +#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL +#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL +#define HW_AES_BUSY_REG_ADDR 0x0914UL +#define HW_DES_BUSY_REG_ADDR 0x0918UL +#define HW_HASH_BUSY_REG_ADDR 0x091CUL +#define HW_CONTENT_REG_ADDR 0x0924UL +#define HW_VERSION_REG_ADDR 0x0928UL +#define HW_CONTEXT_ID_REG_ADDR 0x0930UL +#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL +#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL +#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL +#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL +#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL +#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL +#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL +#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL +#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL +#define HW_OLD_DATA_REG_ADDR 0x0C48UL +#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL +#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL +#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL +#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL +#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL +#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL +#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL +#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL +#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL +#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL +#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL +#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL +#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL +#define HW_SRAM_DATA_REG_ADDR 0x0F00UL +#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL +#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL +#define HW_HOST_IRR_REG_ADDR 0x0A00UL +#define HW_HOST_IMR_REG_ADDR 0x0A04UL +#define HW_HOST_ICR_REG_ADDR 0x0A08UL +#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL +#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL +#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL +#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL +#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL +#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL +#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL +#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL +#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL +#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL +#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL +#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL +#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL +#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL +#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL +#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL +#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL +#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL +#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL +#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL +#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL +#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL +#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL +#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL +#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef HW_DEFS */ diff --git a/drivers/staging/sep/sep_ext_with_pci_driver.c b/drivers/staging/sep/sep_ext_with_pci_driver.c new file mode 100644 index 00000000000..9fb1dd0129a --- /dev/null +++ b/drivers/staging/sep/sep_ext_with_pci_driver.c @@ -0,0 +1,631 @@ +/* + * + * sep_ext_with_pci_driver.c - Security Processor Driver + * pci initialization functions + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_driver_ext_api.h" + +#if SEP_DRIVER_ARM_DEBUG_MODE + +#define CRYS_SEP_ROM_length 0x4000 + +#define CRYS_SEP_ROM_start_address 0x8000C000UL + +#define CRYS_SEP_ROM_start_address_offset 0xC000UL + +#define SEP_ROM_BANK_register 0x80008420UL + +#define SEP_ROM_BANK_register_offset 0x8420UL + +#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000 + +/* 2M size */ +/* #define SEP_RAR_IO_MEM_REGION_SIZE (1024*1024*2) + +static unsigned long CRYS_SEP_ROM[] = { + #include "SEP_ROM_image.h" +}; + +#else +*/ + +/*------------- + THOSE 2 definitions are specific to the board - must be + defined during integration +---------------*/ +#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000 + +/* 2M size */ + +#endif /* SEP_DRIVER_ARM_DEBUG_MODE */ + +#define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000 +#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 + +irqreturn_t sep_inthandler(int irq , void* dev_id); + +/* NOTE - must be defined specific to the board */ +#define VENDOR_ID 0x8086 + +/* io memory (register area) */ +static unsigned long io_memory_start_physical_address; +static unsigned long io_memory_end_physical_address; +static unsigned long io_memory_size; +void *io_memory_start_virtual_address; + +/* restricted access region */ +static unsigned long rar_physical_address; +static void *rar_virtual_address; + +/* shared memory region */ +static unsigned long shared_physical_address; +static void *shared_virtual_address; + +/* firmware regions */ +static unsigned long cache_physical_address; +static unsigned long cache_size; +static void *cache_virtual_address; + +static unsigned long resident_physical_address; +static unsigned long resident_size; +static void *resident_virtual_address; + +/* device interrupt (as retrieved from PCI) */ +int sep_irq; + +/* temporary */ +unsigned long jiffies_future; + +/*----------------------------- + private functions +--------------------------------*/ + +/* + function that is activated on the succesfull probe of the SEP device +*/ +static int __devinit sep_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); + +static struct pci_device_id sep_pci_id_tbl[] = { + { PCI_DEVICE(VENDOR_ID, 0x080c) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); + +static unsigned long rar_region_addr; + + +/* field for registering driver to PCI device */ +static struct pci_driver sep_pci_driver = { + .name = "sep_sec_driver", + .id_table = sep_pci_id_tbl, + .probe = sep_probe +}; + +/* pointer to pci dev received during probe */ +struct pci_dev *sep_pci_dev_ptr; + +/* + This functions locks the area of the resisnd and cache sep code +*/ +void sep_lock_cache_resident_area(void) +{ + return; +} + + +/* + This functions copies the cache and resident from their source location into + destination memory, which is external to Linux VM and is given as + physical address +*/ +int sep_copy_cache_resident_to_area(unsigned long src_cache_addr, + unsigned long cache_size_in_bytes, + unsigned long src_resident_addr, + unsigned long resident_size_in_bytes, + unsigned long *dst_new_cache_addr_ptr, + unsigned long *dst_new_resident_addr_ptr) +{ + /* resident address in user space */ + unsigned long resident_addr; + + /* cahce address in user space */ + unsigned long cache_addr; + + const struct firmware *fw; + + char *cache_name = "cache.image.bin"; + char *res_name = "resident.image.bin"; + + /* error */ + int error; + + /*-------------------------------- + CODE + -------------------------------------*/ + error = 0; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:rar_virtual is %p\n", + rar_virtual_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:rar_physical is %08lx\n", + rar_physical_address); + + rar_region_addr = (unsigned long)rar_virtual_address; + + cache_physical_address = rar_physical_address; + cache_virtual_address = rar_virtual_address; + + /* load cache */ + error = request_firmware(&fw, cache_name, &sep_pci_dev_ptr->dev); + if (error) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cant request cache fw\n"); + goto end_function; + } + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cache data loc is %p\n", + (void *)fw->data); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cache data size is %08x\n", + fw->size); + + memcpy((void *)cache_virtual_address, (void *)fw->data, fw->size); + + cache_size = fw->size; + + cache_addr = (unsigned long)cache_virtual_address; + + release_firmware(fw); + + resident_physical_address = cache_physical_address+cache_size; + resident_virtual_address = cache_virtual_address+cache_size; + + /* load resident */ + error = request_firmware(&fw, res_name, &sep_pci_dev_ptr->dev); + if (error) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cant request res fw\n"); + goto end_function; + } + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:res data loc is %p\n", + (void *)fw->data); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:res data size is %08x\n", + fw->size); + + memcpy((void *)resident_virtual_address, (void *)fw->data, fw->size); + + resident_size = fw->size; + + release_firmware(fw); + + resident_addr = (unsigned long)resident_virtual_address; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:resident_addr (physical )is %08lx\n", + resident_physical_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cache_addr (physical) is %08lx\n", + cache_physical_address); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:resident_addr (logical )is %08lx\n", + resident_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cache_addr (logical) is %08lx\n", + cache_addr); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:resident_size is %08lx\n", resident_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cache_size is %08lx\n", cache_size); + + + + /* physical addresses */ + *dst_new_cache_addr_ptr = cache_physical_address; + *dst_new_resident_addr_ptr = resident_physical_address; + +end_function: + + return error; +} + +/* + This functions maps and allocates the + shared area on the external RAM (device) + The input is shared_area_size - the size of the memory to + allocate. The outputs + are kernel_shared_area_addr_ptr - the kerenl + address of the mapped and allocated + shared area, and phys_shared_area_addr_ptr + - the physical address of the shared area +*/ +int sep_map_and_alloc_shared_area(unsigned long shared_area_size, + unsigned long *kernel_shared_area_addr_ptr, + unsigned long *phys_shared_area_addr_ptr) +{ + // shared_virtual_address = ioremap_nocache(0xda00000,shared_area_size); + shared_virtual_address = kmalloc(shared_area_size, GFP_KERNEL); + if (!shared_virtual_address) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "sep_driver:shared memory kmalloc failed\n"); + return -1; + } + + shared_physical_address = __pa(shared_virtual_address); + // shared_physical_address = 0xda00000; + + *kernel_shared_area_addr_ptr = (unsigned long)shared_virtual_address; + /* set the physical address of the shared area */ + *phys_shared_area_addr_ptr = shared_physical_address; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:shared_virtual_address is %p\n", + shared_virtual_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:shared_region_size is %08lx\n", + shared_area_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:shared_physical_addr is %08lx\n", + *phys_shared_area_addr_ptr); + + return 0; +} + +/* + This functions unmaps and deallocates the shared area + on the external RAM (device) + The input is shared_area_size - the size of the memory to deallocate,kernel_ + shared_area_addr_ptr - the kernel address of the mapped and allocated + shared area,phys_shared_area_addr_ptr - the physical address of + the shared area +*/ +void sep_unmap_and_free_shared_area(unsigned long shared_area_size, + unsigned long kernel_shared_area_addr, + unsigned long phys_shared_area_addr) +{ + kfree((void *)kernel_shared_area_addr); + return; +} + +/* + This functions returns the physical address inside shared area according + to the virtual address. It can be either on the externa RAM device + (ioremapped), or on the system RAM + This implementation is for the external RAM +*/ +unsigned long sep_shared_area_virt_to_phys(unsigned long virt_address) +{ + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:sh virt to phys v %08lx\n", + virt_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:sh virt to phys p %08lx\n", + shared_physical_address + + (virt_address - (unsigned long)shared_virtual_address)); + + return (unsigned long)shared_physical_address + + (virt_address - (unsigned long)shared_virtual_address); +} + +/* + This functions returns the virtual address inside shared area + according to the physical address. It can be either on the + externa RAM device (ioremapped), or on the system RAM This implementation + is for the external RAM +*/ +unsigned long sep_shared_area_phys_to_virt(unsigned long phys_address) +{ + return (unsigned long)shared_virtual_address + + (phys_address - shared_physical_address); +} + + +/* + function that is activaed on the succesfull probe of the SEP device +*/ +static int __devinit sep_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + /* error */ + int error; + + /*------------------------ + CODE + ---------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "Sep pci probe starting\n"); + error = 0; + + /* enable the device */ + error = pci_enable_device(pdev); + if (error) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "error enabling pci device\n"); + goto end_function; + } + + /* set the pci dev pointer */ + sep_pci_dev_ptr = pdev; + + /* get the io memory start address */ + io_memory_start_physical_address = pci_resource_start(pdev, 0); + if (!io_memory_start_physical_address) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver error pci resource start\n"); + goto end_function; + } + + /* get the io memory end address */ + io_memory_end_physical_address = pci_resource_end(pdev, 0); + if (!io_memory_end_physical_address) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver error pci resource end\n"); + goto end_function; + } + + io_memory_size = io_memory_end_physical_address - + io_memory_start_physical_address + 1; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:io_memory_start_physical_address is %08lx\n", + io_memory_start_physical_address); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:io_memory_end_phyaical_address is %08lx\n", + io_memory_end_physical_address); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:io_memory_size is %08lx\n", + io_memory_size); + + io_memory_start_virtual_address = + ioremap_nocache(io_memory_start_physical_address, + io_memory_size); + if (!io_memory_start_virtual_address) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver error ioremap of io memory\n"); + goto end_function; + } + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:io_memory_start_virtual_address is %p\n", + io_memory_start_virtual_address); + + g_sep_reg_base_address = (unsigned long)io_memory_start_virtual_address; + + + /* set up system base address and shared memory location */ + + rar_virtual_address = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, + GFP_KERNEL); + + if (!rar_virtual_address) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:cant kmalloc rar\n"); + goto end_function; + } + + rar_physical_address = __pa(rar_virtual_address); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:rar_physical is %08lx\n", + rar_physical_address); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:rar_virtual is %p\n", + rar_virtual_address); + + +#if !SEP_DRIVER_POLLING_MODE + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: about to write IMR and ICR REG_ADDR\n"); + + /* clear ICR register */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_ICR_REG_ADDR, + 0xFFFFFFFF); + + /* set the IMR register - open only GPR 2 */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_IMR_REG_ADDR, + (~(0x1 << 13))); + + /* figure out our irq */ + error = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, (u8 *)&sep_irq); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: my irq is %d\n", sep_irq); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: about to call request_irq\n"); + /* get the interrupt line */ + error = request_irq(sep_irq, sep_inthandler, IRQF_SHARED, + "sep_driver", &g_sep_reg_base_address); + if (error) + goto end_function; + + goto end_function; + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: about to write IMR REG_ADDR"); + + /* set the IMR register - open only GPR 2 */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_IMR_REG_ADDR, + (~(0x1 << 13))); + +#endif /* SEP_DRIVER_POLLING_MODE */ + +end_function: + + return error; +} + +/* + this function registers th driver to + the device subsystem( either PCI, USB, etc) +*/ +int sep_register_driver_to_device(void) +{ + return pci_register_driver(&sep_pci_driver); +} + + + +void sep_load_rom_code() +{ +#if SEP_DRIVER_ARM_DEBUG_MODE + /* Index variables */ + unsigned long i, k, j; + unsigned long regVal; + unsigned long Error; + unsigned long warning; + + /* Loading ROM from SEP_ROM_image.h file */ + k = sizeof(CRYS_SEP_ROM); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: DX_CC_TST_SepRomLoader start\n"); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: k is %lu\n", k); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: g_sep_reg_base_address is %p\n", + g_sep_reg_base_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", + CRYS_SEP_ROM_start_address_offset); + + for (i = 0; i < 4; i++) { + /* write bank */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + SEP_ROM_BANK_register_offset, i); + + for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) { + SEP_WRITE_REGISTER(g_sep_reg_base_address + + CRYS_SEP_ROM_start_address_offset + 4*j, + CRYS_SEP_ROM[i * 0x1000 + j]); + + k = k - 4; + + if (k == 0) { + j = CRYS_SEP_ROM_length; + i = 4; + } + } + } + + /* reset the SEP*/ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_SW_RST_REG_ADDR, 0x1); + + /* poll for SEP ROM boot finish */ + do { + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR3_REG_ADDR, regVal); + } while (!regVal); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling ended\n"); + + switch (regVal) { + case 0x1: + /* fatal error - read erro status from GPRO */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, Error); + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 1\n"); + break; + case 0x2: + /* Boot First Phase ended */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, warning); + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 2\n"); + break; + case 0x4: + /* Cold boot ended successfully */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, warning); + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 4\n"); + Error = 0; + break; + case 0x8: + /* Warmboot ended successfully */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, warning); + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 8\n"); + Error = 0; + break; + case 0x10: + /* ColdWarm boot ended successfully */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, warning); + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 16\n"); + Error = 0; + break; + case 0x20: + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: ROM polling case 32\n"); + break; + } + +#endif +} + diff --git a/drivers/staging/sep/sep_main_mod.c b/drivers/staging/sep/sep_main_mod.c new file mode 100644 index 00000000000..158c462135b --- /dev/null +++ b/drivers/staging/sep/sep_main_mod.c @@ -0,0 +1,3919 @@ +/* + * + * sep_main_mod.c - Security Processor Driver main group of functions + * + * Copyright(c) 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2009 Discretix. All rights reserved. + * + * 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, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_driver_ext_api.h" + +/*---------------------------------------- + DEFINES +-----------------------------------------*/ + + +#define INT_MODULE_PARM(n, v) int n = v; module_param(n, int, 0) + +/*-------------------------------------- + TYPEDEFS + -----------------------------------------*/ + + + +/*-------------------------------------------- + GLOBAL variables +--------------------------------------------*/ + +/* debug messages level */ +INT_MODULE_PARM(sepDebug, 0x0); +MODULE_PARM_DESC(sepDebug, "Flag to enable SEP debug messages"); + +/* address of the shared memory allocated during init for SEP driver */ +static unsigned long g_sep_shared_area_addr; + +/* the physical address of the shared area */ +static unsigned long g_sep_phys_shared_area_addr; + +/* Message Shared Area start address - will be allocated during init */ +static unsigned long g_message_shared_area_addr; + +/* major and minor device numbers */ +static dev_t g_sep_device_number; + +/* the files operations structure of the driver */ +static struct file_operations g_sep_fops; + +/* cdev struct of the driver */ +static struct cdev g_sep_cdev; + +/* + mutex for the access to the internals of the sep driver +*/ +static DEFINE_MUTEX(sep_mutex); + + +/* wait queue head (event) of the driver */ +DECLARE_WAIT_QUEUE_HEAD(g_sep_event); + + +/* start address of the access to the SEP registers from driver */ +unsigned long g_sep_reg_base_address; + +/* transaction counter that coordinates the transactions between SEP and HOST */ +static unsigned long sep_host_to_sep_send_counter; + +/* counter for the messages from sep */ +static unsigned long sep_sep_to_host_reply_counter; + +/* counter for the number of bytes allocated in the pool for the current +transaction */ +static unsigned long sep_data_pool_bytes_allocated; + +/* array of pointers to the pages that represent input data for the synchronic +DMA action */ +struct page **sep_in_page_array; + +/* array of pointers to the pages that represent out data for the synchronic +DMA action */ +struct page **sep_out_page_array; + +/* number of pages in the sep_in_page_array */ +unsigned long sep_in_num_pages; + +/* number of pages in the sep_out_page_array */ +unsigned long sep_out_num_pages; + +/* global data for every flow */ +static struct sep_flow_context_t g_sep_flows_data_array[SEP_DRIVER_NUM_FLOWS]; + +/* flag for API mode - 1 -is blocking, 0 is non-blocking */ +static unsigned long g_sep_block_mode_flag; + +/* pointer to the workqueue that handles the flow done interrupts */ +static struct workqueue_struct *g_sep_flow_wq_ptr; + +/*------------------------------------------------ + PROTOTYPES +---------------------------------------------------*/ + +/* + interrupt handler function +*/ +irqreturn_t sep_inthandler(int irq, void *dev_id); + +/* + this function registers the driver to the file system +*/ +static int sep_register_driver_to_fs(void); + +/* + this function unregisters driver from fs +*/ +static void sep_unregister_driver_from_fs(void); + +/* + this function calculates the size of data that can be inserted into the lli + table from this array the condition is that either the table is full + (all etnries are entered), or there are no more entries in the lli array +*/ +static unsigned long sep_calculate_lli_table_max_size( + struct sep_lli_entry_t *lli_in_array_ptr, + unsigned long num_array_entries); +/* + this functions builds ont lli table from the lli_array according to the + given size of data +*/ +static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, + struct sep_lli_entry_t *lli_table_ptr, + unsigned long *num_processed_entries_ptr, + unsigned long *num_table_entries_ptr, + unsigned long table_data_size); + +/* + this function goes over the list of the print created tables and prints + all the data +*/ +static void sep_debug_print_lli_tables(struct sep_lli_entry_t *lli_table_ptr, + unsigned long num_table_entries, + unsigned long table_data_size); + + + +/* + This function raises interrupt to SEPm that signals that is has a new + command from HOST +*/ +static void sep_send_command_handler(void); + + +/* + This function raises interrupt to SEP that signals that is has a + new reply from HOST +*/ +static void sep_send_reply_command_handler(void); + +/* + This function handles the allocate data pool memory request + This function returns calculates the physical address of the allocated memory + and the offset of this area from the mapped address. Therefore, the FVOs in + user space can calculate the exact virtual address of this allocated memory +*/ +static int sep_allocate_data_pool_memory_handler(unsigned long arg); + + +/* + This function handles write into allocated data pool command +*/ +static int sep_write_into_data_pool_handler(unsigned long arg); + +/* + this function handles the read from data pool command +*/ +static int sep_read_from_data_pool_handler(unsigned long arg); + +/* + this function handles tha request for creation of the DMA table + for the synchronic symmetric operations (AES,DES) +*/ +static int sep_create_sync_dma_tables_handler(unsigned long arg); + +/* + this function handles the request to create the DMA tables for flow +*/ +static int sep_create_flow_dma_tables_handler(unsigned long arg); + +/* + This API handles the end transaction request +*/ +static int sep_end_transaction_handler(unsigned long arg); + + +/* + this function handles add tables to flow +*/ +static int sep_add_flow_tables_handler(unsigned long arg); + +/* + this function add the flow add message to the specific flow +*/ +static int sep_add_flow_tables_message_handler(unsigned long arg); + +/* + this function handles the request for SEP start +*/ +static int sep_start_handler(void); + +/* + this function handles the request for SEP initialization +*/ +static int sep_init_handler(unsigned long arg); + +/* + this function handles the request cache and resident reallocation +*/ +static int sep_realloc_cache_resident_handler(unsigned long arg); + + +/* + This api handles the setting of API mode to blocking or non-blocking +*/ +static int sep_set_api_mode_handler(unsigned long arg); + +/* handler for flow done interrupt */ +static void sep_flow_done_handler(struct work_struct *work); + +/* + This function locks all the physical pages of the kernel virtual buffer + and construct a basic lli array, where each entry holds the physical + page address and the size that application data holds in this physical pages +*/ +static int sep_lock_kernel_pages(unsigned long kernel_virt_addr, + unsigned long data_size, + unsigned long *num_pages_ptr, + struct sep_lli_entry_t **lli_array_ptr, + struct page ***page_array_ptr); + +/* + This function creates one DMA table for flow and returns its data, + and pointer to its info entry +*/ +static int sep_prepare_one_flow_dma_table(unsigned long virt_buff_addr, + unsigned long virt_buff_size, + struct sep_lli_entry_t *table_data, + struct sep_lli_entry_t **info_entry_ptr, + struct sep_flow_context_t *flow_data_ptr, + bool isKernelVirtualAddress); + +/* + This function creates a list of tables for flow and returns the data for the + first and last tables of the list +*/ +static int sep_prepare_flow_dma_tables(unsigned long num_virtual_buffers, + unsigned long first_buff_addr, + struct sep_flow_context_t *flow_data_ptr, + struct sep_lli_entry_t *first_table_data_ptr, + struct sep_lli_entry_t *last_table_data_ptr, + bool isKernelVirtualAddress); + +/* + this function find a space for the new flow dma table +*/ +static int sep_find_free_flow_dma_table_space( + unsigned long **table_address_ptr); + +/* + this function goes over all the flow tables connected to the given table and + deallocate them +*/ +static void sep_deallocated_flow_tables( + struct sep_lli_entry_t *first_table_ptr); + +/* + This function handler the set flow id command +*/ +static int sep_set_flow_id_handler(unsigned long arg); + +/* + This function returns pointer to the flow data structure + that conatins the given id +*/ +static int sep_find_flow_context(unsigned long flow_id, + struct sep_flow_context_t **flow_data_ptr); + + +/* + this function returns the physical and virtual addresses of the static pool +*/ +static int sep_get_static_pool_addr_handler(unsigned long arg); + +/* + this address gets the offset of the physical address from the start of + the mapped area +*/ +static int sep_get_physical_mapped_offset_handler(unsigned long arg); + + +/* + this function handles the request for get time +*/ +static int sep_get_time_handler(unsigned long arg); + +/* + calculates time and sets it at the predefined address +*/ +static int sep_set_time(unsigned long *address_ptr, + unsigned long *time_in_sec_ptr); + +/* + PATCH for configuring the DMA to single burst instead of multi-burst +*/ +static void sep_configure_dma_burst(void); + +/* + This function locks all the physical pages of the + application virtual buffer and construct a basic lli + array, where each entry holds the physical page address + and the size that application data holds in this physical pages +*/ +static int sep_lock_user_pages(unsigned long app_virt_addr, + unsigned long data_size, + unsigned long *num_pages_ptr, + struct sep_lli_entry_t **lli_array_ptr, + struct page ***page_array_ptr); + +/*--------------------------------------------- + FUNCTIONS +-----------------------------------------------*/ + +/* + this function locks SEP by locking the semaphore +*/ +int sep_lock() +{ + mutex_lock(&sep_mutex); + + return 0; +} + +/* + this function unlocks SEP +*/ +void sep_unlock() +{ + /* release mutex */ + mutex_unlock(&sep_mutex); +} + +/* + this function returns the address of the message shared area +*/ +void sep_map_shared_area(unsigned long *mappedAddr_ptr) +{ + *mappedAddr_ptr = g_sep_shared_area_addr; +} + +/* + this function returns the address of the message shared area +*/ +void sep_send_msg_rdy_cmd() +{ + sep_send_command_handler(); +} + +/* this functions frees all the resources that were allocated for the building +of the LLI DMA tables */ +void sep_free_dma_resources() +{ + sep_free_dma_table_data_handler(); +} + +/* poll(suspend), until reply from sep */ +void sep_driver_poll() +{ + unsigned long retVal = 0; + +#ifdef SEP_DRIVER_POLLING_MODE + + while (sep_host_to_sep_send_counter != (retVal & 0x7FFFFFFF)) + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR2_REG_ADDR, + retVal); + + sep_sep_to_host_reply_counter++; +#else + /* poll, until reply from sep */ + wait_event(g_sep_event, + (sep_host_to_sep_send_counter == sep_sep_to_host_reply_counter)); + +#endif +} + +/*---------------------------------------------------------------------- + open function of the character driver - must only lock the mutex + must also release the memory data pool allocations +------------------------------------------------------------------------*/ +static int sep_open(struct inode *inode_ptr, struct file *file_ptr) +{ + /* return value */ + int error; + + /*----------------- + CODE + ---------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:--------> open start\n"); + + error = 0; + + /* check the blocking mode */ + if (g_sep_block_mode_flag) + /* lock mutex */ + mutex_lock(&sep_mutex); + else + error = mutex_trylock(&sep_mutex); + + /* check the error */ + if (error) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: down_interruptible failed\n"); + + goto end_function; + } + + /* release data pool allocations */ + sep_data_pool_bytes_allocated = 0; + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:<-------- open end\n"); + + return error; +} + + + + +/*------------------------------------------------------------ + release function +-------------------------------------------------------------*/ +static int sep_release(struct inode *inode_ptr, struct file *file_ptr) +{ + /*----------------- + CODE + ---------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "----------->SEP Driver: sep_release start\n"); + +#if 0/*!SEP_DRIVER_POLLING_MODE*/ + /* close IMR */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_IMR_REG_ADDR, 0x7FFF); + + /* release IRQ line */ + free_irq(SEP_DIRVER_IRQ_NUM, &g_sep_reg_base_address); + +#endif + + /* unlock the sep mutex */ + mutex_unlock(&sep_mutex); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_release end\n"); + + return 0; +} + + + + +/*--------------------------------------------------------------- + map function - this functions maps the message shared area +-----------------------------------------------------------------*/ +static int sep_mmap(struct file *filp, struct vm_area_struct *vma) +{ + /* physical addr */ + unsigned long phys_addr; + + /*----------------------- + CODE + -------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "-------->SEP Driver: mmap start\n"); + + /* check that the size of the mapped range is as the size of the message + shared area */ + if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver mmap requested size is more than allowed\n"); + printk(KERN_WARNING "SEP Driver mmap requested size is more \ + than allowed\n"); + printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", + vma->vm_end); + printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", + vma->vm_start); + return -EAGAIN; + } + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:g_message_shared_area_addr is %08lx\n", + g_message_shared_area_addr); + + /* get physical address */ + phys_addr = g_sep_phys_shared_area_addr; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver: phys_addr is %08lx\n", +phys_addr); + + if (remap_pfn_range(vma, + vma->vm_start, + phys_addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver remap_page_range failed\n"); + printk(KERN_WARNING "SEP Driver remap_page_range failed\n"); + return -EAGAIN; + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:<-------- mmap end\n"); + + return 0; +} + + +/*----------------------------------------------- + poll function +*----------------------------------------------*/ +static unsigned int sep_poll(struct file *filp, poll_table *wait) +{ + unsigned long count; + + unsigned int mask = 0; + + /* flow id */ + unsigned long retVal = 0; + + /*---------------------------------------------- + CODE + -------------------------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "---------->SEP Driver poll: start\n"); + + +#if SEP_DRIVER_POLLING_MODE + + while (sep_host_to_sep_send_counter != (retVal & 0x7FFFFFFF)) { + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR2_REG_ADDR, + retVal); + + for (count = 0; count < 10 * 4; count += 4) + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "Poll Debug Word %lu of the message is %lu\n", + count, + *((unsigned long *)(g_sep_shared_area_addr + + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count))); + } + + sep_sep_to_host_reply_counter++; +#else + /* add the event to the polling wait table */ + poll_wait(filp, &g_sep_event, wait); + +#endif + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_host_to_sep_send_counter is %lu\n", + sep_host_to_sep_send_counter); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_sep_to_host_reply_counter is %lu\n", + sep_sep_to_host_reply_counter); + + /* check if the data is ready */ + if (sep_host_to_sep_send_counter == sep_sep_to_host_reply_counter) { + for (count = 0; count < 12 * 4; count += 4) + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "Sep Mesg Word %lu of the message is %lu\n", + count, *((unsigned long *)(g_sep_shared_area_addr + count))); + + for (count = 0; count < 10 * 4; count += 4) + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "Debug Data Word %lu of the message is %lu\n", + count, + *((unsigned long *)(g_sep_shared_area_addr + 0x1800 + count))); + + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR2_REG_ADDR, + retVal); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "retVal is %lu\n", retVal); + /* check if the this is sep reply or request */ + if (retVal >> 31) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep request in\n"); + /* request */ + mask |= POLLOUT | POLLWRNORM; + } else { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver: sep reply in\n"); + mask |= POLLIN | POLLRDNORM; + } + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:<-------- poll exit\n"); + return mask; +} + + +static int sep_ioctl(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + + /* error */ + int error; + + /*------------------------ + CODE + ------------------------*/ + error = 0; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "------------>SEP Driver: ioctl start\n"); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver: cmd is %x\n", cmd); + + /* check that the command is for sep device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) + error = -ENOTTY; + + switch (cmd) { + case SEP_IOCSENDSEPCOMMAND: + + /* send command to SEP */ + sep_send_command_handler(); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: after sep_send_command_handler\n"); + + break; + + case SEP_IOCSENDSEPRPLYCOMMAND: + + /* send reply command to SEP */ + sep_send_reply_command_handler(); + + break; + + case SEP_IOCALLOCDATAPOLL: + + /* allocate data pool */ + error = sep_allocate_data_pool_memory_handler(arg); + + break; + + case SEP_IOCWRITEDATAPOLL: + + /* write data into memory pool */ + error = sep_write_into_data_pool_handler(arg); + + break; + + case SEP_IOCREADDATAPOLL: + + /* read data from data pool into application memory */ + error = sep_read_from_data_pool_handler(arg); + + break; + + case SEP_IOCCREATESYMDMATABLE: + + /* create dma table for synhronic operation */ + error = sep_create_sync_dma_tables_handler(arg); + + break; + + case SEP_IOCCREATEFLOWDMATABLE: + + /* create flow dma tables */ + error = sep_create_flow_dma_tables_handler(arg); + + break; + + case SEP_IOCFREEDMATABLEDATA: + + /* free the pages */ + error = sep_free_dma_table_data_handler(); + + break; + + case SEP_IOCSETFLOWID: + + /* set flow id */ + error = sep_set_flow_id_handler(arg); + + break; + + case SEP_IOCADDFLOWTABLE: + + /* add tables to the dynamic flow */ + error = sep_add_flow_tables_handler(arg); + + break; + + case SEP_IOCADDFLOWMESSAGE: + + /* add message of add tables to flow */ + error = sep_add_flow_tables_message_handler(arg); + + break; + + case SEP_IOCSEPSTART: + + /* start command to sep */ + error = sep_start_handler(); + break; + + case SEP_IOCSEPINIT: + + /* init command to sep */ + error = sep_init_handler(arg); + break; + + case SEP_IOCSETAPIMODE: + + /* set non- blocking mode */ + error = sep_set_api_mode_handler(arg); + + break; + + case SEP_IOCGETSTATICPOOLADDR: + + /* get the physical and virtual addresses of the static pool */ + error = sep_get_static_pool_addr_handler(arg); + + break; + + case SEP_IOCENDTRANSACTION: + + error = sep_end_transaction_handler(arg); + + break; + + case SEP_IOCREALLOCCACHERES: + + error = sep_realloc_cache_resident_handler(arg); + + break; + + case SEP_IOCGETMAPPEDADDROFFSET: + + error = sep_get_physical_mapped_offset_handler(arg); + + break; + case SEP_IOCGETIME: + + error = sep_get_time_handler(arg); + + break; + + default: + error = -ENOTTY; + break; + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- ioctl end\n"); + + return error; +} + + +/* + this function registers the driver to the file system +*/ +static int sep_register_driver_to_fs(void) +{ + /* return value */ + int ret_val; + + /*--------------------- + CODE + -----------------------*/ + + ret_val = alloc_chrdev_region(&g_sep_device_number, 0, 1, "sep_sec_driver"); + if (ret_val) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_driver:major number allocation failed, retval is %d\n", ret_val); + goto end_function; + } + + /* set the files operations structure */ + g_sep_fops.owner = THIS_MODULE; + g_sep_fops.ioctl = sep_ioctl; + g_sep_fops.poll = sep_poll; + g_sep_fops.open = sep_open; + g_sep_fops.release = sep_release; + g_sep_fops.mmap = sep_mmap; + + /* init cdev */ + cdev_init(&g_sep_cdev, &g_sep_fops); + g_sep_cdev.owner = THIS_MODULE; + + /* register the driver with the kernel */ + ret_val = cdev_add(&g_sep_cdev, g_sep_device_number, 1); + + if (ret_val) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_driver:cdev_add failed, retval is %d\n", + ret_val); + goto end_function_unregister_devnum; + } + + goto end_function; + +end_function_unregister_devnum: + + /* unregister dev numbers */ + unregister_chrdev_region(g_sep_device_number, 1); + +end_function: + + return ret_val; +} + +/* + this function unregisters driver from fs +*/ +static void sep_unregister_driver_from_fs(void) +{ + /*------------------- + CODE + ---------------------*/ + + cdev_del(&g_sep_cdev); + + /* unregister dev numbers */ + unregister_chrdev_region(g_sep_device_number, 1); +} + +/*-------------------------------------------------------------- + init function +----------------------------------------------------------------*/ +static int __init sep_init(void) +{ + /* return value */ + int ret_val; + + /* counter */ + int counter; + + /* size to of memory for allocation */ + int size; + + /*------------------------ + CODE + ------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:-------->Init start\n"); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, + "g_sep_shared_area_addr = %lx\n", + (unsigned long)&g_sep_shared_area_addr); + + ret_val = 0; + +/* transaction counter that coordinates the transactions between SEP + and HOST */ + sep_host_to_sep_send_counter = 0; + +/* counter for the messages from sep */ + sep_sep_to_host_reply_counter = 0; + +/* counter for the number of bytes allocated in the pool +for the current transaction */ + sep_data_pool_bytes_allocated = 0; + + /* set the starting mode to blocking */ + g_sep_block_mode_flag = 1; + + + ret_val = sep_register_driver_to_device(); + if (ret_val) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_driver:sep_driver_to_device failed, ret_val is %d\n", + ret_val); + goto end_function_unregister_from_fs; + } + + /* calculate the total size for allocation */ + size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; + + + + /* allocate the shared area */ + if (sep_map_and_alloc_shared_area(size, + &g_sep_shared_area_addr, + &g_sep_phys_shared_area_addr)) { + ret_val = -ENOMEM; + /* allocation failed */ + goto end_function_unmap_io_memory; + } + + /* now set the memory regions */ + g_message_shared_area_addr = g_sep_shared_area_addr; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: g_message_shared_area_addr is %08lx\n", + g_message_shared_area_addr); + +#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1) + + /* send the new SHARED MESSAGE AREA to the SEP */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_HOST_SEP_GPR1_REG_ADDR, + g_sep_phys_shared_area_addr); + + /* poll for SEP response */ + SEP_READ_REGISTER(g_sep_reg_base_address + HW_HOST_SEP_HOST_GPR1_REG_ADDR, + retVal); + while (retVal != 0xffffffff && retVal != g_sep_phys_shared_area_addr) + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR1_REG_ADDR, + retVal); + + /* check the return value (register) */ + if (retVal != g_sep_phys_shared_area_addr) { + ret_val = -ENOMEM; + goto end_function_deallocate_message_area; + } + +#endif + + /* init the flow contextes */ + for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++) + g_sep_flows_data_array[counter].flow_id = SEP_FREE_FLOW_ID; + + g_sep_flow_wq_ptr = create_singlethread_workqueue("sepflowwq"); + if (g_sep_flow_wq_ptr == 0) { + ret_val = -ENOMEM; + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "sep_driver:flow queue creation failed\n"); + goto end_function_deallocate_sep_shared_area; + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: create flow workqueue \n"); + + /* register driver to fs */ + ret_val = sep_register_driver_to_fs(); + if (ret_val) + goto end_function_deallocate_sep_shared_area; + + /* load the rom code */ + sep_load_rom_code(); + + goto end_function; + +end_function_unregister_from_fs: + + /* unregister from fs */ + sep_unregister_driver_from_fs(); + +end_function_deallocate_sep_shared_area: + + /* de-allocate shared area */ + sep_unmap_and_free_shared_area(size, + g_sep_shared_area_addr, + g_sep_phys_shared_area_addr); + +end_function_unmap_io_memory: + + iounmap((void *)g_sep_reg_base_address); + + /* release io memory region */ + release_mem_region(SEP_IO_MEM_REGION_START_ADDRESS, SEP_IO_MEM_REGION_SIZE); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:<-------- Init end\n"); + + return ret_val; +} + + + + +/*------------------------------------------------------------- + exit function +--------------------------------------------------------------*/ +static void __exit sep_exit(void) +{ + /* size */ + int size; + + /*----------------------------- + CODE + --------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:--------> Exit start\n"); + + /* unregister from fs */ + sep_unregister_driver_from_fs(); + + /* calculate the total size for de-allocation */ + size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; + + + /* free shared area */ + sep_unmap_and_free_shared_area(size, + g_sep_shared_area_addr, + g_sep_phys_shared_area_addr); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: free pages SEP SHARED AREA \n"); + + iounmap((void *)g_sep_reg_base_address); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver: iounmap \n"); + + /* release io memory region */ + release_mem_region(SEP_IO_MEM_REGION_START_ADDRESS, SEP_IO_MEM_REGION_SIZE); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver: release_mem_region \n"); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, "SEP Driver:<-------- Exit end\n"); +} + + +/* + interrupt handler function +*/ +irqreturn_t sep_inthandler(int irq, void *dev_id) +{ + /* int error */ + irqreturn_t int_error; + + /* error */ + unsigned long error; + + /* reg value */ + unsigned long reg_val; + + /* flow id */ + unsigned long flow_id; + + /* flow context */ + struct sep_flow_context_t *flow_context_ptr; + + /*----------------------------- + CODE + -----------------------------*/ + + int_error = IRQ_HANDLED; + + /* read the IRR register to check if this is SEP interrupt */ + SEP_READ_REGISTER(g_sep_reg_base_address + HW_HOST_IRR_REG_ADDR, reg_val); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "SEP Interrupt - reg is %08lx\n", + reg_val); + + /* check if this is the flow interrupt */ + if (0/*reg_val & (0x1 << 11)*/) { + /* read GPRO to find out the which flow is done */ + SEP_READ_REGISTER(g_sep_reg_base_address + HW_HOST_IRR_REG_ADDR, + flow_id); + + /* find the contex of the flow */ + error = sep_find_flow_context(flow_id >> 28, &flow_context_ptr); + if (error) + goto end_function_with_error; + + INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler); + + /* queue the work */ + queue_work(g_sep_flow_wq_ptr, &flow_context_ptr->flow_wq); + + } else { + /* check if this is reply interrupt from SEP */ + if (reg_val & (0x1 << 13)) { + /* update the counter of reply messages */ + sep_sep_to_host_reply_counter++; + + /* wake up the waiting process */ + wake_up(&g_sep_event); + } else { + int_error = IRQ_NONE; + goto end_function; + } + } + +end_function_with_error: + + /* clear the interrupt */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_ICR_REG_ADDR, reg_val); + +end_function: + + return int_error; +} + + +/* + This function prepares only input DMA table for synhronic symmetric + operations (HASH) +*/ +int sep_prepare_input_dma_table(unsigned long app_virt_addr, + unsigned long data_size, + unsigned long block_size, + unsigned long *lli_table_ptr, + unsigned long *num_entries_ptr, + unsigned long *table_data_size_ptr, + bool isKernelVirtualAddress) + +{ + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry_t *info_entry_ptr; + + /* array of pointers ot page */ + struct sep_lli_entry_t *lli_array_ptr; + + /* points to the first entry to be processed in the lli_in_array */ + unsigned long current_entry; + + /* num entries in the virtual buffer */ + unsigned long sep_lli_entries; + + /* lli table pointer */ + struct sep_lli_entry_t *in_lli_table_ptr; + + /* the total data in one table */ + unsigned long table_data_size; + + /* number of entries in lli table */ + unsigned long num_entries_in_table; + + /* next table address */ + unsigned long lli_table_alloc_addr; + + /* result */ + unsigned long result; + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_prepare_input_dma_table start\n"); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver:data_size is %lu\n", + data_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, "SEP Driver:block_size is %lu\n", + block_size); + + /* initialize the pages pointers */ + sep_in_page_array = 0; + sep_in_num_pages = 0; + + if (data_size == 0) { + /* special case - created 2 entries table with zero data */ + in_lli_table_ptr = (struct sep_lli_entry_t *)(g_sep_shared_area_addr + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES); + in_lli_table_ptr->physical_address = g_sep_shared_area_addr + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; + in_lli_table_ptr->block_size = 0; + + in_lli_table_ptr++; + in_lli_table_ptr->physical_address = 0xFFFFFFFF; + in_lli_table_ptr->block_size = 0; + + *lli_table_ptr = g_sep_phys_shared_area_addr + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; + *num_entries_ptr = 2; + *table_data_size_ptr = 0; + + goto end_function; + } + + /* check if the pages are in Kernel Virtual Address layout */ + if (isKernelVirtualAddress == true) + /* lock the pages of the kernel buffer and translate them to pages */ + result = sep_lock_kernel_pages(app_virt_addr, + data_size, + &sep_in_num_pages, + &lli_array_ptr, + &sep_in_page_array); + else + /* lock the pages of the user buffer and translate them to pages */ + result = sep_lock_user_pages(app_virt_addr, + data_size, + &sep_in_num_pages, + &lli_array_ptr, + &sep_in_page_array); + + if (result) + return result; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output sep_in_num_pages is %lu\n", + sep_in_num_pages); + + current_entry = 0; + info_entry_ptr = 0; + sep_lli_entries = sep_in_num_pages; + + /* initiate to point after the message area */ + lli_table_alloc_addr = g_sep_shared_area_addr + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; + + /* loop till all the entries in in array are not processed */ + while (current_entry < sep_lli_entries) { + /* set the new input and output tables */ + in_lli_table_ptr = (struct sep_lli_entry_t *)lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* calculate the maximum size of data for input table */ + table_data_size = sep_calculate_lli_table_max_size( + &lli_array_ptr[current_entry], + (sep_lli_entries - current_entry)); + + /* now calculate the table size so that it will be module block size */ + table_data_size = (table_data_size / block_size) * block_size; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output table_data_size is %lu\n", + table_data_size); + + /* construct input lli table */ + sep_build_lli_table(&lli_array_ptr[current_entry], + in_lli_table_ptr, + ¤t_entry, + &num_entries_in_table, + table_data_size); + + if (info_entry_ptr == 0) { + /* set the output parameters to physical addresses */ + *lli_table_ptr = sep_shared_area_virt_to_phys( + (unsigned long)in_lli_table_ptr); + *num_entries_ptr = num_entries_in_table; + *table_data_size_ptr = table_data_size; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output lli_table_in_ptr is %08lx\n", + *lli_table_ptr); + } else { + /* update the info entry of the previous in table */ + info_entry_ptr->physical_address = sep_shared_area_virt_to_phys( + (unsigned long)in_lli_table_ptr); + info_entry_ptr->block_size = ((num_entries_in_table) << 24) | + (table_data_size); + } + + /* save the pointer to the info entry of the current tables */ + info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; + } + + /* print input tables */ + sep_debug_print_lli_tables((struct sep_lli_entry_t *) + sep_shared_area_phys_to_virt(*lli_table_ptr), + *num_entries_ptr, + *table_data_size_ptr); + + /* the array of the pages */ + kfree(lli_array_ptr); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_prepare_input_dma_table end\n"); + + return 0; + +} + +/* + This function builds input and output DMA tables for synhronic + symmetric operations (AES, DES). It also checks that each table + is of the modular block size +*/ +int sep_prepare_input_output_dma_table(unsigned long app_virt_in_addr, + unsigned long app_virt_out_addr, + unsigned long data_size, + unsigned long block_size, + unsigned long *lli_table_in_ptr, + unsigned long *lli_table_out_ptr, + unsigned long *in_num_entries_ptr, + unsigned long *out_num_entries_ptr, + unsigned long *table_data_size_ptr, + bool isKernelVirtualAddress) + +{ + /* array of pointers of page */ + struct sep_lli_entry_t *lli_in_array; + + /* array of pointers of page */ + struct sep_lli_entry_t *lli_out_array; + + /* result */ + int result; + + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_prepare_input_output_dma_table start\n"); + + result = 0; + + /* initialize the pages pointers */ + sep_in_page_array = 0; + sep_out_page_array = 0; + + /* check if the pages are in Kernel Virtual Address layout */ + if (isKernelVirtualAddress == true) { + /* lock the pages of the kernel buffer and translate them to pages */ + result = sep_lock_kernel_pages(app_virt_in_addr, + data_size, + &sep_in_num_pages, + &lli_in_array, + &sep_in_page_array); + if (result) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n"); + goto end_function; + } + } else { + /* lock the pages of the user buffer and translate them to pages */ + result = sep_lock_user_pages(app_virt_in_addr, + data_size, + &sep_in_num_pages, + &lli_in_array, + &sep_in_page_array); + if (result) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep_lock_user_pages for input virtual buffer failed\n"); + goto end_function; + } + } + + if (isKernelVirtualAddress == true) { + result = sep_lock_kernel_pages(app_virt_out_addr, + data_size, + &sep_out_num_pages, + &lli_out_array, + &sep_out_page_array); + if (result) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n"); + goto end_function_with_error1; + } + } else { + result = sep_lock_user_pages(app_virt_out_addr, + data_size, + &sep_out_num_pages, + &lli_out_array, + &sep_out_page_array); + if (result) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep_lock_user_pages for output virtual buffer failed\n"); + goto end_function_with_error1; + } + } + + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_in_num_pages is %lu\n", sep_in_num_pages); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "sep_out_num_pages is %lu\n", sep_out_num_pages); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + + /* call the fucntion that creates table from the lli arrays */ + result = sep_construct_dma_tables_from_lli(lli_in_array, + sep_in_num_pages, + lli_out_array, + sep_out_num_pages, + block_size, + lli_table_in_ptr, + lli_table_out_ptr, + in_num_entries_ptr, + out_num_entries_ptr, + table_data_size_ptr); + if (result) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: sep_construct_dma_tables_from_lli failed\n"); + goto end_function_with_error2; + } + + /* fall through - free the lli entry arrays */ + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, "in_num_entries_ptr is %08lx\n", + *in_num_entries_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, "out_num_entries_ptr is %08lx\n", + *out_num_entries_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, "table_data_size_ptr is %08lx\n", + *table_data_size_ptr); + + +end_function_with_error2: + + kfree(lli_out_array); + +end_function_with_error1: + + kfree(lli_in_array); + +end_function: + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, +"SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", +(int)result); + + return result; + +} + + +/* + This function creates the input and output dma tables for + symmetric operations (AES/DES) according to the block size from LLI arays +*/ +int sep_construct_dma_tables_from_lli(struct sep_lli_entry_t *lli_in_array, + unsigned long sep_in_lli_entries, + struct sep_lli_entry_t *lli_out_array, + unsigned long sep_out_lli_entries, + unsigned long block_size, + unsigned long *lli_table_in_ptr, + unsigned long *lli_table_out_ptr, + unsigned long *in_num_entries_ptr, + unsigned long *out_num_entries_ptr, + unsigned long *table_data_size_ptr) +{ + /* points to the area where next lli table can be allocated */ + unsigned long lli_table_alloc_addr; + + /* input lli table */ + struct sep_lli_entry_t *in_lli_table_ptr; + + /* output lli table */ + struct sep_lli_entry_t *out_lli_table_ptr; + + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry_t *info_in_entry_ptr; + + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry_t *info_out_entry_ptr; + + /* points to the first entry to be processed in the lli_in_array */ + unsigned long current_in_entry; + + /* points to the first entry to be processed in the lli_out_array */ + unsigned long current_out_entry; + + /* max size of the input table */ + unsigned long in_table_data_size; + + /* max size of the output table */ + unsigned long out_table_data_size; + + /* flag te signifies if this is the first tables build from the arrays */ + unsigned long first_table_flag; + + /* the data size that should be in table */ + unsigned long table_data_size; + + /* number of etnries in the input table */ + unsigned long num_entries_in_table; + + /* number of etnries in the output table */ + unsigned long num_entries_out_table; + + /*--------------------- + CODE + ------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_construct_dma_tables_from_lli start\n"); + + /* initiate to pint after the message area */ + lli_table_alloc_addr = g_sep_shared_area_addr + + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; + + current_in_entry = 0; + current_out_entry = 0; + first_table_flag = 1; + info_in_entry_ptr = 0; + info_out_entry_ptr = 0; + + /* loop till all the entries in in array are not processed */ + while (current_in_entry < sep_in_lli_entries) { + /* set the new input and output tables */ + in_lli_table_ptr = (struct sep_lli_entry_t *)lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* set the first output tables */ + out_lli_table_ptr = (struct sep_lli_entry_t *)lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* calculate the maximum size of data for input table */ + in_table_data_size = + sep_calculate_lli_table_max_size( + &lli_in_array[current_in_entry], + (sep_in_lli_entries - current_in_entry)); + + /* calculate the maximum size of data for output table */ + out_table_data_size = + sep_calculate_lli_table_max_size( + &lli_out_array[current_out_entry], + (sep_out_lli_entries - current_out_entry)); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:in_table_data_size is %lu\n", in_table_data_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:out_table_data_size is %lu\n", out_table_data_size); + + /* check where the data is smallest */ + table_data_size = in_table_data_size; + if (table_data_size > out_table_data_size) + table_data_size = out_table_data_size; + + /* now calculate the table size so that it will be module block size */ + table_data_size = (table_data_size / block_size) * block_size; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:table_data_size is %lu\n", + table_data_size); + + /* construct input lli table */ + sep_build_lli_table(&lli_in_array[current_in_entry], + in_lli_table_ptr, + ¤t_in_entry, + &num_entries_in_table, + table_data_size); + + /* construct output lli table */ + sep_build_lli_table(&lli_out_array[current_out_entry], + out_lli_table_ptr, + ¤t_out_entry, + &num_entries_out_table, + table_data_size); + + /* if info entry is null - this is the first table built */ + if (info_in_entry_ptr == 0) { + /* set the output parameters to physical addresses */ + *lli_table_in_ptr = + sep_shared_area_virt_to_phys((unsigned long)in_lli_table_ptr); + *in_num_entries_ptr = num_entries_in_table; + *lli_table_out_ptr = + sep_shared_area_virt_to_phys((unsigned long)out_lli_table_ptr); + *out_num_entries_ptr = num_entries_out_table; + *table_data_size_ptr = table_data_size; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr); + } else { + /* update the info entry of the previous in table */ + info_in_entry_ptr->physical_address = + sep_shared_area_virt_to_phys((unsigned long)in_lli_table_ptr); + info_in_entry_ptr->block_size = + ((num_entries_in_table) << 24) | (table_data_size); + + /* update the info entry of the previous in table */ + info_out_entry_ptr->physical_address = + sep_shared_area_virt_to_phys((unsigned long)out_lli_table_ptr); + info_out_entry_ptr->block_size = + ((num_entries_out_table) << 24) | (table_data_size); + } + + /* save the pointer to the info entry of the current tables */ + info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; + info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output num_entries_out_table is %lu\n", + (unsigned long)num_entries_out_table); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output info_in_entry_ptr is %lu\n", + (unsigned long)info_in_entry_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:output info_out_entry_ptr is %lu\n", + (unsigned long)info_out_entry_ptr); + } + + /* print input tables */ + sep_debug_print_lli_tables( + (struct sep_lli_entry_t *) + sep_shared_area_phys_to_virt(*lli_table_in_ptr), + *in_num_entries_ptr, + *table_data_size_ptr); + + /* print output tables */ + sep_debug_print_lli_tables( + (struct sep_lli_entry_t *) + sep_shared_area_phys_to_virt(*lli_table_out_ptr), + *out_num_entries_ptr, + *table_data_size_ptr); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n"); + + return 0; +} + +/* + this function calculates the size of data that can be inserted into the lli + table from this array the condition is that either the table is full + (all etnries are entered), or there are no more entries in the lli array +*/ +unsigned long sep_calculate_lli_table_max_size( + struct sep_lli_entry_t *lli_in_array_ptr, + unsigned long num_array_entries) +{ + /* table data size */ + unsigned long table_data_size; + + /* counter */ + unsigned long counter; + + /*--------------------- + CODE + ----------------------*/ + + table_data_size = 0; + + /* calculate the data in the out lli table if till we fill the whole + table or till the data has ended */ + for (counter = 0; + (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && + (counter < num_array_entries); counter++) + table_data_size += lli_in_array_ptr[counter].block_size; + + return table_data_size; +} + +/* + this functions builds ont lli table from the lli_array according to + the given size of data +*/ +static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, + struct sep_lli_entry_t *lli_table_ptr, + unsigned long *num_processed_entries_ptr, + unsigned long *num_table_entries_ptr, + unsigned long table_data_size) +{ + /* current table data size */ + unsigned long curr_table_data_size; + + /* counter of lli array entry */ + unsigned long array_counter; + + /*----------------------- + CODE + ---------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_build_lli_table start\n"); + + /* init currrent table data size and lli array entry counter */ + curr_table_data_size = 0; + array_counter = 0; + *num_table_entries_ptr = 1; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:table_data_size is %lu\n", + table_data_size); + + /* fill the table till table size reaches the needed amount */ + while (curr_table_data_size < table_data_size) { + /* update the number of entries in table */ + (*num_table_entries_ptr)++; + + lli_table_ptr->physical_address = + lli_array_ptr[array_counter].physical_address; + lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size; + curr_table_data_size += lli_table_ptr->block_size; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr is %08lx\n", + (unsigned long)lli_table_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->physical_address is %08lx\n", + lli_table_ptr->physical_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->block_size is %lu\n", + lli_table_ptr->block_size); + + /* check for overflow of the table data */ + if (curr_table_data_size > table_data_size) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:curr_table_data_size > table_data_size\n"); + + /* update the size of block in the table */ + lli_table_ptr->block_size -= (curr_table_data_size - table_data_size); + + /* update the physical address in the lli array */ + lli_array_ptr[array_counter].physical_address += + lli_table_ptr->block_size; + + /* update the block size left in the lli array */ + lli_array_ptr[array_counter].block_size = + (curr_table_data_size - table_data_size); + } else + /* advance to the next entry in the lli_array */ + array_counter++; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->physical_address is %08lx\n", + lli_table_ptr->physical_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->block_size is %lu\n", + lli_table_ptr->block_size); + + /* move to the next entry in table */ + lli_table_ptr++; + } + + /* set the info entry to default */ + lli_table_ptr->physical_address = 0xffffffff; + lli_table_ptr->block_size = 0; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr is %08lx\n", + (unsigned long)lli_table_ptr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->physical_address is %08lx\n", + lli_table_ptr->physical_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr->block_size is %lu\n", + lli_table_ptr->block_size); + + + /* set the output parameter */ + *num_processed_entries_ptr += array_counter; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:*num_processed_entries_ptr is %lu\n", + *num_processed_entries_ptr); + + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_build_lli_table end\n"); + + return; +} + +/* + this function goes over the list of the print created tables and + prints all the data +*/ +static void sep_debug_print_lli_tables(struct sep_lli_entry_t *lli_table_ptr, + unsigned long num_table_entries, + unsigned long table_data_size) +{ + unsigned long table_count; + + unsigned long entries_count; + /*----------------------------- + CODE + -------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_debug_print_lli_tables start\n"); + + table_count = 1; + while ((unsigned long)lli_table_ptr != 0xffffffff) { + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: lli table %08lx, table_data_size is %lu\n", + table_count, + table_data_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: num_table_entries is %lu\n", num_table_entries); + + /* print entries of the table (without info entry) */ + for (entries_count = 0; + entries_count < num_table_entries; + entries_count++, lli_table_ptr++) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:lli_table_ptr address is %08lx\n", + (unsigned long)lli_table_ptr); + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:phys address is %08lx block size is %lu\n", + lli_table_ptr->physical_address, lli_table_ptr->block_size); + } + + /* point to the info entry */ + lli_table_ptr--; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:phys lli_table_ptr->block_size is %lu\n", + lli_table_ptr->block_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", + lli_table_ptr->physical_address); + + + table_data_size = lli_table_ptr->block_size & 0xffffff; + num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; + lli_table_ptr = (struct sep_lli_entry_t *) + (lli_table_ptr->physical_address); + + DEBUG_PRINT_3(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:phys table_data_size is %lu num_table_entries is \ + %lu lli_table_ptr is%lu\n", + table_data_size, num_table_entries, (unsigned long)lli_table_ptr); + + if ((unsigned long)lli_table_ptr != 0xffffffff) + lli_table_ptr = (struct sep_lli_entry_t *)sep_shared_area_phys_to_virt( + (unsigned long)lli_table_ptr); + + table_count++; + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_debug_print_lli_tables end\n"); +} + + +/* + This function locks all the physical pages of the application virtual buffer + and construct a basic lli array, where each entry holds the physical page + address and the size that application data holds in this physical pages +*/ +int sep_lock_user_pages(unsigned long app_virt_addr, + unsigned long data_size, + unsigned long *num_pages_ptr, + struct sep_lli_entry_t **lli_array_ptr, + struct page ***page_array_ptr) + +{ + /* error */ + int error; + + /* the the page of the end address of the user space buffer */ + unsigned long end_page; + + /* the page of the start address of the user space buffer */ + unsigned long start_page; + + /* the range in pages */ + unsigned long num_pages; + + /* array of pointers ot page */ + struct page **page_array; + + /* array of lli */ + struct sep_lli_entry_t *lli_array; + + /* count */ + unsigned long count; + + /* result */ + int result; + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_lock_user_pages start\n"); + + error = 0; + + /* set start and end pages and num pages */ + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = app_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: app_virt_addr is %08lx\n", + app_virt_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: data_size is %lu\n", + data_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: start_page is %lu\n", + start_page); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: end_page is %lu\n", + end_page); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: num_pages is %lu\n", + num_pages); + + /* allocate array of pages structure pointers */ + page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); + if (!page_array) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: kmalloc for page_array failed\n"); + + error = -ENOMEM; + goto end_function; + } + + lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); + if (!lli_array) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: kmalloc for lli_array failed\n"); + + error = -ENOMEM; + goto end_function_with_error1; + } + + /* convert the application virtual address into a set of physical */ + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, + page_array, + 0); + up_read(¤t->mm->mmap_sem); + + /* check the number of pages locked - if not all then exit with error */ + if (result != num_pages) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver: not all pages locked by get_user_pages\n"); + + error = -ENOMEM; + goto end_function_with_error2; + } + + /* flush the cache */ + for (count = 0; count < num_pages; count++) + flush_dcache_page(page_array[count]); + + /* set the start address of the first page - app data may start not at + the beginning of the page */ + lli_array[0].physical_address = ( + (unsigned long)page_to_phys(page_array[0])) + + (app_virt_addr & (~PAGE_MASK)) ; + + /* check that not all the data is in the first page only */ + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); + + /* debug print */ + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", + lli_array[0].physical_address, + lli_array[0].block_size); + + /* go from the second page to the prev before last */ + for (count = 1; count < (num_pages - 1); count++) { + lli_array[count].physical_address = + (unsigned long)page_to_phys(page_array[count]); + lli_array[count].block_size = PAGE_SIZE; + + DEBUG_PRINT_4(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[%lu].physical_address is %08lx, \ + lli_array[%lu].block_size is %lu\n", + count, lli_array[count].physical_address, + count, + lli_array[count].block_size); + } + + /* if more then 1 pages locked - then update for the last page size needed */ + if (num_pages > 1) { + /* update the address of the last page */ + lli_array[count].physical_address = + (unsigned long)page_to_phys(page_array[count]); + + /* set the size of the last page */ + lli_array[count].block_size = (app_virt_addr + data_size) & + (~PAGE_MASK); + + if (lli_array[count].block_size == 0) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, + "app_virt_addr is %08lx\n", + app_virt_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, "data_size is %lu\n", data_size); + while (1); + } + DEBUG_PRINT_4(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[%lu].physical_address is %08lx, \ + lli_array[%lu].block_size is %lu\n", + count, lli_array[count].physical_address, + count, + lli_array[count].block_size); + } + + /* set output params */ + *lli_array_ptr = lli_array; + *num_pages_ptr = num_pages; + *page_array_ptr = page_array; + + goto end_function; + +end_function_with_error2: + + /* release the cache */ + for (count = 0; count < num_pages; count++) + page_cache_release(page_array[count]); + + /* free lli array */ + kfree(lli_array); + +end_function_with_error1: + + /* free page array */ + kfree(page_array); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_lock_user_pages end\n"); + + return 0; +} + +/* + This function locks all the physical pages of the kernel virtual buffer + and construct a basic lli array, where each entry holds the physical + page address and the size that application data holds in this physical pages +*/ +int sep_lock_kernel_pages(unsigned long kernel_virt_addr, + unsigned long data_size, + unsigned long *num_pages_ptr, + struct sep_lli_entry_t **lli_array_ptr, + struct page ***page_array_ptr) + +{ + /* error */ + int error; + + /* the the page of the end address of the user space buffer */ + unsigned long end_page; + + /* the page of the start address of the user space buffer */ + unsigned long start_page; + + /* the range in pages */ + unsigned long num_pages; + + /* array of lli */ + struct sep_lli_entry_t *lli_array; + + /* next kernel address to map */ + unsigned long next_kernel_address; + + /* count */ + unsigned long count; + + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_lock_kernel_pages start\n"); + + error = 0; + + /* set start and end pages and num pages */ + end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = kernel_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: kernel_virt_addr is %08lx\n", + kernel_virt_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: data_size is %lu\n", + data_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: start_page is %lx\n", + start_page); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: end_page is %lx\n", + end_page); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: num_pages is %lu\n", + num_pages); + + lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); + if (!lli_array) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver: kmalloc for lli_array failed\n"); + + error = -ENOMEM; + goto end_function; + } + + /* set the start address of the first page - app data may start not at + the beginning of the page */ + lli_array[0].physical_address = + (unsigned long)virt_to_phys((unsigned long *)kernel_virt_addr); + + /* check that not all the data is in the first page only */ + if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = + PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK)); + + /* debug print */ + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", + lli_array[0].physical_address, + lli_array[0].block_size); + + /* advance the address to the start of the next page */ + next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE; + + /* go from the second page to the prev before last */ + for (count = 1; count < (num_pages - 1); count++) { + lli_array[count].physical_address = + (unsigned long)virt_to_phys((unsigned long *)next_kernel_address); + lli_array[count].block_size = PAGE_SIZE; + + DEBUG_PRINT_4(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[%lu].physical_address is %08lx, \ + lli_array[%lu].block_size is %lu\n", + count, lli_array[count].physical_address, count, + lli_array[count].block_size); + + next_kernel_address += PAGE_SIZE; + } + + /* if more then 1 pages locked - then update for the last page size needed */ + if (num_pages > 1) { + /* update the address of the last page */ + lli_array[count].physical_address = + (unsigned long)virt_to_phys((unsigned long *)next_kernel_address); + + /* set the size of the last page */ + lli_array[count].block_size = + (kernel_virt_addr + data_size) & (~PAGE_MASK); + + if (lli_array[count].block_size == 0) { + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, + "app_virt_addr is %08lx\n", + kernel_virt_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_BASIC, "data_size is %lu\n", data_size); + while (1); + } + + DEBUG_PRINT_4(SEP_DEBUG_LEVEL_EXTENDED, + "lli_array[%lu].physical_address is %08lx, \ + lli_array[%lu].block_size is %lu\n", + count, lli_array[count].physical_address, + count, + lli_array[count].block_size); + } + + /* set output params */ + *lli_array_ptr = lli_array; + *num_pages_ptr = num_pages; + *page_array_ptr = 0; + + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_lock_kernel_pages end\n"); + + return 0; +} + +/* + This function releases all the application virtual buffer physical pages, + that were previously locked +*/ +int sep_free_dma_pages(struct page **page_array_ptr, + unsigned long num_pages, + unsigned long dirtyFlag) +{ + /* count */ + unsigned long count; + + /*------------------- + CODE + ---------------------*/ + + if (dirtyFlag) { + for (count = 0; count < num_pages; count++) { + /* the out array was written, therefore the data was changed */ + if (!PageReserved(page_array_ptr[count])) + SetPageDirty(page_array_ptr[count]); + page_cache_release(page_array_ptr[count]); + } + } else { + /* free in pages - the data was only read, therefore no update was done + on those pages */ + for (count = 0; count < num_pages; count++) + page_cache_release(page_array_ptr[count]); + } + + if (page_array_ptr) + /* free the array */ + kfree(page_array_ptr); + + return 0; +} + +/* + This function raises interrupt to SEP that signals that is has a new + command from HOST +*/ +static void sep_send_command_handler() +{ + + unsigned long count; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_send_command_handler start\n"); + + sep_set_time(0, 0); + + /* flash cache */ + flush_cache_all(); + + for (count = 0; count < 12 * 4; count += 4) + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "Word %lu of the message is %lu\n", + count, + *((unsigned long *)(g_sep_shared_area_addr + count))); + + /* update counter */ + sep_host_to_sep_send_counter++; + + /* send interrupt to SEP */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_send_command_handler end\n"); + + return; +} + +/* + This function raises interrupt to SEPm that signals that is has a + new command from HOST +*/ +static void sep_send_reply_command_handler() +{ + unsigned long count; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_send_reply_command_handler start\n"); + + /* flash cache */ + flush_cache_all(); + + for (count = 0; count < 12 * 4; count += 4) + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "Word %lu of the message is %lu\n", + count, + *((unsigned long *)(g_sep_shared_area_addr + count))); + + + /* update counter */ + sep_host_to_sep_send_counter++; + + /* send the interrupt to SEP */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_HOST_SEP_GPR2_REG_ADDR, + sep_host_to_sep_send_counter); + + /* update both counters */ + sep_host_to_sep_send_counter++; + + sep_sep_to_host_reply_counter++; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_send_reply_command_handler end\n"); + + return; +} + + + +/* + This function handles the allocate data pool memory request + This function returns calculates the physical address of the + allocated memory, and the offset of this area from the mapped address. + Therefore, the FVOs in user space can calculate the exact virtual + address of this allocated memory +*/ +static int sep_allocate_data_pool_memory_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command paramaters */ + struct sep_driver_alloc_t command_args; + + /*------------------------- + CODE + ----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n"); + + + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_alloc_t)); + if (error) + goto end_function; + + /* allocate memory */ + if ( + (sep_data_pool_bytes_allocated + command_args.num_bytes) > + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { + error = -ENOTTY; + goto end_function; + } + + /* set the virtual and physical address */ + command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + + sep_data_pool_bytes_allocated; + command_args.phys_address = g_sep_phys_shared_area_addr + + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + + sep_data_pool_bytes_allocated; + + /* write the memory back to the user space */ + error = copy_to_user((void *)arg, + (void *)&command_args, + sizeof(struct sep_driver_alloc_t)); + if (error) + goto end_function; + + /* set the allocation */ + sep_data_pool_bytes_allocated += command_args.num_bytes; + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n"); + + return error; +} + +/* + This function handles write into allocated data pool command +*/ +static int sep_write_into_data_pool_handler(unsigned long arg) +{ + /* error */ + int error; + + /* virtual address */ + unsigned long virt_address; + + /* application in address */ + unsigned long app_in_address; + + /* number of bytes */ + unsigned long num_bytes; + + /* address of the data pool */ + unsigned long data_pool_area_addr; + + /*-------------------------- + CODE + -----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_write_into_data_pool_handler start\n"); + + /* get the application address */ + error = get_user(app_in_address, + &(((struct sep_driver_write_t *)arg)->app_address)); + if (error) + goto end_function; + + /* get the virtual kernel address address */ + error = get_user(virt_address, + &(((struct sep_driver_write_t *)arg)->datapool_address)); + if (error) + goto end_function; + + /* get the number of bytes */ + error = get_user(num_bytes, &(((struct sep_driver_write_t *)arg)->num_bytes)); + if (error) + goto end_function; + + /* calculate the start of the data pool */ + data_pool_area_addr = g_sep_shared_area_addr + + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; + + + /* check that the range of the virtual kernel address is correct */ + if ((virt_address < data_pool_area_addr) || + (virt_address > (data_pool_area_addr + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES))) { + error = -ENOTTY; + goto end_function; + } + + /* copy the application data */ + error = copy_from_user((void *)virt_address, + (void *)app_in_address, + num_bytes); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_write_into_data_pool_handler end\n"); + + return error; +} + +/* + this function handles the read from data pool command +*/ +static int sep_read_from_data_pool_handler(unsigned long arg) +{ + /* error */ + int error; + + /* virtual address of dest application buffer */ + unsigned long app_out_address; + + /* virtual address of the data pool */ + unsigned long virt_address; + + /* number bytes */ + unsigned long num_bytes; + + /* address of the data pool */ + unsigned long data_pool_area_addr; + + /*------------------------ + CODE + -----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_read_from_data_pool_handler start\n"); + + /* get the application address */ + error = get_user(app_out_address, + &(((struct sep_driver_write_t *)arg)->app_address)); + if (error) + goto end_function; + + /* get the virtual kernel address address */ + error = get_user(virt_address, + &(((struct sep_driver_write_t *)arg)->datapool_address)); + if (error) + goto end_function; + + /* get the number of bytes */ + error = get_user(num_bytes, &(((struct sep_driver_write_t *)arg)->num_bytes)); + if (error) + goto end_function; + + /* calculate the start of the data pool */ + data_pool_area_addr = g_sep_shared_area_addr + + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; + + /* check that the range of the virtual kernel address is correct */ + if ((virt_address < data_pool_area_addr) || + (virt_address > (data_pool_area_addr + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES))) { + error = -ENOTTY; + goto end_function; + } + + /* copy the application data */ + error = copy_to_user((void *)app_out_address, (void *)virt_address, + num_bytes); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_read_from_data_pool_handler end\n"); + + return error; +} + + +/* + this function handles tha request for creation of the DMA table + for the synchronic symmetric operations (AES,DES) +*/ +static int sep_create_sync_dma_tables_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command arguments */ + struct sep_driver_build_sync_table_t command_args; + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_create_sync_dma_tables_handler start\n"); + + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_build_sync_table_t)); + if (error) + goto end_function; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "app_in_address is %08lx\n", + command_args.app_in_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "app_out_address is %08lx\n", + command_args.app_out_address); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "data_size is %lu\n", + command_args.data_in_size); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "block_size is %lu\n", + command_args.block_size); + + + /* check if we need to build only input table or input/output */ + if (command_args.app_out_address) + /* prepare input and output tables */ + error = sep_prepare_input_output_dma_table(command_args.app_in_address, + command_args.app_out_address, + command_args.data_in_size, + command_args.block_size, + &command_args.in_table_address, + &command_args.out_table_address, + &command_args.in_table_num_entries, + &command_args.out_table_num_entries, + &command_args.table_data_size, + command_args.isKernelVirtualAddress); + else + /* prepare input tables */ + error = sep_prepare_input_dma_table(command_args.app_in_address, + command_args.data_in_size, + command_args.block_size, + &command_args.in_table_address, + &command_args.in_table_num_entries, + &command_args.table_data_size, + command_args.isKernelVirtualAddress); + + if (error) + goto end_function; + + /* copy to user */ + error = copy_to_user((void *)arg, + (void *)&command_args, + sizeof(struct sep_driver_build_sync_table_t)); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n"); + + return error; +} + +/* + this function handles the request for freeing dma table for synhronic actions +*/ +int sep_free_dma_table_data_handler() +{ + /*------------------------- + CODE + -----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_free_dma_table_data_handler start\n"); + + /* free input pages array */ + sep_free_dma_pages(sep_in_page_array, + sep_in_num_pages, + 0); + + /* free output pages array if needed */ + if (sep_out_page_array) + sep_free_dma_pages(sep_out_page_array, + sep_out_num_pages, + 1); + + /* reset all the values */ + sep_in_page_array = 0; + sep_out_page_array = 0; + sep_in_num_pages = 0; + sep_out_num_pages = 0; + + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_free_dma_table_data_handler end\n"); + + return 0; +} + +/* + this function handles the request to create the DMA tables for flow +*/ +static int sep_create_flow_dma_tables_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command arguments */ + struct sep_driver_build_flow_table_t command_args; + + /* first table - output */ + struct sep_lli_entry_t first_table_data; + + /* dma table data */ + struct sep_lli_entry_t last_table_data; + + /* pointer to the info entry of the previuos DMA table */ + struct sep_lli_entry_t *prev_info_entry_ptr; + + /* pointer to the flow data strucutre */ + struct sep_flow_context_t *flow_context_ptr; + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_create_flow_dma_tables_handler start\n"); + + /* init variables */ + prev_info_entry_ptr = 0; + first_table_data.physical_address = 0xffffffff; + + /* find the free structure for flow data */ + error = sep_find_flow_context(SEP_FREE_FLOW_ID, &flow_context_ptr); + if (error) + goto end_function; + + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_build_flow_table_t)); + if (error) + goto end_function; + + /* create flow tables */ + error = sep_prepare_flow_dma_tables(command_args.num_virtual_buffers, + command_args.virt_buff_data_addr, + flow_context_ptr, + &first_table_data, + &last_table_data, + command_args.isKernelVirtualAddress); + if (error) + goto end_function_with_error; + + /* check if flow is static */ + if (!command_args.flow_type) + /* point the info entry of the last to the info entry of the first */ + last_table_data = first_table_data; + + /* set output params */ + command_args.first_table_addr = first_table_data.physical_address; + command_args.first_table_num_entries = + ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & + SEP_NUM_ENTRIES_MASK); + command_args.first_table_data_size = + (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); + + /* send the parameters to user application */ + error = copy_to_user((void *)arg, + &command_args, + sizeof(struct sep_driver_build_flow_table_t)); + if (error) + goto end_function_with_error; + + /* all the flow created - update the flow entry with temp id */ + flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID; + + /* set the processing tables data in the context */ + if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG) + flow_context_ptr->input_tables_in_process = first_table_data; + else + flow_context_ptr->output_tables_in_process = first_table_data; + + goto end_function; + +end_function_with_error: + + /* free the allocated tables */ + sep_deallocated_flow_tables(&first_table_data); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n"); + + return error; + +} + +/* + this functio n handles add tables to flow +*/ +static int sep_add_flow_tables_handler(unsigned long arg) +{ + /* error */ + int error; + + /* number of entries */ + unsigned long num_entries; + + /* command arguments */ + struct sep_driver_add_flow_table_t command_args; + + /* pointer to the flow data strucutre */ + struct sep_flow_context_t *flow_context_ptr; + + /* first dma table data */ + struct sep_lli_entry_t first_table_data; + + /* last dma table data */ + struct sep_lli_entry_t last_table_data; + + /* pointer to the info entry of the current DMA table */ + struct sep_lli_entry_t *info_entry_ptr; + + /*-------------------------- + CODE + ----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_add_flow_tables_handler start\n"); + + /* get input parameters */ + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_add_flow_table_t)); + if (error) + goto end_function; + + /* find the flow structure for the flow id */ + error = sep_find_flow_context(command_args.flow_id, &flow_context_ptr); + if (error) + goto end_function; + + /* prepare the flow dma tables */ + error = sep_prepare_flow_dma_tables(command_args.num_virtual_buffers, + command_args.virt_buff_data_addr, + flow_context_ptr, + &first_table_data, + &last_table_data, + command_args.isKernelVirtualAddress); + if (error) + goto end_function_with_error; + + /* now check if there is already an existing add table for this flow */ + if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) { + /* this buffer was for input buffers */ + if (flow_context_ptr->input_tables_flag) { + /* add table already exists - add the new tables to the end + of the previous */ + num_entries = (flow_context_ptr->last_input_table.block_size >> + SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; + + info_entry_ptr = + (struct sep_lli_entry_t *) + (flow_context_ptr->last_input_table.physical_address + + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); + + /* connect to list of tables */ + *info_entry_ptr = first_table_data; + + /* set the first table data */ + first_table_data = flow_context_ptr->first_input_table; + } else { + /* set the input flag */ + flow_context_ptr->input_tables_flag = 1; + + /* set the first table data */ + flow_context_ptr->first_input_table = first_table_data; + } + /* set the last table data */ + flow_context_ptr->last_input_table = last_table_data; + } else /* this is output tables */ { + /* this buffer was for input buffers */ + if (flow_context_ptr->output_tables_flag) { + /* add table already exists - add the new tables to + the end of the previous */ + num_entries = (flow_context_ptr->last_output_table.block_size >> + SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; + + info_entry_ptr = + (struct sep_lli_entry_t *) + (flow_context_ptr->last_output_table.physical_address + + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); + + /* connect to list of tables */ + *info_entry_ptr = first_table_data; + + /* set the first table data */ + first_table_data = flow_context_ptr->first_output_table; + } else { + /* set the input flag */ + flow_context_ptr->output_tables_flag = 1; + + /* set the first table data */ + flow_context_ptr->first_output_table = first_table_data; + } + /* set the last table data */ + flow_context_ptr->last_output_table = last_table_data; + } + + /* set output params */ + command_args.first_table_addr = first_table_data.physical_address; + command_args.first_table_num_entries = ((first_table_data.block_size >> + SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); + command_args.first_table_data_size = + (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); + + /* send the parameters to user application */ + error = copy_to_user((void *)arg, + &command_args, + sizeof(struct sep_driver_add_flow_table_t)); + if (error) + goto end_function_with_error; + +end_function_with_error: + + /* free the allocated tables */ + sep_deallocated_flow_tables(&first_table_data); + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_add_flow_tables_handler end\n"); + + return error; +} + +/* + this function add the flow add message to the specific flow +*/ +static int sep_add_flow_tables_message_handler(unsigned long arg) +{ + /* error */ + int error; + + /* arguments */ + struct sep_driver_add_message_t command_args; + + /* flow context */ + struct sep_flow_context_t *flow_context_ptr; + + /*---------------------------- + CODE + ------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_add_flow_tables_message_handler start\n"); + + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_add_message_t)); + if (error) + goto end_function; + + /* check input */ + if (command_args.message_size_in_bytes > + SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) { + error = -ENOMEM; + goto end_function; + } + + /* find the flow context */ + error = sep_find_flow_context(command_args.flow_id, &flow_context_ptr); + if (error) + goto end_function; + + /* copy the message into context */ + flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes; + + error = copy_from_user(flow_context_ptr->message, + (void *)command_args.message_address, + command_args.message_size_in_bytes); + + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_add_flow_tables_message_handler end\n"); + + return error; +} + + +/* + this function returns the physical and virtual addresses of the static pool +*/ +static int sep_get_static_pool_addr_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command arguments */ + struct sep_driver_static_pool_addr_t command_args; + + /*----------------------------- + CODE + ------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_get_static_pool_addr_handler start\n"); + + /*prepare the output parameters in the struct */ + command_args.physical_static_address = g_sep_phys_shared_area_addr + + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; + command_args.virtual_static_address = g_sep_shared_area_addr + + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; + + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:physical_static_address is %08lx, virtual_static_address %08lx\n", + command_args.physical_static_address, + command_args.virtual_static_address); + + /* send the parameters to user application */ + error = copy_to_user((void *)arg, + &command_args, + sizeof(struct sep_driver_static_pool_addr_t)); + if (error) + goto end_function; + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_get_static_pool_addr_handler end\n"); + + return error; +} + +/* + this address gets the offset of the physical address from the start + of the mapped area +*/ +static int sep_get_physical_mapped_offset_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command arguments */ + struct sep_driver_get_mapped_offset_t command_args; + + /*----------------------------- + CODE + ------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n"); + + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_get_mapped_offset_t)); + if (error) + goto end_function; + + if (command_args.physical_address < g_sep_phys_shared_area_addr) { + error = -ENOTTY; + goto end_function; + } + + /*prepare the output parameters in the struct */ + command_args.offset = command_args.physical_address - + g_sep_phys_shared_area_addr; + + DEBUG_PRINT_2(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:physical_address is %08lx, offset is %lu\n", + command_args.physical_address, + command_args.offset); + + /* send the parameters to user application */ + error = copy_to_user((void *)arg, + &command_args, + sizeof(struct sep_driver_get_mapped_offset_t)); + if (error) + goto end_function; + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n"); + + return error; +} + + +/* + ? +*/ +static int sep_start_handler(void) +{ + /* reg val */ + unsigned long reg_val; + + /* error */ + unsigned long error; + + /*----------------------------- + CODE + ------------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_start_handler start\n"); + + error = 0; + + /* wait in polling for message from SEP */ + do { + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR3_REG_ADDR, reg_val); + } while (!reg_val); + + /* check the value */ + if (reg_val == 0x1) { + /* fatal error - read erro status from GPRO */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, error); + goto end_function; + } + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_start_handler end\n"); + + return error; +} + +/* + this function handles the request for SEP initialization +*/ +static int sep_init_handler(unsigned long arg) +{ + /* word from message */ + unsigned long message_word; + + /* message ptr */ + unsigned long *message_ptr; + + /* command arguments */ + struct sep_driver_init_t command_args; + + /* counter */ + unsigned long counter; + + /* error */ + unsigned long error; + + /* reg val */ + unsigned long reg_val; + + /*------------------- + CODE + ---------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_init_handler start\n"); + + error = 0; + + error = copy_from_user(&command_args, (void *)arg, + sizeof(struct sep_driver_init_t)); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_init_handler - finished copy_from_user \n"); + + if (error) + goto end_function; + + /* PATCH - configure the DMA to single -burst instead of multi-burst */ + /*sep_configure_dma_burst();*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n"); + + message_ptr = (unsigned long *)command_args.message_addr; + + /* set the base address of the SRAM */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_SRAM_ADDR_REG_ADDR, + HW_CC_SRAM_BASE_ADDRESS); + + for (counter = 0 ; + counter < command_args.message_size_in_words; + counter++, message_ptr++) { + get_user(message_word, message_ptr); + + /* write data to SRAM */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_SRAM_DATA_REG_ADDR, + message_word); + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:message_word is %lu\n", + message_word); + + /* wait for write complete */ + SEP_WAIT_SRAM_WRITE_COMPLETE(); + } + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_init_handler - finished getting messages from user space\n"); + + /* signal SEP */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_HOST_SEP_GPR0_REG_ADDR, + 0x1); + + do { + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR3_REG_ADDR, reg_val); + } while (!(reg_val & 0xFFFFFFFD)); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n"); + + /* check the value */ + if (reg_val == 0x1) { + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:init failed\n"); + + SEP_READ_REGISTER(g_sep_reg_base_address + 0x8060, error); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:sw monitor is %lu\n", + error); + + /* fatal error - read erro status from GPRO */ + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_HOST_GPR0_REG_ADDR, + error); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:error is %lu\n", error); + goto end_function; + } + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_init_handler end\n"); + + return error; + +} + +/* + this function handles the request cache and resident reallocation +*/ +static int sep_realloc_cache_resident_handler(unsigned long arg) +{ + /* error */ + int error; + + /* physical cache addr */ + unsigned long phys_cache_address; + + /* physical resident addr */ + unsigned long phys_resident_address; + + /* command arguments */ + struct sep_driver_realloc_cache_resident_t command_args; + + /*------------------ + CODE + ---------------------*/ + + /* copy the data */ + error = copy_from_user(&command_args, + (void *)arg, + sizeof(struct sep_driver_realloc_cache_resident_t)); + if (error) + goto end_function; + + /* copy cache and resident to the their intended locations */ + error = sep_copy_cache_resident_to_area(command_args.cache_addr, + command_args.cache_size_in_bytes, + command_args.resident_addr, + command_args.resident_size_in_bytes, + &phys_cache_address, + &phys_resident_address); + if (error) + goto end_function; + + /* lock the area (if needed) */ + sep_lock_cache_resident_area(); + + command_args.new_base_addr = g_sep_phys_shared_area_addr; + + /* find the new base address according to the lowest address between + cache, resident and shared area */ + if (phys_resident_address < command_args.new_base_addr) + command_args.new_base_addr = phys_resident_address; + if (phys_cache_address < command_args.new_base_addr) + command_args.new_base_addr = phys_cache_address; + + /* set the return parameters */ + command_args.new_cache_addr = phys_cache_address; + command_args.new_resident_addr = phys_resident_address; + + + /* set the new shared area */ + command_args.new_shared_area_addr = g_sep_phys_shared_area_addr; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:command_args.new_shared_area_addr is %08lx\n", + command_args.new_shared_area_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:command_args.new_base_addr is %08lx\n", + command_args.new_base_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:command_args.new_resident_addr is %08lx\n", + command_args.new_resident_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:command_args.new_cache_addr is %08lx\n", + command_args.new_cache_addr); + + /* return to user */ + error = copy_to_user((void *)arg, + (void *)&command_args, + sizeof(struct sep_driver_realloc_cache_resident_t)); + +end_function: + + return error; +} + +/* + this function handles the request for get time +*/ +static int sep_get_time_handler(unsigned long arg) +{ + /* error */ + int error; + + /* command arguments */ + struct sep_driver_get_time_t command_args; + + /*------------------------ + CODE + --------------------------*/ + + error = sep_set_time(&command_args.time_physical_address, + &command_args.time_value); + + /* return to user */ + error = copy_to_user((void *)arg, + (void *)&command_args, + sizeof(struct sep_driver_get_time_t)); + + return error; + +} + +/* + This api handles the setting of API mode to blocking or non-blocking +*/ +static int sep_set_api_mode_handler(unsigned long arg) +{ + /* error */ + int error; + + /* flag */ + unsigned long mode_flag; + + /*---------------------------- + CODE + -----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_set_api_mode_handler start\n"); + + error = get_user( + mode_flag, &(((struct sep_driver_set_api_mode_t *)arg)->mode)); + if (error) + goto end_function; + + /* set the global flag */ + g_sep_block_mode_flag = mode_flag; + + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_set_api_mode_handler end\n"); + + return error; +} + +/* + This API handles the end transaction request +*/ +static int sep_end_transaction_handler(unsigned long arg) +{ + /*---------------------------- + CODE + -----------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_end_transaction_handler start\n"); + +#if 0/*!SEP_DRIVER_POLLING_MODE*/ + /* close IMR */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + HW_HOST_IMR_REG_ADDR, 0x7FFF); + + /* release IRQ line */ + free_irq(SEP_DIRVER_IRQ_NUM, &g_sep_reg_base_address); + + /* lock the sep mutex */ + mutex_unlock(&sep_mutex); +#endif + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_end_transaction_handler end\n"); + + return 0; +} + +/* handler for flow done interrupt */ +static void sep_flow_done_handler(struct work_struct *work) +{ + /* flow context_ptr */ + struct sep_flow_context_t *flow_data_ptr; + /*------------------------- + CODE + ---------------------------*/ + + /* obtain the mutex */ + mutex_lock(&sep_mutex); + + /* get the pointer to context */ + flow_data_ptr = (struct sep_flow_context_t *)work; + + /* free all the current input tables in sep */ + sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process); + + /* free all the current tables output tables in SEP (if needed) */ + if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff) + sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process); + + /* check if we have additional tables to be sent to SEP only input + flag may be checked */ + if (flow_data_ptr->input_tables_flag) { + /* copy the message to the shared RAM and signal SEP */ + memcpy((void *)flow_data_ptr->message, + (void *)g_sep_shared_area_addr, + flow_data_ptr->message_size_in_bytes); + + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_HOST_HOST_SEP_GPR2_REG_ADDR, + 0x2); + } + mutex_unlock(&sep_mutex); +} + + +/* + This function creates a list of tables for flow and returns the data for + the first and last tables of the list +*/ +static int sep_prepare_flow_dma_tables(unsigned long num_virtual_buffers, + unsigned long first_buff_addr, + struct sep_flow_context_t *flow_data_ptr, + struct sep_lli_entry_t *first_table_data_ptr, + struct sep_lli_entry_t *last_table_data_ptr, + bool isKernelVirtualAddress) +{ + /* error */ + int error; + + /* virtaul address of one buffer */ + unsigned long virt_buff_addr; + + /* virtual size of one buffer */ + unsigned long virt_buff_size; + + /* table data for each created table */ + struct sep_lli_entry_t table_data; + + /* info entry */ + struct sep_lli_entry_t *info_entry_ptr; + + /* prevouis info entry */ + struct sep_lli_entry_t *prev_info_entry_ptr; + + /* counter */ + unsigned long i; + + /*------------------------------- + CODE + ----------------------------------*/ + + /* init vars */ + error = 0; + prev_info_entry_ptr = 0; + + /* init the first table to default */ + table_data.physical_address = 0xffffffff; + first_table_data_ptr->physical_address = 0xffffffff; + table_data.block_size = 0; + + for (i = 0; i < num_virtual_buffers; i++) { + /* get the virtual buffer address */ + error = get_user(virt_buff_addr, &first_buff_addr); + if (error) + goto end_function; + + /* get the virtual buffer size */ + first_buff_addr++; + error = get_user(virt_buff_size, &first_buff_addr); + if (error) + goto end_function; + + /* advance the address to point to the next pair of address|size */ + first_buff_addr++; + + /* now prepare the one flow LLI table from the data */ + error = sep_prepare_one_flow_dma_table(virt_buff_addr, + virt_buff_size, + &table_data, + &info_entry_ptr, + flow_data_ptr, + isKernelVirtualAddress); + if (error) + goto end_function; + + if (i == 0) { + /* if this is the first table - save it to return to the user + application */ + *first_table_data_ptr = table_data; + + /* set the pointer to info entry */ + prev_info_entry_ptr = info_entry_ptr; + } else { + /* not first table - the previous table info entry should + be updated */ + prev_info_entry_ptr->block_size = + (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | + (table_data.block_size); + + /* set the pointer to info entry */ + prev_info_entry_ptr = info_entry_ptr; + } + } + + /* set the last table data */ + *last_table_data_ptr = table_data; + +end_function: + + return error; +} + + +/* + This function creates one DMA table for flow and returns its data, + and pointer to its info entry +*/ +static int sep_prepare_one_flow_dma_table( + unsigned long virt_buff_addr, + unsigned long virt_buff_size, + struct sep_lli_entry_t *table_data, + struct sep_lli_entry_t **info_entry_ptr, + struct sep_flow_context_t *flow_data_ptr, + bool isKernelVirtualAddress) +{ + /* error */ + int error; + + /* the range in pages */ + unsigned long lli_array_size; + + /* array of pointers ot page */ + struct sep_lli_entry_t *lli_array; + + /* pointer to the entry in the dma table */ + struct sep_lli_entry_t *flow_dma_table_entry_ptr; + + /* address of the dma table */ + unsigned long *start_dma_table_ptr; + + /* total table data counter */ + unsigned long dma_table_data_count; + + /* pointer that will keep the pointer t the pages of the virtual buffer */ + struct page **page_array_ptr; + + /* counter */ + unsigned long entry_count; + + /*------------------------------- + CODE + ----------------------------------*/ + + /* find the space for the new table */ + error = sep_find_free_flow_dma_table_space(&start_dma_table_ptr); + if (error) + goto end_function; + + /* check if the pages are in Kernel Virtual Address layout */ + if (isKernelVirtualAddress == true) + /* lock kernel buffer in the memory */ + error = sep_lock_kernel_pages(virt_buff_addr, + virt_buff_size, + &lli_array_size, + &lli_array, + &page_array_ptr); + else + /* lock user buffer in the memory */ + error = sep_lock_user_pages(virt_buff_addr, + virt_buff_size, + &lli_array_size, + &lli_array, + &page_array_ptr); + + if (error) + goto end_function; + + /* set the pointer to page array at the beginning of table - this table is + now considered taken */ + *start_dma_table_ptr = lli_array_size; + + /* point to the place of the pages pointers of the table */ + start_dma_table_ptr++; + + /* set the pages pointer */ + *start_dma_table_ptr = (unsigned long)page_array_ptr; + + /* set the pointer to the first entry */ + flow_dma_table_entry_ptr = (struct sep_lli_entry_t *)(++start_dma_table_ptr); + + /* now create the entries for table */ + for (dma_table_data_count = entry_count = 0; + entry_count < lli_array_size; + entry_count++) { + flow_dma_table_entry_ptr->physical_address = + lli_array[entry_count].physical_address; + + flow_dma_table_entry_ptr->block_size = + lli_array[entry_count].block_size; + + /* set the total data of a table */ + dma_table_data_count += lli_array[entry_count].block_size; + + flow_dma_table_entry_ptr++; + } + + /* set the physical address */ + table_data->physical_address = virt_to_phys(start_dma_table_ptr); + + /* set the num_entries and total data size */ + table_data->block_size = ((lli_array_size + 1) << + SEP_NUM_ENTRIES_OFFSET_IN_BITS) | + (dma_table_data_count); + + /* set the info entry */ + flow_dma_table_entry_ptr->physical_address = 0xffffffff; + flow_dma_table_entry_ptr->block_size = 0; + + /* set the pointer to info entry */ + *info_entry_ptr = flow_dma_table_entry_ptr; + + /* the array of the lli entries */ + kfree(lli_array); + +end_function: + + return error; +} + + +/* + This function returns pointer to the flow data structure + that conatins the given id +*/ +static int sep_find_flow_context( + unsigned long flow_id, + struct sep_flow_context_t **flow_data_ptr) +{ + /* count */ + unsigned long count; + + /* error */ + int error; + + /*----------------------- + CODE + ---------------------------*/ + + error = 0; + + /* + always search for flow with id default first - in case we + already started working on the flow there can be no situation + when 2 flows are with default flag + */ + for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) { + if (g_sep_flows_data_array[count].flow_id == flow_id) { + *flow_data_ptr = &g_sep_flows_data_array[count]; + break; + } + } + + if (count == SEP_DRIVER_NUM_FLOWS) + /* no flow found */ + error = -ENOMEM; + + return error; +} + +/* + this function find a space for the new flow dma table +*/ +static int sep_find_free_flow_dma_table_space( + unsigned long **table_address_ptr) +{ + /* error */ + int error; + + /* pointer to the id field of the flow dma table */ + unsigned long *start_table_ptr; + + /* start address of the flow dma area */ + unsigned long flow_dma_area_start_addr; + + /* end address of the flow dma area */ + unsigned long flow_dma_area_end_addr; + + /* maximum table size in words */ + unsigned long table_size_in_words; + + /*--------------------- + CODE + -----------------------*/ + + error = 0; + + /* find the start address of the flow DMA table area */ + flow_dma_area_start_addr = g_sep_shared_area_addr + + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES; + + /* set end address of the flow table area */ + flow_dma_area_end_addr = flow_dma_area_start_addr + + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES; + + /* set table size in words */ + table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * + (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2; + + /* set the pointer to the start address of DMA area */ + start_table_ptr = (unsigned long *)flow_dma_area_start_addr; + + /* find the space for the next table */ + while (((*start_table_ptr & 0x7FFFFFFF) != 0) && + ((unsigned long)start_table_ptr < + flow_dma_area_end_addr)) + start_table_ptr += table_size_in_words; + + /* check if we reached the end of floa tables area */ + if ((unsigned long)start_table_ptr >= flow_dma_area_end_addr) + error = -1; + else + *table_address_ptr = start_table_ptr; + + return error; +} + +/* + this function goes over all the flow tables connected to the given + table and deallocate them +*/ +static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr) +{ + /* id poiner */ + unsigned long *table_ptr; + + /* end address of the flow dma area */ + unsigned long num_entries; + + unsigned long num_pages; + + /* pages ptr */ + struct page **pages_ptr; + + /* maximum table size in words */ + struct sep_lli_entry_t *info_entry_ptr; + + /*------------------------------- + CODE + ---------------------------------*/ + + /* set the pointer to the first table */ + table_ptr = (unsigned long *)first_table_ptr->physical_address; + + /* set the num of entries */ + num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) + & SEP_NUM_ENTRIES_MASK; + + /* go over all the connected tables */ + while (*table_ptr != 0xffffffff) { + /* get number of pages */ + num_pages = *(table_ptr - 2); + + /* get the pointer to the pages */ + pages_ptr = (struct page **)(*(table_ptr - 1)); + + /* free the pages */ + sep_free_dma_pages(pages_ptr, num_pages, 1); + + /* goto to the info entry */ + info_entry_ptr = ((struct sep_lli_entry_t *)table_ptr) + + (num_entries - 1); + + table_ptr = (unsigned long *)info_entry_ptr->physical_address; + num_entries = (info_entry_ptr->block_size >> + SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; + } + + return; +} + +/* + This function handler the set flow id command +*/ +static int sep_set_flow_id_handler(unsigned long arg) +{ + /* error */ + int error; + + /* flow _id */ + unsigned long flow_id; + + /* pointer to flow data structre */ + struct sep_flow_context_t *flow_data_ptr; + + /*---------------------- + CODE + -----------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "------------>SEP Driver: sep_set_flow_id_handler start\n"); + + error = get_user(flow_id, + &(((struct sep_driver_set_flow_id_t *)arg)->flow_id)); + if (error) + goto end_function; + + /* find the flow data structure that was just used for creating new flow + - its id should be default */ + error = sep_find_flow_context(SEP_TEMP_FLOW_ID, &flow_data_ptr); + if (error) + goto end_function; + + /* set flow id */ + flow_data_ptr->flow_id = flow_id; + +end_function: + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_set_flow_id_handler end\n"); + + + return error; +} + + +/* + calculates time and sets it at the predefined address +*/ +static int sep_set_time(unsigned long *address_ptr, + unsigned long *time_in_sec_ptr) +{ + /* time struct */ + struct timeval time; + + /* address of time in the kernel */ + unsigned long time_addr; + + + /*------------------------ + CODE + --------------------------*/ + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:--------> sep_set_time start\n"); + + + do_gettimeofday(&time); + + /* set value in the SYSTEM MEMORY offset */ + time_addr = g_message_shared_area_addr + + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; + + *(unsigned long *)time_addr = SEP_TIME_VAL_TOKEN; + *(unsigned long *)(time_addr + 4) = time.tv_sec; + + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:time.tv_sec is %lu\n", + time.tv_sec); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:time_addr is %lu\n", + time_addr); + DEBUG_PRINT_1(SEP_DEBUG_LEVEL_EXTENDED, + "SEP Driver:g_message_shared_area_addr is %lu\n", + g_message_shared_area_addr); + + /* set the output parameters if needed */ + if (address_ptr) + *address_ptr = sep_shared_area_virt_to_phys(time_addr); + + if (time_in_sec_ptr) + *time_in_sec_ptr = time.tv_sec; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_set_time end\n"); + + return 0; +} + +/* + PATCH for configuring the DMA to single burst instead of multi-burst +*/ +static void sep_configure_dma_burst(void) +{ + +#define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL + + unsigned long regVal; + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_configure_dma_burst start \n"); + + /* request access to registers from SEP */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2UL); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n"); + + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_BUSY_REG_ADDR, regVal); + while (regVal) + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_BUSY_REG_ADDR, regVal); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n"); + + /* set the DMA burst register to single burst*/ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL); + + /* release the sep busy */ + SEP_WRITE_REGISTER(g_sep_reg_base_address + + HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL); + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_BUSY_REG_ADDR, regVal); + while (regVal != 0x0) + SEP_READ_REGISTER(g_sep_reg_base_address + + HW_HOST_SEP_BUSY_REG_ADDR, regVal); + + DEBUG_PRINT_0(SEP_DEBUG_LEVEL_BASIC, + "SEP Driver:<-------- sep_configure_dma_burst done \n"); + +} + +module_init(sep_init); +module_exit(sep_exit); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 542385ee6da337529c1087dd3d8c7af3e4269602 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 6 Aug 2009 20:44:18 +0100 Subject: Staging: sep: Move the RAR support into staging where it is supposed to be Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/rar/Kconfig | 17 ++ drivers/staging/rar/Makefile | 2 + drivers/staging/rar/rar_driver.c | 450 +++++++++++++++++++++++++++++++++++++++ drivers/staging/rar/rar_driver.h | 99 +++++++++ 6 files changed, 571 insertions(+) create mode 100644 drivers/staging/rar/Kconfig create mode 100644 drivers/staging/rar/Makefile create mode 100644 drivers/staging/rar/rar_driver.c create mode 100644 drivers/staging/rar/rar_driver.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2860bd5704f..9548ec0f7cd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -135,6 +135,8 @@ source "drivers/staging/hv/Kconfig" source "drivers/staging/vme/Kconfig" +source "drivers/staging/rar/Kconfig" + source "drivers/staging/sep/Kconfig" endif # !STAGING_EXCLUDE_BUILD diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ce6523c02f9..edd0c061143 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -49,4 +49,5 @@ obj-$(CONFIG_USB_CPC) += cpc-usb/ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ +obj-$(CONFIG_RAR_REGISTER) += rar/ obj-$(CONFIG_DX_SEP) += sep/ diff --git a/drivers/staging/rar/Kconfig b/drivers/staging/rar/Kconfig new file mode 100644 index 00000000000..17f8bf3bb41 --- /dev/null +++ b/drivers/staging/rar/Kconfig @@ -0,0 +1,17 @@ +# +# RAR device configuration +# + +menu "RAR Register Driver" +# +# Restricted Access Register Manager +# +config RAR_REGISTER + tristate "Restricted Access Region Register Driver" + default n + ---help--- + This driver allows other kernel drivers access to the + contents of the restricted access region control + registers. + +endmenu diff --git a/drivers/staging/rar/Makefile b/drivers/staging/rar/Makefile new file mode 100644 index 00000000000..5422ed04ccf --- /dev/null +++ b/drivers/staging/rar/Makefile @@ -0,0 +1,2 @@ +EXTRA_CFLAGS += -DLITTLE__ENDIAN +obj-$(CONFIG_RAR_REGISTER) += rar_driver.o diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c new file mode 100644 index 00000000000..8c4463e2f62 --- /dev/null +++ b/drivers/staging/rar/rar_driver.c @@ -0,0 +1,450 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rar_driver.h" + +/* PCI vendor id for controler */ +#define VENDOR_ID 0x8086 + +/* PCI device id for controler */ +#define DEVICE_ID 0x4110 + +/* The following defines are for the IPC process to retrieve RAR in */ + +/* === Lincroft Message Bus Interface === */ +/* Message Control Register */ +#define LNC_MCR_OFFSET 0xD0 + +/* Message Data Register */ +#define LNC_MDR_OFFSET 0xD4 + +/* Message Opcodes */ +#define LNC_MESSAGE_READ_OPCODE 0xD0 +#define LNC_MESSAGE_WRITE_OPCODE 0xE0 + +/* Message Write Byte Enables */ +#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF + +/* B-unit Port */ +#define LNC_BUNIT_PORT 0x3 + +/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ +#define LNC_BRAR0L 0x10 +#define LNC_BRAR0H 0x11 +#define LNC_BRAR1L 0x12 +#define LNC_BRAR1H 0x13 + +/* Reserved for SeP */ +#define LNC_BRAR2L 0x14 +#define LNC_BRAR2H 0x15 + + +/* This structure is only used during module initialization. */ +struct RAR_offsets { + int low; /* Register offset for low RAR physical address. */ + int high; /* Register offset for high RAR physical address. */ +}; + +struct pci_dev *rar_dev; +static uint32_t registered; + +/* Moorestown supports three restricted access regions. */ +#define MRST_NUM_RAR 3 + +struct RAR_address_struct rar_addr[MRST_NUM_RAR]; + +/* prototype for init */ +static int __init rar_init_handler(void); +static void __exit rar_exit_handler(void); + +/* + function that is activated on the succesfull probe of the RAR device +*/ +static int __devinit rar_probe(struct pci_dev *pdev, struct pci_device_id *ent); + +static struct pci_device_id rar_pci_id_tbl[] = { + { PCI_DEVICE(VENDOR_ID, DEVICE_ID) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); + +/* field for registering driver to PCI device */ +static struct pci_driver rar_pci_driver = { + .name = "rar_driver", + .id_table = rar_pci_id_tbl, + .probe = rar_probe +}; + +/* This function is used to retrieved RAR info using the IPC message + bus interface */ +static int memrar_get_rar_addr(struct pci_dev* pdev, + int offset, + u32 *addr) +{ + /* + * ======== The Lincroft Message Bus Interface ======== + * Lincroft registers may be obtained from the PCI + * (the Host Bridge) using the Lincroft Message Bus + * Interface. That message bus interface is generally + * comprised of two registers: a control register (MCR, 0xDO) + * and a data register (MDR, 0xD4). + * + * The MCR (message control register) format is the following: + * 1. [31:24]: Opcode + * 2. [23:16]: Port + * 3. [15:8]: Register Offset + * 4. [7:4]: Byte Enables (use 0xF to set all of these bits + * to 1) + * 5. [3:0]: reserved + * + * Read (0xD0) and write (0xE0) opcodes are written to the + * control register when reading and writing to Lincroft + * registers, respectively. + * + * We're interested in registers found in the Lincroft + * B-unit. The B-unit port is 0x3. + * + * The six B-unit RAR register offsets we use are listed + * earlier in this file. + * + * Lastly writing to the MCR register requires the "Byte + * enables" bits to be set to 1. This may be achieved by + * writing 0xF at bit 4. + * + * The MDR (message data register) format is the following: + * 1. [31:0]: Read/Write Data + * + * Data being read from this register is only available after + * writing the appropriate control message to the MCR + * register. + * + * Data being written to this register must be written before + * writing the appropriate control message to the MCR + * register. + */ + + int result = 0; /* result */ + /* Construct control message */ + u32 const message = + (LNC_MESSAGE_READ_OPCODE << 24) + | (LNC_BUNIT_PORT << 16) + | (offset << 8) + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + + printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset); + + if (addr == 0) + return -EINVAL; + + /* Send the control message */ + result = pci_write_config_dword(pdev, + LNC_MCR_OFFSET, + message); + + printk(KERN_WARNING "rar- result from send ctl register is %x\n" + ,result); + + if (!result) + result = pci_read_config_dword(pdev, + LNC_MDR_OFFSET, + addr); + + printk(KERN_WARNING "rar- result from read data register is %x\n", + result); + + printk(KERN_WARNING "rar- value read from data register is %x\n", + *addr); + + if (result) + return -1; + else + return 0; +} + +static int memrar_set_rar_addr(struct pci_dev* pdev, + int offset, + u32 addr) +{ + /* + * ======== The Lincroft Message Bus Interface ======== + * Lincroft registers may be obtained from the PCI + * (the Host Bridge) using the Lincroft Message Bus + * Interface. That message bus interface is generally + * comprised of two registers: a control register (MCR, 0xDO) + * and a data register (MDR, 0xD4). + * + * The MCR (message control register) format is the following: + * 1. [31:24]: Opcode + * 2. [23:16]: Port + * 3. [15:8]: Register Offset + * 4. [7:4]: Byte Enables (use 0xF to set all of these bits + * to 1) + * 5. [3:0]: reserved + * + * Read (0xD0) and write (0xE0) opcodes are written to the + * control register when reading and writing to Lincroft + * registers, respectively. + * + * We're interested in registers found in the Lincroft + * B-unit. The B-unit port is 0x3. + * + * The six B-unit RAR register offsets we use are listed + * earlier in this file. + * + * Lastly writing to the MCR register requires the "Byte + * enables" bits to be set to 1. This may be achieved by + * writing 0xF at bit 4. + * + * The MDR (message data register) format is the following: + * 1. [31:0]: Read/Write Data + * + * Data being read from this register is only available after + * writing the appropriate control message to the MCR + * register. + * + * Data being written to this register must be written before + * writing the appropriate control message to the MCR + * register. + */ + + int result = 0; /* result */ + + /* Construct control message */ + u32 const message = + (LNC_MESSAGE_WRITE_OPCODE << 24) + | (LNC_BUNIT_PORT << 16) + | (offset << 8) + | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + + printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset); + + if (addr == 0) + return -EINVAL; + + /* Send the control message */ + result = pci_write_config_dword(pdev, + LNC_MDR_OFFSET, + addr); + + printk(KERN_WARNING "rar- result from send ctl register is %x\n" + ,result); + + if (!result) + result = pci_write_config_dword(pdev, + LNC_MCR_OFFSET, + message); + + printk(KERN_WARNING "rar- result from write data register is %x\n", + result); + + printk(KERN_WARNING "rar- value read to data register is %x\n", + addr); + + if (result) + return -1; + else + return 0; +} + +/* + + * Initialize RAR parameters, such as physical addresses, etc. + + */ +static int memrar_init_rar_params(struct pci_dev *pdev) +{ + struct RAR_offsets const offsets[] = { + { LNC_BRAR0L, LNC_BRAR0H }, + { LNC_BRAR1L, LNC_BRAR1H }, + { LNC_BRAR2L, LNC_BRAR2H } + }; + + size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); + struct RAR_offsets const *end = offsets + num_offsets; + struct RAR_offsets const *i; + unsigned int n = 0; + int result = 0; + + /* Retrieve RAR start and end physical addresses. */ + + /* + * Access the RAR registers through the Lincroft Message Bus + * Interface on PCI device: 00:00.0 Host bridge. + */ + + /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ + + if (pdev == NULL) + return -ENODEV; + + for (i = offsets; i != end; ++i, ++n) { + if (memrar_get_rar_addr (pdev, + (*i).low, + &(rar_addr[n].low)) != 0 + || memrar_get_rar_addr (pdev, + (*i).high, + &(rar_addr[n].high)) != 0) { + result = -1; + break; + } + } + + /* Done accessing the device. */ + /* pci_dev_put(pdev); */ + + if (result == 0) { + if(1) { + size_t z; + for (z = 0; z != MRST_NUM_RAR; ++z) { + printk(KERN_WARNING "rar - BRAR[%u] physical address low\n" + "\tlow: 0x%08x\n" + "\thigh: 0x%08x\n", + z, + rar_addr[z].low, + rar_addr[z].high); + } + } + } + + return result; +} + +/* + function that is activaed on the succesfull probe of the RAR device +*/ +static int __devinit rar_probe(struct pci_dev *pdev, struct pci_device_id *ent) +{ + /* error */ + int error; + + /*------------------------ + CODE + ---------------------------*/ + + DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, + "Rar pci probe starting\n"); + error = 0; + + /* enable the device */ + error = pci_enable_device(pdev); + if (error) { + DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, + "error enabling pci device\n"); + goto end_function; + } + + rar_dev = pdev; + registered = 1; + + /* Initialize the RAR parameters, which have to be retrieved */ + /* via the message bus service */ + error=memrar_init_rar_params(rar_dev); + + if (error) { + DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, + "error getting RAR addresses device\n"); + registered = 0; + goto end_function; + } + +end_function: + + return error; +} + +/* + this function registers th driver to + the device subsystem( either PCI, USB, etc) +*/ +static int __init rar_init_handler(void) +{ + return pci_register_driver(&rar_pci_driver); +} + +static void __exit rar_exit_handler(void) +{ + pci_unregister_driver(&rar_pci_driver); +} + +module_init(rar_init_handler); +module_exit(rar_exit_handler); + +MODULE_LICENSE("GPL"); + + +/* The get_rar_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes two + * parameter: + * + * int rar_index + * The rar_index is an index to the rar for which you wish to retrieve + * the address information. + * Values can be 0,1, or 2. + * + * struct RAR_address_struct is a pointer to a place to which the function + * can return the address structure for the RAR. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int get_rar_address(int rar_index,struct RAR_address_struct *addresses) +{ + if (registered && (rar_index < 3) && (rar_index >= 0)) { + *addresses=rar_addr[rar_index]; + /* strip off lock bit information */ + addresses->low = addresses->low & 0xfffffff0; + addresses->high = addresses->high & 0xfffffff0; + return 0; + } + + else { + return -ENODEV; + } +} + + +EXPORT_SYMBOL(get_rar_address); + +/* The lock_rar function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * + * int rar_index + * The rar_index is an index to the rar that you want to lock. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int lock_rar(int rar_index) +{ + u32 working_addr; + int result; +if (registered && (rar_index < 3) && (rar_index >= 0)) { + /* first make sure that lock bits are clear (this does lock) */ + working_addr=rar_addr[rar_index].low & 0xfffffff0; + + /* now send that value to the register using the IPC */ + result=memrar_set_rar_addr(rar_dev,rar_index,working_addr); + return result; + } + +else { + return -ENODEV; + } +} diff --git a/drivers/staging/rar/rar_driver.h b/drivers/staging/rar/rar_driver.h new file mode 100644 index 00000000000..3690f984ff5 --- /dev/null +++ b/drivers/staging/rar/rar_driver.h @@ -0,0 +1,99 @@ +/* === RAR Physical Addresses === */ +struct RAR_address_struct { + u32 low; + u32 high; +}; + +/* The get_rar_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes two + * parameter: + * + * int rar_index + * The rar_index is an index to the rar for which you wish to retrieve + * the address information. + * Values can be 0,1, or 2. + * + * struct RAR_address_struct is a pointer to a place to which the function + * can return the address structure for the RAR. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int get_rar_address(int rar_index,struct RAR_address_struct *addresses); + + +/* The lock_rar function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * + * int rar_index + * The rar_index is an index to the rar that you want to lock. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +int lock_rar(int rar_index); + + +/* DEBUG LEVEL MASKS */ +#define RAR_DEBUG_LEVEL_BASIC 0x1 + +#define RAR_DEBUG_LEVEL_REGISTERS 0x2 + +#define RAR_DEBUG_LEVEL_EXTENDED 0x4 + +#define DEBUG_LEVEL 0x7 + +/* FUNCTIONAL MACROS */ + +/* debug macro without paramaters */ +#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ +do \ +{ \ + if(DEBUG_LEVEL) \ + { \ + printk(KERN_WARNING info); \ + } \ +}while(0) + +/* debug macro with 1 paramater */ +#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ +do \ +{ \ + if(DEBUG_LEVEL) \ + { \ + printk(KERN_WARNING info , param1); \ + } \ +}while(0) + +/* debug macro with 2 paramaters */ +#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ +do \ +{ \ + if(DEBUG_LEVEL) \ + { \ + printk(KERN_WARNING info , param1, param2); \ + } \ +}while(0) + +/* debug macro with 3 paramaters */ +#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ +do \ +{ \ + if(DEBUG_LEVEL) \ + { \ + printk(KERN_WARNING info , param1, param2 , param3); \ + } \ +}while(0) + +/* debug macro with 4 paramaters */ +#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ +do \ +{ \ + if(DEBUG_LEVEL) \ + { \ + printk(KERN_WARNING info , param1, param2 , param3 , param4); \ + } \ +}while(0) + -- cgit v1.2.3 From 49debb5684009d56ec5a0f930e513b1044db5e76 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 23 Aug 2009 15:32:20 +0200 Subject: Staging: remove no longer needed rt3070 driver rt2870 handles now all rt2870/rt3070 chipsets. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 -- drivers/staging/Makefile | 1 - drivers/staging/rt3070/2870_main_dev.c | 1 - drivers/staging/rt3070/Kconfig | 6 ---- drivers/staging/rt3070/Makefile | 43 -------------------------- drivers/staging/rt3070/action.h | 1 - drivers/staging/rt3070/aironet.h | 1 - drivers/staging/rt3070/ap.h | 1 - drivers/staging/rt3070/chlist.h | 1 - drivers/staging/rt3070/common/2870_rtmp_init.c | 1 - drivers/staging/rt3070/common/action.c | 1 - drivers/staging/rt3070/common/ba_action.c | 1 - drivers/staging/rt3070/common/cmm_data.c | 1 - drivers/staging/rt3070/common/cmm_data_2870.c | 1 - drivers/staging/rt3070/common/cmm_info.c | 1 - drivers/staging/rt3070/common/cmm_sanity.c | 1 - drivers/staging/rt3070/common/cmm_sync.c | 1 - drivers/staging/rt3070/common/cmm_wpa.c | 1 - drivers/staging/rt3070/common/dfs.c | 1 - drivers/staging/rt3070/common/eeprom.c | 1 - drivers/staging/rt3070/common/md5.c | 1 - drivers/staging/rt3070/common/mlme.c | 1 - drivers/staging/rt3070/common/rtmp_init.c | 1 - drivers/staging/rt3070/common/rtmp_tkip.c | 1 - drivers/staging/rt3070/common/rtmp_wep.c | 1 - drivers/staging/rt3070/common/rtusb_bulk.c | 1 - drivers/staging/rt3070/common/rtusb_data.c | 1 - drivers/staging/rt3070/common/rtusb_io.c | 1 - drivers/staging/rt3070/common/spectrum.c | 1 - drivers/staging/rt3070/dfs.h | 1 - drivers/staging/rt3070/md5.h | 1 - drivers/staging/rt3070/mlme.h | 1 - drivers/staging/rt3070/oid.h | 1 - drivers/staging/rt3070/rt2870.h | 1 - drivers/staging/rt3070/rt28xx.h | 1 - drivers/staging/rt3070/rt_config.h | 1 - drivers/staging/rt3070/rt_linux.c | 1 - drivers/staging/rt3070/rt_linux.h | 1 - drivers/staging/rt3070/rt_main_dev.c | 1 - drivers/staging/rt3070/rt_profile.c | 1 - drivers/staging/rt3070/rtmp.h | 1 - drivers/staging/rt3070/rtmp_ckipmic.h | 1 - drivers/staging/rt3070/rtmp_def.h | 1 - drivers/staging/rt3070/rtmp_type.h | 1 - drivers/staging/rt3070/spectrum.h | 1 - drivers/staging/rt3070/spectrum_def.h | 1 - drivers/staging/rt3070/sta/aironet.c | 1 - drivers/staging/rt3070/sta/assoc.c | 1 - drivers/staging/rt3070/sta/auth.c | 1 - drivers/staging/rt3070/sta/auth_rsp.c | 1 - drivers/staging/rt3070/sta/connect.c | 2 -- drivers/staging/rt3070/sta/rtmp_data.c | 1 - drivers/staging/rt3070/sta/sanity.c | 1 - drivers/staging/rt3070/sta/sync.c | 1 - drivers/staging/rt3070/sta/wpa.c | 1 - drivers/staging/rt3070/sta_ioctl.c | 1 - drivers/staging/rt3070/wpa.h | 1 - 57 files changed, 106 deletions(-) delete mode 100644 drivers/staging/rt3070/2870_main_dev.c delete mode 100644 drivers/staging/rt3070/Kconfig delete mode 100644 drivers/staging/rt3070/Makefile delete mode 100644 drivers/staging/rt3070/action.h delete mode 100644 drivers/staging/rt3070/aironet.h delete mode 100644 drivers/staging/rt3070/ap.h delete mode 100644 drivers/staging/rt3070/chlist.h delete mode 100644 drivers/staging/rt3070/common/2870_rtmp_init.c delete mode 100644 drivers/staging/rt3070/common/action.c delete mode 100644 drivers/staging/rt3070/common/ba_action.c delete mode 100644 drivers/staging/rt3070/common/cmm_data.c delete mode 100644 drivers/staging/rt3070/common/cmm_data_2870.c delete mode 100644 drivers/staging/rt3070/common/cmm_info.c delete mode 100644 drivers/staging/rt3070/common/cmm_sanity.c delete mode 100644 drivers/staging/rt3070/common/cmm_sync.c delete mode 100644 drivers/staging/rt3070/common/cmm_wpa.c delete mode 100644 drivers/staging/rt3070/common/dfs.c delete mode 100644 drivers/staging/rt3070/common/eeprom.c delete mode 100644 drivers/staging/rt3070/common/md5.c delete mode 100644 drivers/staging/rt3070/common/mlme.c delete mode 100644 drivers/staging/rt3070/common/rtmp_init.c delete mode 100644 drivers/staging/rt3070/common/rtmp_tkip.c delete mode 100644 drivers/staging/rt3070/common/rtmp_wep.c delete mode 100644 drivers/staging/rt3070/common/rtusb_bulk.c delete mode 100644 drivers/staging/rt3070/common/rtusb_data.c delete mode 100644 drivers/staging/rt3070/common/rtusb_io.c delete mode 100644 drivers/staging/rt3070/common/spectrum.c delete mode 100644 drivers/staging/rt3070/dfs.h delete mode 100644 drivers/staging/rt3070/md5.h delete mode 100644 drivers/staging/rt3070/mlme.h delete mode 100644 drivers/staging/rt3070/oid.h delete mode 100644 drivers/staging/rt3070/rt2870.h delete mode 100644 drivers/staging/rt3070/rt28xx.h delete mode 100644 drivers/staging/rt3070/rt_config.h delete mode 100644 drivers/staging/rt3070/rt_linux.c delete mode 100644 drivers/staging/rt3070/rt_linux.h delete mode 100644 drivers/staging/rt3070/rt_main_dev.c delete mode 100644 drivers/staging/rt3070/rt_profile.c delete mode 100644 drivers/staging/rt3070/rtmp.h delete mode 100644 drivers/staging/rt3070/rtmp_ckipmic.h delete mode 100644 drivers/staging/rt3070/rtmp_def.h delete mode 100644 drivers/staging/rt3070/rtmp_type.h delete mode 100644 drivers/staging/rt3070/spectrum.h delete mode 100644 drivers/staging/rt3070/spectrum_def.h delete mode 100644 drivers/staging/rt3070/sta/aironet.c delete mode 100644 drivers/staging/rt3070/sta/assoc.c delete mode 100644 drivers/staging/rt3070/sta/auth.c delete mode 100644 drivers/staging/rt3070/sta/auth_rsp.c delete mode 100644 drivers/staging/rt3070/sta/connect.c delete mode 100644 drivers/staging/rt3070/sta/rtmp_data.c delete mode 100644 drivers/staging/rt3070/sta/sanity.c delete mode 100644 drivers/staging/rt3070/sta/sync.c delete mode 100644 drivers/staging/rt3070/sta/wpa.c delete mode 100644 drivers/staging/rt3070/sta_ioctl.c delete mode 100644 drivers/staging/rt3070/wpa.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 9548ec0f7cd..d08cd8d5631 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -73,8 +73,6 @@ source "drivers/staging/rt2860/Kconfig" source "drivers/staging/rt2870/Kconfig" -source "drivers/staging/rt3070/Kconfig" - source "drivers/staging/rt3090/Kconfig" source "drivers/staging/comedi/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index edd0c061143..9a23438bf7c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_AGNX) += agnx/ obj-$(CONFIG_OTUS) += otus/ obj-$(CONFIG_RT2860) += rt2860/ obj-$(CONFIG_RT2870) += rt2870/ -obj-$(CONFIG_RT3070) += rt3070/ obj-$(CONFIG_RT3090) += rt3090/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_ASUS_OLED) += asus_oled/ diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c deleted file mode 100644 index 32427c0bb3b..00000000000 --- a/drivers/staging/rt3070/2870_main_dev.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/2870_main_dev.c" diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig deleted file mode 100644 index 652d825338e..00000000000 --- a/drivers/staging/rt3070/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config RT3070 - tristate "Ralink 3070 wireless support" - depends on USB && X86 && WLAN_80211 && !RT2870 - ---help--- - This is an experimental driver for the Ralink 3070 wireless chip. - diff --git a/drivers/staging/rt3070/Makefile b/drivers/staging/rt3070/Makefile deleted file mode 100644 index df7ac19e088..00000000000 --- a/drivers/staging/rt3070/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -obj-$(CONFIG_RT3070) += rt3070sta.o - -# TODO: all of these should be removed -EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -EXTRA_CFLAGS += -DRT2870 -DRT30xx -DRT3070 -EXTRA_CFLAGS += -DDBG - -rt3070sta-objs := \ - common/md5.o \ - common/mlme.o \ - common/rtmp_wep.o \ - common/action.o \ - common/cmm_data.o \ - common/rtmp_init.o \ - common/rtmp_tkip.o \ - common/cmm_sync.o \ - common/eeprom.o \ - common/cmm_sanity.o \ - common/cmm_info.o \ - common/cmm_wpa.o \ - common/dfs.o \ - common/spectrum.o \ - sta/assoc.o \ - sta/aironet.o \ - sta/auth.o \ - sta/auth_rsp.o \ - sta/sync.o \ - sta/sanity.o \ - sta/rtmp_data.o \ - sta/connect.o \ - sta/wpa.o \ - rt_linux.o \ - rt_profile.o \ - rt_main_dev.o \ - sta_ioctl.o \ - common/ba_action.o \ - 2870_main_dev.o \ - common/2870_rtmp_init.o \ - common/rtusb_io.o \ - common/rtusb_bulk.o \ - common/rtusb_data.o \ - common/cmm_data_2870.o - diff --git a/drivers/staging/rt3070/action.h b/drivers/staging/rt3070/action.h deleted file mode 100644 index 345fa8922ed..00000000000 --- a/drivers/staging/rt3070/action.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/common/action.h" diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h deleted file mode 100644 index 78088f2087e..00000000000 --- a/drivers/staging/rt3070/aironet.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/aironet.h" diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h deleted file mode 100644 index ab8de4bbad0..00000000000 --- a/drivers/staging/rt3070/ap.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/ap.h" diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h deleted file mode 100644 index 8ee1ff527f5..00000000000 --- a/drivers/staging/rt3070/chlist.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/chlist.h" diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c deleted file mode 100644 index 5456454b8d3..00000000000 --- a/drivers/staging/rt3070/common/2870_rtmp_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/2870_rtmp_init.c" diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c deleted file mode 100644 index 035fd803f61..00000000000 --- a/drivers/staging/rt3070/common/action.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/action.c" diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c deleted file mode 100644 index 2d638ea8c87..00000000000 --- a/drivers/staging/rt3070/common/ba_action.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/ba_action.c" diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c deleted file mode 100644 index 02e202db4da..00000000000 --- a/drivers/staging/rt3070/common/cmm_data.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_data.c" diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c deleted file mode 100644 index 0e51ee414a2..00000000000 --- a/drivers/staging/rt3070/common/cmm_data_2870.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_data_2870.c" diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c deleted file mode 100644 index 6e981e523fb..00000000000 --- a/drivers/staging/rt3070/common/cmm_info.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_info.c" diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c deleted file mode 100644 index 82ccf9e85f3..00000000000 --- a/drivers/staging/rt3070/common/cmm_sanity.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_sanity.c" diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c deleted file mode 100644 index 3b517420f48..00000000000 --- a/drivers/staging/rt3070/common/cmm_sync.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_sync.c" diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c deleted file mode 100644 index 6483d329286..00000000000 --- a/drivers/staging/rt3070/common/cmm_wpa.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/cmm_wpa.c" diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c deleted file mode 100644 index c584a6924c3..00000000000 --- a/drivers/staging/rt3070/common/dfs.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/dfs.c" diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c deleted file mode 100644 index 0c567d3dad0..00000000000 --- a/drivers/staging/rt3070/common/eeprom.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/eeprom.c" diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c deleted file mode 100644 index 07528842267..00000000000 --- a/drivers/staging/rt3070/common/md5.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/md5.c" diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c deleted file mode 100644 index c2d0d4e10cb..00000000000 --- a/drivers/staging/rt3070/common/mlme.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/mlme.c" diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c deleted file mode 100644 index 4709e5f28a8..00000000000 --- a/drivers/staging/rt3070/common/rtmp_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtmp_init.c" diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c deleted file mode 100644 index 57a5ee96f31..00000000000 --- a/drivers/staging/rt3070/common/rtmp_tkip.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtmp_tkip.c" diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c deleted file mode 100644 index 71979856e11..00000000000 --- a/drivers/staging/rt3070/common/rtmp_wep.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtmp_wep.c" diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c deleted file mode 100644 index 762ecfe6044..00000000000 --- a/drivers/staging/rt3070/common/rtusb_bulk.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtusb_bulk.c" diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c deleted file mode 100644 index d05deb870f4..00000000000 --- a/drivers/staging/rt3070/common/rtusb_data.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtusb_data.c" diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c deleted file mode 100644 index 20a0b56e58b..00000000000 --- a/drivers/staging/rt3070/common/rtusb_io.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/rtusb_io.c" diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c deleted file mode 100644 index de3b949e52f..00000000000 --- a/drivers/staging/rt3070/common/spectrum.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/common/spectrum.c" diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h deleted file mode 100644 index b9c92e354f2..00000000000 --- a/drivers/staging/rt3070/dfs.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/dfs.h" diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h deleted file mode 100644 index 1042a994dc7..00000000000 --- a/drivers/staging/rt3070/md5.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/md5.h" diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h deleted file mode 100644 index 773c0edfcea..00000000000 --- a/drivers/staging/rt3070/mlme.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/mlme.h" diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h deleted file mode 100644 index cbf16a8ae61..00000000000 --- a/drivers/staging/rt3070/oid.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/oid.h" diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h deleted file mode 100644 index 16d8717b9db..00000000000 --- a/drivers/staging/rt3070/rt2870.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt2870.h" diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h deleted file mode 100644 index c47ddc8bd9e..00000000000 --- a/drivers/staging/rt3070/rt28xx.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt28xx.h" diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h deleted file mode 100644 index 3e8fcbdd579..00000000000 --- a/drivers/staging/rt3070/rt_config.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt_config.h" diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c deleted file mode 100644 index 6185f2e9992..00000000000 --- a/drivers/staging/rt3070/rt_linux.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt_linux.c" diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h deleted file mode 100644 index 9f7efee3d60..00000000000 --- a/drivers/staging/rt3070/rt_linux.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/rt_linux.h" diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c deleted file mode 100644 index c8bcd4029c3..00000000000 --- a/drivers/staging/rt3070/rt_main_dev.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt_main_dev.c" diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c deleted file mode 100644 index ab9eb1d55bb..00000000000 --- a/drivers/staging/rt3070/rt_profile.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rt_profile.c" diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h deleted file mode 100644 index 5390ca3eb27..00000000000 --- a/drivers/staging/rt3070/rtmp.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rtmp.h" diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h deleted file mode 100644 index 4956093f475..00000000000 --- a/drivers/staging/rt3070/rtmp_ckipmic.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rtmp_ckipmic.h" diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h deleted file mode 100644 index fa3b6b55cfe..00000000000 --- a/drivers/staging/rt3070/rtmp_def.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rtmp_def.h" diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h deleted file mode 100644 index 42384e50679..00000000000 --- a/drivers/staging/rt3070/rtmp_type.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/rtmp_type.h" diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h deleted file mode 100644 index 1ca9c2584bf..00000000000 --- a/drivers/staging/rt3070/spectrum.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/spectrum.h" diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h deleted file mode 100644 index 892bc88c65f..00000000000 --- a/drivers/staging/rt3070/spectrum_def.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/spectrum_def.h" diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c deleted file mode 100644 index 48fcc469527..00000000000 --- a/drivers/staging/rt3070/sta/aironet.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/aironet.c" diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c deleted file mode 100644 index 1987a2a4b05..00000000000 --- a/drivers/staging/rt3070/sta/assoc.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/assoc.c" diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c deleted file mode 100644 index d55198288d9..00000000000 --- a/drivers/staging/rt3070/sta/auth.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/auth.c" diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c deleted file mode 100644 index c4ea2dc49ad..00000000000 --- a/drivers/staging/rt3070/sta/auth_rsp.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/auth_rsp.c" diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c deleted file mode 100644 index d77802caa30..00000000000 --- a/drivers/staging/rt3070/sta/connect.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../rt2870/sta/connect.c" - diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c deleted file mode 100644 index bf091206f5c..00000000000 --- a/drivers/staging/rt3070/sta/rtmp_data.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/rtmp_data.c" diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c deleted file mode 100644 index b4954779b31..00000000000 --- a/drivers/staging/rt3070/sta/sanity.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/sanity.c" diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c deleted file mode 100644 index b7b8eb4f446..00000000000 --- a/drivers/staging/rt3070/sta/sync.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/sync.c" diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c deleted file mode 100644 index 95543bb1f0e..00000000000 --- a/drivers/staging/rt3070/sta/wpa.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2870/sta/wpa.c" diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c deleted file mode 100644 index ac56507e3c8..00000000000 --- a/drivers/staging/rt3070/sta_ioctl.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/sta_ioctl.c" diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h deleted file mode 100644 index 94bb2327940..00000000000 --- a/drivers/staging/rt3070/wpa.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2870/wpa.h" -- cgit v1.2.3 From 847ec80bbaa76aae41062d6802cea9c1b2289f14 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 18 Aug 2009 18:06:19 +0100 Subject: Staging: IIO: core support for device registration and management Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/iio/Kconfig | 11 + drivers/staging/iio/Makefile | 6 + drivers/staging/iio/chrdev.h | 118 +++++ drivers/staging/iio/iio.h | 411 +++++++++++++++ drivers/staging/iio/industrialio-core.c | 851 ++++++++++++++++++++++++++++++++ drivers/staging/iio/sysfs.h | 293 +++++++++++ drivers/staging/iio/trigger_consumer.h | 26 + 9 files changed, 1719 insertions(+) create mode 100644 drivers/staging/iio/Kconfig create mode 100644 drivers/staging/iio/Makefile create mode 100644 drivers/staging/iio/chrdev.h create mode 100644 drivers/staging/iio/iio.h create mode 100644 drivers/staging/iio/industrialio-core.c create mode 100644 drivers/staging/iio/sysfs.h create mode 100644 drivers/staging/iio/trigger_consumer.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d08cd8d5631..4d836a02343 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -137,5 +137,7 @@ source "drivers/staging/rar/Kconfig" source "drivers/staging/sep/Kconfig" +source "drivers/staging/iio/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 9a23438bf7c..f0c33eec012 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,3 +50,4 @@ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_RAR_REGISTER) += rar/ obj-$(CONFIG_DX_SEP) += sep/ +obj-$(CONFIG_IIO) += iio/ diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig new file mode 100644 index 00000000000..09e4101939e --- /dev/null +++ b/drivers/staging/iio/Kconfig @@ -0,0 +1,11 @@ +# +# Industrial I/O subsytem configuration +# + +menuconfig IIO + tristate "Industrial I/O support" + ---help--- + The industrial I/O subsystem provides a unified framework for + drivers for many different types of embedded sensors using a + number of different physical interfaces (i2c, spi etc). See + Documentation/industrialio for more information. diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile new file mode 100644 index 00000000000..92b462a125e --- /dev/null +++ b/drivers/staging/iio/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the industrial I/O core. +# + +obj-$(CONFIG_IIO) += industrialio.o +industrialio-y := industrialio-core.o diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h new file mode 100644 index 00000000000..8bc64bf0845 --- /dev/null +++ b/drivers/staging/iio/chrdev.h @@ -0,0 +1,118 @@ +/* The industrial I/O core - character device related + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _IIO_CHRDEV_H_ +#define _IIO_CHRDEV_H_ +struct iio_dev; + +/** + * struct iio_handler - Structure used to specify file operations + * for a particular chrdev + * @chrdev: character device structure + * @id: the location in the handler table - used for deallocation. + * @flags: file operations related flags including busy flag. + * @private: handler specific data used by the fileops registered with + * the chrdev. + */ +struct iio_handler { + struct cdev chrdev; + int id; + unsigned long flags; + void *private; +}; + +#define iio_cdev_to_handler(cd) \ + container_of(cd, struct iio_handler, chrdev) + +/** + * struct iio_event_data - The actual event being pushed to userspace + * @id: event identifier + * @timestamp: best estimate of time of event occurance (often from + * the interrupt handler) + */ +struct iio_event_data { + int id; + s64 timestamp; +}; + +/** + * struct iio_detected_event_list - list element for events that have occured + * @list: linked list header + * @ev: the event itself + * @shared_pointer: used when the event is shared - i.e. can be escallated + * on demand (eg ring buffer 50%->100% full) + */ +struct iio_detected_event_list { + struct list_head list; + struct iio_event_data ev; + struct iio_shared_ev_pointer *shared_pointer; +}; +/** + * struct iio_shared_ev_pointer - allows shared events to identify if currently + * in the detected event list + * @ev_p: pointer to detected event list element (null if not in list) + * @lock: protect this element to prevent simultaneous edit and remove + */ +struct iio_shared_ev_pointer { + struct iio_detected_event_list *ev_p; + spinlock_t lock; +}; + +/** + * struct iio_event_interface - chrdev interface for an event line + * @dev: device assocated with event interface + * @handler: fileoperations and related control for the chrdev + * @wait: wait queue to allow blocking reads of events + * @event_list_lock: mutex to protect the list of detected events + * @det_events: list of detected events + * @max_events: maximum number of events before new ones are dropped + * @current_events: number of events in detected list + * @id: indentifier to allow the event interface to know which + * physical line it corresponds to + * @owner: ensure the driver module owns the file, not iio + * @private: driver specific data + * @_name: used internally to store the sysfs name for minor id + * attribute + */ +struct iio_event_interface { + struct device dev; + struct iio_handler handler; + wait_queue_head_t wait; + struct mutex event_list_lock; + struct iio_detected_event_list det_events; + int max_events; + int current_events; + int id; + struct iio_chrdev_minor_attr attr; + struct module *owner; + void *private; + char _name[20]; + char _attrname[20]; +}; + +/** + * struct iio_event_handler_list - element in list of handlers for events + * @list: list header + * @refcount: as the handler may be shared between multiple device + * side events, reference counting ensures clean removal + * @exist_lock: prevents race conditions related to refcount useage. + * @handler: event handler function - called on event if this + * event_handler is enabled. + * + * Each device has one list of these per interrupt line + **/ +struct iio_event_handler_list { + struct list_head list; + int refcount; + struct mutex exist_lock; + int (*handler)(struct iio_dev *dev_info, int index, s64 timestamp, + int no_test); +}; + +#endif diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h new file mode 100644 index 00000000000..25ccb809221 --- /dev/null +++ b/drivers/staging/iio/iio.h @@ -0,0 +1,411 @@ +/* The industrial I/O core + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _INDUSTRIAL_IO_H_ +#define _INDUSTRIAL_IO_H_ + +#include +#include +#include "sysfs.h" +#include "chrdev.h" + +/* IIO TODO LIST */ +/* Static device specific elements (conversion factors etc) + * should be exported via sysfs + * + * Provide means of adjusting timer accuracy. + * Currently assumes nano seconds. + */ + +/* Event interface flags */ +#define IIO_BUSY_BIT_POS 1 + +struct iio_dev; + +/** + * iio_get_time_ns() - utility function to get a time stamp for events etc + **/ +static inline s64 iio_get_time_ns(void) +{ + struct timespec ts; + /* + * calls getnstimeofday. + * If hrtimers then up to ns accurate, if not microsecond. + */ + ktime_get_real_ts(&ts); + + return timespec_to_ns(&ts); +} + +/** + * iio_add_event_to_list() - Wraps adding to event lists + * @el: the list element of the event to be handled. + * @head: the list associated with the event handler being used. + * + * Does reference counting to allow shared handlers. + **/ +void iio_add_event_to_list(struct iio_event_handler_list *el, + struct list_head *head); + +/** + * iio_remove_event_from_list() - Wraps removing from event list + * @el: element to be removed + * @head: associate list head for the interrupt handler. + * + * Does reference counting to allow shared handlers. + **/ +void iio_remove_event_from_list(struct iio_event_handler_list *el, + struct list_head *head); + +/* Device operating modes */ +#define INDIO_DIRECT_MODE 0x01 +#define INDIO_RING_TRIGGERED 0x02 +#define INDIO_RING_HARDWARE_BUFFER 0x08 + +#define INDIO_ALL_RING_MODES (INDIO_RING_TRIGGERED | INDIO_RING_HARDWARE_BUFFER) + +/* Vast majority of this is set by the industrialio subsystem on a + * call to iio_device_register. */ + +/** + * struct iio_dev - industrial I/O device + * @id: [INTERN] used to identify device internally + * @dev_data: [DRIVER] device specific data + * @modes: [DRIVER] operating modes supported by device + * @currentmode: [DRIVER] current operating mode + * @dev: [DRIVER] device structure, should be assigned a parent + * and owner + * @attrs: [DRIVER] general purpose device attributes + * @driver_module: [DRIVER] module structure used to ensure correct + * ownership of chrdevs etc + * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device + * @interrupts: [INTERN] interrupt line specific event lists etc + * @event_attrs: [DRIVER] event control attributes + * @event_conf_attrs: [DRIVER] event configuration attributes + * @event_interfaces: [INTERN] event chrdevs associated with interrupt lines + * @ring: [DRIVER] any ring buffer present + * @mlock: [INTERN] lock used to prevent simultaneous device state + * changes + * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode + * control method is used + * @scan_count: [INTERN] the number of elements in the current scan mode + * @scan_mask: [INTERN] bitmask used in masking scan mode elements + * @scan_timestamp: [INTERN] does the scan mode include a timestamp + * @trig: [INTERN] current device trigger (ring buffer modes) + * @pollfunc: [DRIVER] function run on trigger being recieved + **/ +struct iio_dev { + int id; + void *dev_data; + int modes; + int currentmode; + struct device dev; + const struct attribute_group *attrs; + struct module *driver_module; + + int num_interrupt_lines; + struct iio_interrupt **interrupts; + struct attribute_group *event_attrs; + struct attribute_group *event_conf_attrs; + + struct iio_event_interface *event_interfaces; + + struct iio_ring_buffer *ring; + struct mutex mlock; + + struct attribute_group *scan_el_attrs; + int scan_count; + + u16 scan_mask; + bool scan_timestamp; + struct iio_trigger *trig; + struct iio_poll_func *pollfunc; +}; + +/* + * These are mainly provided to allow for a change of implementation if a device + * has a large number of scan elements + */ +#define IIO_MAX_SCAN_LENGTH 15 + +static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit) +{ + if (bit > IIO_MAX_SCAN_LENGTH) + return -EINVAL; + else + return !!(dev_info->scan_mask & (1 << bit)); +}; + +static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit) +{ + if (bit > IIO_MAX_SCAN_LENGTH) + return -EINVAL; + dev_info->scan_mask |= (1 << bit); + dev_info->scan_count++; + return 0; +}; + +static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit) +{ + if (bit > IIO_MAX_SCAN_LENGTH) + return -EINVAL; + dev_info->scan_mask &= ~(1 << bit); + dev_info->scan_count--; + return 0; +}; + +/** + * iio_scan_mask_count_to_right() - how many scan elements occur before here + * @dev_info: the iio_device whose scan mode we are querying + * @bit: which number scan element is this + **/ +static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info, +int bit) +{ + int count = 0; + int mask = (1 << bit); + if (bit > IIO_MAX_SCAN_LENGTH) + return -EINVAL; + while (mask) { + mask >>= 1; + if (mask & dev_info->scan_mask) + count++; + } + + return count; +} + +/** + * iio_device_register() - register a device with the IIO subsystem + * @dev_info: Device structure filled by the device driver + **/ +int iio_device_register(struct iio_dev *dev_info); + +/** + * iio_device_unregister() - unregister a device from the IIO subsystem + * @dev_info: Device structure representing the device. + **/ +void iio_device_unregister(struct iio_dev *dev_info); + +/** + * struct iio_interrupt - wrapper used to allow easy handling of multiple + * physical interrupt lines + * @dev_info: the iio device for which the is an interrupt line + * @line_number: associated line number + * @id: idr allocated unique id number + * @irq: associate interrupt number + * @ev_list: event handler list for associated events + * @ev_list_lock: ensure only one access to list at a time + **/ +struct iio_interrupt { + struct iio_dev *dev_info; + int line_number; + int id; + int irq; + struct list_head ev_list; + spinlock_t ev_list_lock; +}; + +#define to_iio_interrupt(i) container_of(i, struct iio_interrupt, ev_list) + +/** + * iio_register_interrupt_line() - Tell IIO about interrupt lines + * + * @irq: Typically provided via platform data + * @dev_info: IIO device info structure for device + * @line_number: Which interrupt line of the device is this? + * @type: Interrupt type (e.g. edge triggered etc) + * @name: Identifying name. + **/ +int iio_register_interrupt_line(unsigned int irq, + struct iio_dev *dev_info, + int line_number, + unsigned long type, + const char *name); + +void iio_unregister_interrupt_line(struct iio_dev *dev_info, + int line_number); + + + +/** + * iio_push_event() - try to add event to the list for userspace reading + * @dev_info: IIO device structure + * @ev_line: Which event line (hardware interrupt) + * @ev_code: What event + * @timestamp: When the event occured + **/ +int iio_push_event(struct iio_dev *dev_info, + int ev_line, + int ev_code, + s64 timestamp); + +/** + * struct iio_work_cont - container for when singleton handler case matters + * @ws: [DEVICE]work_struct when not only possible event + * @ws_nocheck: [DEVICE]work_struct when only possible event + * @address: [DEVICE]associated register address + * @mask: [DEVICE]associated mask for identifying event source + * @st: [DEVICE]device specific state information + **/ +struct iio_work_cont { + struct work_struct ws; + struct work_struct ws_nocheck; + int address; + int mask; + void *st; +}; + +#define to_iio_work_cont_check(_ws) \ + container_of(_ws, struct iio_work_cont, ws) + +#define to_iio_work_cont_no_check(_ws) \ + container_of(_ws, struct iio_work_cont, ws_nocheck) + +/** + * iio_init_work_cont() - intiialize the elements of a work container + * @cont: the work container + * @_checkfunc: function called when there are multiple possible int sources + * @_nocheckfunc: function for when there is only one int source + * @_add: driver dependant, typically a register address + * @_mask: driver dependant, typically a bit mask for a register + * @_st: driver dependant, typically pointer to a device state structure + **/ +static inline void +iio_init_work_cont(struct iio_work_cont *cont, + void (*_checkfunc)(struct work_struct *), + void (*_nocheckfunc)(struct work_struct *), + int _add, int _mask, void *_st) +{ + INIT_WORK(&(cont)->ws, _checkfunc); + INIT_WORK(&(cont)->ws_nocheck, _nocheckfunc); + cont->address = _add; + cont->mask = _mask; + cont->st = _st; +} +/** + * __iio_push_event() tries to add an event to the list associated with a chrdev + * @ev_int: the event interface to which we are pushing the event + * @ev_code: the outgoing event code + * @timestamp: timestamp of the event + * @shared_pointer_p: the shared event pointer + **/ +int __iio_push_event(struct iio_event_interface *ev_int, + int ev_code, + s64 timestamp, + struct iio_shared_ev_pointer* + shared_pointer_p); +/** + * __iio_change_event() change an event code in case of event escallation + * @ev: the evnet to be changed + * @ev_code: new event code + * @timestamp: new timestamp + **/ +void __iio_change_event(struct iio_detected_event_list *ev, + int ev_code, + s64 timestamp); + +/** + * iio_setup_ev_int() Configure an event interface (chrdev) + * @name: name used for resulting sysfs directory etc. + * @ev_int: interface we are configuring + * @owner: module that is responsible for registering this ev_int + * @dev: device whose ev_int this is + **/ +int iio_setup_ev_int(struct iio_event_interface *ev_int, + const char *name, + struct module *owner, + struct device *dev); + +void iio_free_ev_int(struct iio_event_interface *ev_int); + +/** + * iio_allocate_chrdev() - Allocate a chrdev + * @handler: struct that contains relevant file handling for chrdev + * @dev_info: iio_dev for which chrdev is being created + **/ +int iio_allocate_chrdev(struct iio_handler *handler, struct iio_dev *dev_info); +void iio_deallocate_chrdev(struct iio_handler *handler); + +/* Used to distinguish between bipolar and unipolar scan elemenents. + * Whilst this may seem obvious, we may well want to change the representation + * in the future!*/ +#define IIO_SIGNED(a) -(a) +#define IIO_UNSIGNED(a) (a) + +extern dev_t iio_devt; +extern struct class iio_class; + +/** + * iio_put_device() - reference counted deallocated of struct device + * @dev: the iio_device containing the device + **/ +static inline void iio_put_device(struct iio_dev *dev) +{ + if (dev) + put_device(&dev->dev); +}; + +/** + * to_iio_dev() - get iio_dev for which we have have the struct device + * @d: the struct device + **/ +static inline struct iio_dev *to_iio_dev(struct device *d) +{ + return container_of(d, struct iio_dev, dev); +}; + +/** + * iio_dev_get_devdata() - helper function gets device specific data + * @d: the iio_dev associated with the device + **/ +static inline void *iio_dev_get_devdata(struct iio_dev *d) +{ + return d->dev_data; +} + +/** + * iio_allocate_device() - allocate an iio_dev from a driver + **/ +struct iio_dev *iio_allocate_device(void); + +/** + * iio_free_device() - free an iio_dev from a driver + **/ +void iio_free_device(struct iio_dev *dev); + +/** + * iio_put() - internal module reference count reduce + **/ +void iio_put(void); + +/** + * iio_get() - internal module reference count increase + **/ +void iio_get(void); + +/* Ring buffer related */ +int iio_device_get_chrdev_minor(void); +void iio_device_free_chrdev_minor(int val); + +/** + * iio_ring_enabled() helper function to test if any form of ring enabled + **/ +static inline bool iio_ring_enabled(struct iio_dev *dev_info) +{ + return dev_info->currentmode + & (INDIO_RING_TRIGGERED + | INDIO_RING_HARDWARE_BUFFER); +}; + +struct idr; + +int iio_get_new_idr_val(struct idr *this_idr); +void iio_free_idr_val(struct idr *this_idr, int id); +#endif /* _INDUSTRIAL_IO_H_ */ diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c new file mode 100644 index 00000000000..660a9c1a1f3 --- /dev/null +++ b/drivers/staging/iio/industrialio-core.c @@ -0,0 +1,851 @@ +/* The industrial I/O core + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Based on elements of hwmon and input subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iio.h" +#include "trigger_consumer.h" + +#define IIO_ID_PREFIX "device" +#define IIO_ID_FORMAT IIO_ID_PREFIX "%d" + +/* IDR to assign each registered device a unique id*/ +static DEFINE_IDR(iio_idr); + +/* IDR for general event identifiers */ +static DEFINE_IDR(iio_event_idr); +/* IDR to allocate character device minor numbers */ +static DEFINE_IDR(iio_chrdev_idr); +/* Lock used to protect both of the above */ +static DEFINE_SPINLOCK(iio_idr_lock); + +dev_t iio_devt; +EXPORT_SYMBOL(iio_devt); + +#define IIO_DEV_MAX 256 +static char *iio_nodename(struct device *dev) +{ + return kasprintf(GFP_KERNEL, "iio/%s", dev_name(dev)); +} + +struct class iio_class = { + .name = "iio", + .nodename = iio_nodename, +}; +EXPORT_SYMBOL(iio_class); + +void __iio_change_event(struct iio_detected_event_list *ev, + int ev_code, + s64 timestamp) +{ + ev->ev.id = ev_code; + ev->ev.timestamp = timestamp; +} +EXPORT_SYMBOL(__iio_change_event); + +/* Used both in the interrupt line put events and the ring buffer ones */ + +/* Note that in it's current form someone has to be listening before events + * are queued. Hence a client MUST open the chrdev before the ring buffer is + * switched on. + */ + int __iio_push_event(struct iio_event_interface *ev_int, + int ev_code, + s64 timestamp, + struct iio_shared_ev_pointer * + shared_pointer_p) +{ + struct iio_detected_event_list *ev; + int ret = 0; + + /* Does anyone care? */ + mutex_lock(&ev_int->event_list_lock); + if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) { + if (ev_int->current_events == ev_int->max_events) + return 0; + ev = kmalloc(sizeof(*ev), GFP_KERNEL); + if (ev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ev->ev.id = ev_code; + ev->ev.timestamp = timestamp; + ev->shared_pointer = shared_pointer_p; + if (ev->shared_pointer) + shared_pointer_p->ev_p = ev; + + list_add_tail(&ev->list, &ev_int->det_events.list); + ev_int->current_events++; + mutex_unlock(&ev_int->event_list_lock); + wake_up_interruptible(&ev_int->wait); + } else + mutex_unlock(&ev_int->event_list_lock); + +error_ret: + return ret; +} +EXPORT_SYMBOL(__iio_push_event); + +int iio_push_event(struct iio_dev *dev_info, + int ev_line, + int ev_code, + s64 timestamp) +{ + return __iio_push_event(&dev_info->event_interfaces[ev_line], + ev_code, timestamp, NULL); +} +EXPORT_SYMBOL(iio_push_event); + +/* Generic interrupt line interrupt handler */ +irqreturn_t iio_interrupt_handler(int irq, void *_int_info) +{ + struct iio_interrupt *int_info = _int_info; + struct iio_dev *dev_info = int_info->dev_info; + struct iio_event_handler_list *p; + s64 time_ns; + unsigned long flags; + + spin_lock_irqsave(&int_info->ev_list_lock, flags); + if (list_empty(&int_info->ev_list)) { + spin_unlock_irqrestore(&int_info->ev_list_lock, flags); + return IRQ_NONE; + } + + time_ns = iio_get_time_ns(); + /* detect single element list*/ + if (list_is_singular(&int_info->ev_list)) { + disable_irq_nosync(irq); + p = list_first_entry(&int_info->ev_list, + struct iio_event_handler_list, + list); + /* single event handler - maybe shared */ + p->handler(dev_info, 1, time_ns, !(p->refcount > 1)); + } else + list_for_each_entry(p, &int_info->ev_list, list) { + disable_irq_nosync(irq); + p->handler(dev_info, 1, time_ns, 0); + } + spin_unlock_irqrestore(&int_info->ev_list_lock, flags); + + return IRQ_HANDLED; +} + +static struct iio_interrupt *iio_allocate_interrupt(void) +{ + struct iio_interrupt *i = kmalloc(sizeof *i, GFP_KERNEL); + if (i) { + spin_lock_init(&i->ev_list_lock); + INIT_LIST_HEAD(&i->ev_list); + } + return i; +} + +/* Confirming the validity of supplied irq is left to drivers.*/ +int iio_register_interrupt_line(unsigned int irq, + struct iio_dev *dev_info, + int line_number, + unsigned long type, + const char *name) +{ + int ret; + + dev_info->interrupts[line_number] = iio_allocate_interrupt(); + if (dev_info->interrupts[line_number] == NULL) { + ret = -ENOMEM; + goto error_ret; + } + dev_info->interrupts[line_number]->line_number = line_number; + dev_info->interrupts[line_number]->irq = irq; + dev_info->interrupts[line_number]->dev_info = dev_info; + + /* Possibly only request on demand? + * Can see this may complicate the handling of interrupts. + * However, with this approach we might end up handling lots of + * events no-one cares about.*/ + ret = request_irq(irq, + &iio_interrupt_handler, + type, + name, + dev_info->interrupts[line_number]); + +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_register_interrupt_line); + +/* This turns up an awful lot */ +ssize_t iio_read_const_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string); +} +EXPORT_SYMBOL(iio_read_const_attr); + +/* Before this runs the interrupt generator must have been disabled */ +void iio_unregister_interrupt_line(struct iio_dev *dev_info, int line_number) +{ + /* make sure the interrupt handlers are all done */ + flush_scheduled_work(); + free_irq(dev_info->interrupts[line_number]->irq, + dev_info->interrupts[line_number]); + kfree(dev_info->interrupts[line_number]); +} +EXPORT_SYMBOL(iio_unregister_interrupt_line); + +/* Reference counted add and remove */ +void iio_add_event_to_list(struct iio_event_handler_list *el, + struct list_head *head) +{ + unsigned long flags; + struct iio_interrupt *inter = to_iio_interrupt(head); + + /* take mutex to protect this element */ + mutex_lock(&el->exist_lock); + if (el->refcount == 0) { + /* Take the event list spin lock */ + spin_lock_irqsave(&inter->ev_list_lock, flags); + list_add(&el->list, head); + spin_unlock_irqrestore(&inter->ev_list_lock, flags); + } + el->refcount++; + mutex_unlock(&el->exist_lock); +} +EXPORT_SYMBOL(iio_add_event_to_list); + +void iio_remove_event_from_list(struct iio_event_handler_list *el, + struct list_head *head) +{ + unsigned long flags; + struct iio_interrupt *inter = to_iio_interrupt(head); + + mutex_lock(&el->exist_lock); + el->refcount--; + if (el->refcount == 0) { + /* Take the event list spin lock */ + spin_lock_irqsave(&inter->ev_list_lock, flags); + list_del_init(&el->list); + spin_unlock_irqrestore(&inter->ev_list_lock, flags); + } + mutex_unlock(&el->exist_lock); +} +EXPORT_SYMBOL(iio_remove_event_from_list); + +ssize_t iio_event_chrdev_read(struct file *filep, + char *buf, + size_t count, + loff_t *f_ps) +{ + struct iio_event_interface *ev_int = filep->private_data; + struct iio_detected_event_list *el; + int ret; + size_t len; + + mutex_lock(&ev_int->event_list_lock); + if (list_empty(&ev_int->det_events.list)) { + if (filep->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + goto error_mutex_unlock; + } + mutex_unlock(&ev_int->event_list_lock); + /* Blocking on device; waiting for something to be there */ + ret = wait_event_interruptible(ev_int->wait, + !list_empty(&ev_int + ->det_events.list)); + if (ret) + goto error_ret; + /* Single access device so noone else can get the data */ + mutex_lock(&ev_int->event_list_lock); + } + + el = list_first_entry(&ev_int->det_events.list, + struct iio_detected_event_list, + list); + len = sizeof el->ev; + if (copy_to_user(buf, &(el->ev), len)) { + ret = -EFAULT; + goto error_mutex_unlock; + } + list_del(&el->list); + ev_int->current_events--; + mutex_unlock(&ev_int->event_list_lock); + /* + * Possible concurency issue if an update of this event is on its way + * through. May lead to new even being removed whilst the reported event + * was the unescalated event. In typical use case this is not a problem + * as userspace will say read half the buffer due to a 50% full event + * which would make the correct 100% full incorrect anyway. + */ + spin_lock(&el->shared_pointer->lock); + if (el->shared_pointer) + (el->shared_pointer->ev_p) = NULL; + spin_unlock(&el->shared_pointer->lock); + + kfree(el); + + return len; + +error_mutex_unlock: + mutex_unlock(&ev_int->event_list_lock); +error_ret: + + return ret; +} + +int iio_event_chrdev_release(struct inode *inode, struct file *filep) +{ + struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); + struct iio_event_interface *ev_int = hand->private; + struct iio_detected_event_list *el, *t; + + mutex_lock(&ev_int->event_list_lock); + clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags); + /* + * In order to maintain a clean state for reopening, + * clear out any awaiting events. The mask will prevent + * any new __iio_push_event calls running. + */ + list_for_each_entry_safe(el, t, &ev_int->det_events.list, list) { + list_del(&el->list); + kfree(el); + } + mutex_unlock(&ev_int->event_list_lock); + + return 0; +} + +int iio_event_chrdev_open(struct inode *inode, struct file *filep) +{ + struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); + struct iio_event_interface *ev_int = hand->private; + + mutex_lock(&ev_int->event_list_lock); + if (test_and_set_bit(IIO_BUSY_BIT_POS, &hand->flags)) { + fops_put(filep->f_op); + mutex_unlock(&ev_int->event_list_lock); + return -EBUSY; + } + filep->private_data = hand->private; + mutex_unlock(&ev_int->event_list_lock); + + return 0; +} + +static const struct file_operations iio_event_chrdev_fileops = { + .read = iio_event_chrdev_read, + .release = iio_event_chrdev_release, + .open = iio_event_chrdev_open, + .owner = THIS_MODULE, +}; + +static void iio_event_dev_release(struct device *dev) +{ + struct iio_event_interface *ev_int + = container_of(dev, struct iio_event_interface, dev); + cdev_del(&ev_int->handler.chrdev); + iio_device_free_chrdev_minor(MINOR(dev->devt)); +}; + +static struct device_type iio_event_type = { + .release = iio_event_dev_release, +}; + +int iio_device_get_chrdev_minor(void) +{ + int ret, val; + +idr_again: + if (unlikely(idr_pre_get(&iio_chrdev_idr, GFP_KERNEL) == 0)) + return -ENOMEM; + spin_lock(&iio_idr_lock); + ret = idr_get_new(&iio_chrdev_idr, NULL, &val); + spin_unlock(&iio_idr_lock); + if (unlikely(ret == -EAGAIN)) + goto idr_again; + else if (unlikely(ret)) + return ret; + if (val > IIO_DEV_MAX) + return -ENOMEM; + return val; +} + +void iio_device_free_chrdev_minor(int val) +{ + spin_lock(&iio_idr_lock); + idr_remove(&iio_chrdev_idr, val); + spin_unlock(&iio_idr_lock); +} + +int iio_setup_ev_int(struct iio_event_interface *ev_int, + const char *name, + struct module *owner, + struct device *dev) +{ + int ret, minor; + + ev_int->dev.class = &iio_class; + ev_int->dev.parent = dev; + ev_int->dev.type = &iio_event_type; + device_initialize(&ev_int->dev); + + minor = iio_device_get_chrdev_minor(); + if (minor < 0) { + ret = minor; + goto error_device_put; + } + ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor); + dev_set_name(&ev_int->dev, "%s", name); + + ret = device_add(&ev_int->dev); + if (ret) + goto error_free_minor; + + cdev_init(&ev_int->handler.chrdev, &iio_event_chrdev_fileops); + ev_int->handler.chrdev.owner = owner; + + mutex_init(&ev_int->event_list_lock); + /* discussion point - make this variable? */ + ev_int->max_events = 10; + ev_int->current_events = 0; + INIT_LIST_HEAD(&ev_int->det_events.list); + init_waitqueue_head(&ev_int->wait); + ev_int->handler.private = ev_int; + ev_int->handler.flags = 0; + + ret = cdev_add(&ev_int->handler.chrdev, ev_int->dev.devt, 1); + if (ret) + goto error_unreg_device; + + return 0; + +error_unreg_device: + device_unregister(&ev_int->dev); +error_free_minor: + iio_device_free_chrdev_minor(minor); +error_device_put: + put_device(&ev_int->dev); + + return ret; +} + +void iio_free_ev_int(struct iio_event_interface *ev_int) +{ + device_unregister(&ev_int->dev); + put_device(&ev_int->dev); +} + +static int __init iio_dev_init(void) +{ + int err; + + err = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); + if (err < 0) + printk(KERN_ERR "%s: failed to allocate char dev region\n", + __FILE__); + + return err; +} + +static void __exit iio_dev_exit(void) +{ + if (iio_devt) + unregister_chrdev_region(iio_devt, IIO_DEV_MAX); +} + +static int __init iio_init(void) +{ + int ret; + + /* Create sysfs class */ + ret = class_register(&iio_class); + if (ret < 0) { + printk(KERN_ERR + "%s could not create sysfs class\n", + __FILE__); + goto error_nothing; + } + + ret = iio_dev_init(); + if (ret < 0) + goto error_unregister_class; + + return 0; + +error_unregister_class: + class_unregister(&iio_class); +error_nothing: + return ret; +} + +static void __exit iio_exit(void) +{ + iio_dev_exit(); + class_unregister(&iio_class); +} + +static int iio_device_register_sysfs(struct iio_dev *dev_info) +{ + int ret = 0; + + ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs); + if (ret) { + dev_err(dev_info->dev.parent, + "Failed to register sysfs hooks\n"); + goto error_ret; + } + + if (dev_info->scan_el_attrs) { + ret = sysfs_create_group(&dev_info->dev.kobj, + dev_info->scan_el_attrs); + if (ret) + dev_err(&dev_info->dev, + "Failed to add sysfs scan els\n"); + } + +error_ret: + return ret; +} + +static void iio_device_unregister_sysfs(struct iio_dev *dev_info) +{ + if (dev_info->scan_el_attrs) + sysfs_remove_group(&dev_info->dev.kobj, + dev_info->scan_el_attrs); + + sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs); +} + +int iio_get_new_idr_val(struct idr *this_idr) +{ + int ret; + int val; + +idr_again: + if (unlikely(idr_pre_get(this_idr, GFP_KERNEL) == 0)) + return -ENOMEM; + + spin_lock(&iio_idr_lock); + ret = idr_get_new(this_idr, NULL, &val); + spin_unlock(&iio_idr_lock); + if (unlikely(ret == -EAGAIN)) + goto idr_again; + else if (unlikely(ret)) + return ret; + + return val; +} +EXPORT_SYMBOL(iio_get_new_idr_val); + +void iio_free_idr_val(struct idr *this_idr, int id) +{ + spin_lock(&iio_idr_lock); + idr_remove(this_idr, id); + spin_unlock(&iio_idr_lock); +} +EXPORT_SYMBOL(iio_free_idr_val); + +static int iio_device_register_id(struct iio_dev *dev_info, + struct idr *this_idr) +{ + + dev_info->id = iio_get_new_idr_val(&iio_idr); + if (dev_info->id < 0) + return dev_info->id; + return 0; +} + +static void iio_device_unregister_id(struct iio_dev *dev_info) +{ + iio_free_idr_val(&iio_idr, dev_info->id); +} + +static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i) +{ + int ret; + /*p for adding, q for removing */ + struct attribute **attrp, **attrq; + + if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) { + attrp = dev_info->event_conf_attrs[i].attrs; + while (*attrp) { + ret = sysfs_add_file_to_group(&dev_info->dev.kobj, + *attrp, + dev_info + ->event_attrs[i].name); + if (ret) + goto error_ret; + attrp++; + } + } + return 0; + +error_ret: + attrq = dev_info->event_conf_attrs[i].attrs; + while (attrq != attrp) { + sysfs_remove_file_from_group(&dev_info->dev.kobj, + *attrq, + dev_info->event_attrs[i].name); + attrq++; + } + + return ret; +} + +static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info, + int i) +{ + struct attribute **attrq; + + if (dev_info->event_conf_attrs + && dev_info->event_conf_attrs[i].attrs) { + attrq = dev_info->event_conf_attrs[i].attrs; + while (*attrq) { + sysfs_remove_file_from_group(&dev_info->dev.kobj, + *attrq, + dev_info + ->event_attrs[i].name); + attrq++; + } + } + + return 0; +} + +static int iio_device_register_eventset(struct iio_dev *dev_info) +{ + int ret = 0, i, j; + + if (dev_info->num_interrupt_lines == 0) + return 0; + + dev_info->event_interfaces = + kzalloc(sizeof(struct iio_event_interface) + *dev_info->num_interrupt_lines, + GFP_KERNEL); + if (dev_info->event_interfaces == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + dev_info->interrupts = kzalloc(sizeof(struct iio_interrupt *) + *dev_info->num_interrupt_lines, + GFP_KERNEL); + if (dev_info->interrupts == NULL) { + ret = -ENOMEM; + goto error_free_event_interfaces; + } + + for (i = 0; i < dev_info->num_interrupt_lines; i++) { + dev_info->event_interfaces[i].owner = dev_info->driver_module; + ret = iio_get_new_idr_val(&iio_event_idr); + if (ret) + goto error_free_setup_ev_ints; + else + dev_info->event_interfaces[i].id = ret; + + snprintf(dev_info->event_interfaces[i]._name, 20, + "event_line%d", + dev_info->event_interfaces[i].id); + + ret = iio_setup_ev_int(&dev_info->event_interfaces[i], + (const char *)(dev_info + ->event_interfaces[i] + ._name), + dev_info->driver_module, + &dev_info->dev); + if (ret) { + dev_err(&dev_info->dev, + "Could not get chrdev interface\n"); + iio_free_idr_val(&iio_event_idr, + dev_info->event_interfaces[i].id); + goto error_free_setup_ev_ints; + } + } + + for (i = 0; i < dev_info->num_interrupt_lines; i++) { + snprintf(dev_info->event_interfaces[i]._attrname, 20, + "event_line%d_sources", i); + dev_info->event_attrs[i].name + = (const char *) + (dev_info->event_interfaces[i]._attrname); + ret = sysfs_create_group(&dev_info->dev.kobj, + &dev_info->event_attrs[i]); + if (ret) { + dev_err(&dev_info->dev, + "Failed to register sysfs for event attrs"); + goto error_remove_sysfs_interfaces; + } + } + + for (i = 0; i < dev_info->num_interrupt_lines; i++) { + ret = __iio_add_event_config_attrs(dev_info, i); + if (ret) + goto error_unregister_config_attrs; + } + + return 0; + +error_unregister_config_attrs: + for (j = 0; j < i; j++) + __iio_remove_event_config_attrs(dev_info, i); + i = dev_info->num_interrupt_lines - 1; +error_remove_sysfs_interfaces: + for (j = 0; j < i; j++) + sysfs_remove_group(&dev_info->dev.kobj, + &dev_info->event_attrs[j]); + i = dev_info->num_interrupt_lines - 1; +error_free_setup_ev_ints: + for (j = 0; j < i; j++) { + iio_free_idr_val(&iio_event_idr, + dev_info->event_interfaces[i].id); + iio_free_ev_int(&dev_info->event_interfaces[j]); + } + kfree(dev_info->interrupts); +error_free_event_interfaces: + kfree(dev_info->event_interfaces); +error_ret: + + return ret; +} + +static void iio_device_unregister_eventset(struct iio_dev *dev_info) +{ + int i; + + if (dev_info->num_interrupt_lines == 0) + return; + for (i = 0; i < dev_info->num_interrupt_lines; i++) + sysfs_remove_group(&dev_info->dev.kobj, + &dev_info->event_attrs[i]); + + for (i = 0; i < dev_info->num_interrupt_lines; i++) { + iio_free_idr_val(&iio_event_idr, + dev_info->event_interfaces[i].id); + iio_free_ev_int(&dev_info->event_interfaces[i]); + } + kfree(dev_info->interrupts); + kfree(dev_info->event_interfaces); +} + +static void iio_dev_release(struct device *device) +{ + struct iio_dev *dev = to_iio_dev(device); + + iio_put(); + kfree(dev); +} + +static struct device_type iio_dev_type = { + .name = "iio_device", + .release = iio_dev_release, +}; + +struct iio_dev *iio_allocate_device(void) +{ + struct iio_dev *dev = kzalloc(sizeof *dev, GFP_KERNEL); + + if (dev) { + dev->dev.type = &iio_dev_type; + dev->dev.class = &iio_class; + device_initialize(&dev->dev); + dev_set_drvdata(&dev->dev, (void *)dev); + mutex_init(&dev->mlock); + iio_get(); + } + + return dev; +} +EXPORT_SYMBOL(iio_allocate_device); + +void iio_free_device(struct iio_dev *dev) +{ + if (dev) + iio_put_device(dev); +} +EXPORT_SYMBOL(iio_free_device); + +int iio_device_register(struct iio_dev *dev_info) +{ + int ret; + + ret = iio_device_register_id(dev_info, &iio_idr); + if (ret) { + dev_err(&dev_info->dev, "Failed to get id\n"); + goto error_ret; + } + dev_set_name(&dev_info->dev, "device%d", dev_info->id); + + ret = device_add(&dev_info->dev); + if (ret) + goto error_free_idr; + ret = iio_device_register_sysfs(dev_info); + if (ret) { + dev_err(dev_info->dev.parent, + "Failed to register sysfs interfaces\n"); + goto error_del_device; + } + ret = iio_device_register_eventset(dev_info); + if (ret) { + dev_err(dev_info->dev.parent, + "Failed to register event set \n"); + goto error_free_sysfs; + } + if (dev_info->modes & INDIO_RING_TRIGGERED) + iio_device_register_trigger_consumer(dev_info); + + return 0; + +error_free_sysfs: + iio_device_unregister_sysfs(dev_info); +error_del_device: + device_del(&dev_info->dev); +error_free_idr: + iio_device_unregister_id(dev_info); +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_device_register); + +void iio_device_unregister(struct iio_dev *dev_info) +{ + if (dev_info->modes & INDIO_RING_TRIGGERED) + iio_device_unregister_trigger_consumer(dev_info); + iio_device_unregister_eventset(dev_info); + iio_device_unregister_sysfs(dev_info); + iio_device_unregister_id(dev_info); + device_unregister(&dev_info->dev); +} +EXPORT_SYMBOL(iio_device_unregister); + +void iio_put(void) +{ + module_put(THIS_MODULE); +} + +void iio_get(void) +{ + __module_get(THIS_MODULE); +} + +subsys_initcall(iio_init); +module_exit(iio_exit); + +MODULE_AUTHOR("Jonathan Cameron "); +MODULE_DESCRIPTION("Industrial I/O core"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h new file mode 100644 index 00000000000..bfe4055c0ed --- /dev/null +++ b/drivers/staging/iio/sysfs.h @@ -0,0 +1,293 @@ +/* The industrial I/O core + * + *Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * General attributes + */ + +#ifndef _INDUSTRIAL_IO_SYSFS_H_ +#define _INDUSTRIAL_IO_SYSFS_H_ + +#include "iio.h" + +/** + * struct iio_event_attribute - event control attribute + * @dev_attr: underlying device attribute + * @mask: mask for the event when detecting + * @listel: list header to allow addition to list of event handlers +*/ +struct iio_event_attr { + struct device_attribute dev_attr; + int mask; + struct iio_event_handler_list *listel; +}; + +#define to_iio_event_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_event_attr, dev_attr) + +/** + * struct iio_chrdev_minor_attr - simple attribute to allow reading of chrdev + * minor number + * @dev_attr: underlying device attribute + * @minor: the minor number + */ +struct iio_chrdev_minor_attr { + struct device_attribute dev_attr; + int minor; +}; + +void +__init_iio_chrdev_minor_attr(struct iio_chrdev_minor_attr *minor_attr, + const char *name, + struct module *owner, + int id); + + +#define to_iio_chrdev_minor_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_chrdev_minor_attr, dev_attr); + +/** + * struct iio_dev_attr - iio specific device attribute + * @dev_attr: underlying device attribute + * @address: associated register address + */ +struct iio_dev_attr { + struct device_attribute dev_attr; + int address; + int val2; +}; + +#define to_iio_dev_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_dev_attr, dev_attr) + +ssize_t iio_read_const_attr(struct device *dev, + struct device_attribute *attr, + char *len); + +/** + * struct iio_const_attr - constant device specific attribute + * often used for things like available modes + */ +struct iio_const_attr { + const char *string; + struct device_attribute dev_attr; +}; + +#define to_iio_const_attr(_dev_attr) \ + container_of(_dev_attr, struct iio_const_attr, dev_attr) + +/* Some attributes will be hard coded (device dependant) and not require an + address, in these cases pass a negative */ +#define IIO_ATTR(_name, _mode, _show, _store, _addr) \ + { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .address = _addr } + +#define IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2) \ + { .dev_attr = __ATTR(_name, _mode, _show, _store), \ + .address = _addr, \ + .val2 = _val2 } + +#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \ + struct iio_dev_attr iio_dev_attr_##_name \ + = IIO_ATTR(_name, _mode, _show, _store, _addr) + + +#define IIO_DEVICE_ATTR_2(_name, _mode, _show, _store, _addr, _val2) \ + struct iio_dev_attr iio_dev_attr_##_name \ + = IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2) + +#define IIO_CONST_ATTR(_name, _string) \ + struct iio_const_attr iio_const_attr_##_name \ + = { .string = _string, \ + .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} + +/* Generic attributes of onetype or another */ + +/** + * IIO_DEV_ATTR_REG: revision number for the device + * + * Very much device dependent. + **/ +#define IIO_DEV_ATTR_REV(_show) \ + IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0) +/** + * IIO_DEV_ATTR_NAME: chip type dependant identifier + **/ +#define IIO_DEV_ATTR_NAME(_show) \ + IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0) + +/** + * IIO_DEV_ATTR_SAMP_FREQ: sets any internal clock frequency + **/ +#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store) \ + IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0) + +/** + * IIO_DEV_ATTR_AVAIL_SAMP_FREQ: list available sampling frequencies. + * + * May be mode dependant on some devices + **/ +#define IIO_DEV_ATTR_AVAIL_SAMP_FREQ(_show) \ + IIO_DEVICE_ATTR(available_sampling_frequency, S_IRUGO, _show, NULL, 0) + +/** + * IIO_DEV_ATTR_CONST_AVAIL_SAMP_FREQ: list available sampling frequencies. + * + * Constant version + **/ +#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string) \ + IIO_CONST_ATTR(available_sampling_frequency, _string) +/** + * IIO_DEV_ATTR_SCAN_MODE: select a scan mode + * + * This is used when only certain combinations of inputs may be read in one + * scan. + **/ +#define IIO_DEV_ATTR_SCAN_MODE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(scan_mode, _mode, _show, _store, 0) +/** + * IIO_DEV_ATTR_AVAIL_SCAN_MODES: list available scan modes + **/ +#define IIO_DEV_ATTR_AVAIL_SCAN_MODES(_show) \ + IIO_DEVICE_ATTR(available_scan_modes, S_IRUGO, _show, NULL, 0) + +/** + * IIO_DEV_ATTR_SCAN: result of scan of multiple channels + **/ +#define IIO_DEV_ATTR_SCAN(_show) \ + IIO_DEVICE_ATTR(scan, S_IRUGO, _show, NULL, 0); + +/** + * IIO_DEV_ATTR_INPUT: direct read of a single input channel + **/ +#define IIO_DEV_ATTR_INPUT(_number, _show) \ + IIO_DEVICE_ATTR(in##_number, S_IRUGO, _show, NULL, _number) + + +/** + * IIO_DEV_ATTR_SW_RING_ENABLE: enable software ring buffer + * + * Success may be dependant on attachment of trigger previously + **/ +#define IIO_DEV_ATTR_SW_RING_ENABLE(_show, _store) \ + IIO_DEVICE_ATTR(sw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0) + +/** + * IIO_DEV_ATTR_HW_RING_ENABLE: enable hardware ring buffer + * + * This is a different attribute from the software one as one can invision + * schemes where a combination of the two may be used. + **/ +#define IIO_DEV_ATTR_HW_RING_ENABLE(_show, _store) \ + IIO_DEVICE_ATTR(hw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0) + +/** + * IIO_DEV_ATTR_BPSE: set number of bits per scan element + **/ +#define IIO_DEV_ATTR_BPSE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(bpse, _mode, _show, _store, 0) + +/** + * IIO_DEV_ATTR_BPSE_AVAILABLE: no of bits per scan element supported + **/ +#define IIO_DEV_ATTR_BPSE_AVAILABLE(_show) \ + IIO_DEVICE_ATTR(bpse_available, S_IRUGO, _show, NULL, 0) + +/** + * IIO_DEV_ATTR_TEMP: many sensors have auxiliary temperature sensors + **/ +#define IIO_DEV_ATTR_TEMP(_show) \ + IIO_DEVICE_ATTR(temp, S_IRUGO, _show, NULL, 0) +/** + * IIO_EVENT_SH: generic shared event handler + * + * This is used in cases where more than one event may result from a single + * handler. Often the case that some alarm register must be read and multiple + * alarms may have been triggered. + **/ +#define IIO_EVENT_SH(_name, _handler) \ + static struct iio_event_handler_list \ + iio_event_##_name = { \ + .handler = _handler, \ + .refcount = 0, \ + .exist_lock = __MUTEX_INITIALIZER(iio_event_##_name \ + .exist_lock), \ + .list = { \ + .next = &iio_event_##_name.list, \ + .prev = &iio_event_##_name.list, \ + }, \ + }; +/** + * IIO_EVENT_ATTR_SH: generic shared event attribute + * + * An attribute with an associated IIO_EVENT_SH + **/ +#define IIO_EVENT_ATTR_SH(_name, _ev_list, _show, _store, _mask) \ + static struct iio_event_attr \ + iio_event_attr_##_name \ + = { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR, \ + _show, _store), \ + .mask = _mask, \ + .listel = &_ev_list }; + +/** + * IIO_EVENT_ATTR: non shared event attribute + **/ +#define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler) \ + static struct iio_event_handler_list \ + iio_event_##_name = { \ + .handler = _handler, \ + }; \ + static struct \ + iio_event_attr \ + iio_event_attr_##_name \ + = { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR, \ + _show, _store), \ + .mask = _mask, \ + .listel = &iio_event_##_name }; \ + +/** + * IIO_EVENT_ATTR_DATA_RDY: event driven by data ready signal + * + * Not typically implemented in devices where full triggering support + * has been implemented + **/ +#define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \ + IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler) + +#define IIO_EVENT_CODE_DATA_RDY 100 +#define IIO_EVENT_CODE_RING_BASE 200 +#define IIO_EVENT_CODE_ACCEL_BASE 300 +#define IIO_EVENT_CODE_GYRO_BASE 400 +#define IIO_EVENT_CODE_ADC_BASE 500 +#define IIO_EVENT_CODE_MISC_BASE 600 + +#define IIO_EVENT_CODE_DEVICE_SPECIFIC 1000 + +/** + * IIO_EVENT_ATTR_RING_50_FULL: ring buffer event to indicate 50% full + **/ +#define IIO_EVENT_ATTR_RING_50_FULL(_show, _store, _mask, _handler) \ + IIO_EVENT_ATTR(ring_50_full, _show, _store, _mask, _handler) + +/** + * IIO_EVENT_ATTR_RING_50_FULL_SH: shared ring event to indicate 50% full + **/ +#define IIO_EVENT_ATTR_RING_50_FULL_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ring_50_full, _evlist, _show, _store, _mask) + +/** + * IIO_EVENT_ATTR_RING_75_FULL_SH: shared ring event to indicate 75% full + **/ +#define IIO_EVENT_ATTR_RING_75_FULL_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ring_75_full, _evlist, _show, _store, _mask) + +#define IIO_EVENT_CODE_RING_50_FULL IIO_EVENT_CODE_RING_BASE +#define IIO_EVENT_CODE_RING_75_FULL (IIO_EVENT_CODE_RING_BASE + 1) +#define IIO_EVENT_CODE_RING_100_FULL (IIO_EVENT_CODE_RING_BASE + 2) + +#endif /* _INDUSTRIAL_IO_SYSFS_H_ */ diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h new file mode 100644 index 00000000000..a6053892893 --- /dev/null +++ b/drivers/staging/iio/trigger_consumer.h @@ -0,0 +1,26 @@ + +/* The industrial I/O core, trigger consumer handling functions + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/** + * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers. + * @dev_info: iio_dev associated with the device that will consume the trigger + **/ +int iio_device_register_trigger_consumer(struct iio_dev *dev_info) +{ + return 0; +}; +/** + * iio_device_unregister_trigger_consumer() - reverse the registration process +. * @dev_info: iio_dev associated with the device that consumed the trigger + **/ +int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) +{ + return 0; +}; -- cgit v1.2.3 From ecdfa44610fa18678c3dd481af75368b9800c6c7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 Aug 2009 15:57:55 -0700 Subject: Staging: add Realtek 8192 PCI wireless driver This wireless driver should work for the Realtek 8192 PCI devices. It comes directly from Realtek and has been tested to work on at least one laptop in the wild. Cc: Anthony Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/rtl8192e/Kconfig | 6 + drivers/staging/rtl8192e/Makefile | 35 + drivers/staging/rtl8192e/dot11d.h | 102 + drivers/staging/rtl8192e/ieee80211.h | 2802 ++++++++ drivers/staging/rtl8192e/ieee80211/EndianFree.h | 199 + drivers/staging/rtl8192e/ieee80211/aes.c | 469 ++ drivers/staging/rtl8192e/ieee80211/api.c | 246 + drivers/staging/rtl8192e/ieee80211/arc4.c | 103 + drivers/staging/rtl8192e/ieee80211/autoload.c | 40 + drivers/staging/rtl8192e/ieee80211/cipher.c | 299 + drivers/staging/rtl8192e/ieee80211/compress.c | 64 + drivers/staging/rtl8192e/ieee80211/crypto_compat.h | 90 + drivers/staging/rtl8192e/ieee80211/digest.c | 108 + drivers/staging/rtl8192e/ieee80211/dot11d.c | 239 + drivers/staging/rtl8192e/ieee80211/dot11d.h | 102 + drivers/staging/rtl8192e/ieee80211/ieee80211.h | 2802 ++++++++ .../staging/rtl8192e/ieee80211/ieee80211_crypt.c | 273 + .../staging/rtl8192e/ieee80211/ieee80211_crypt.h | 93 + .../rtl8192e/ieee80211/ieee80211_crypt_ccmp.c | 534 ++ .../rtl8192e/ieee80211/ieee80211_crypt_tkip.c | 1034 +++ .../rtl8192e/ieee80211/ieee80211_crypt_wep.c | 397 ++ .../staging/rtl8192e/ieee80211/ieee80211_module.c | 432 ++ drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 2802 ++++++++ .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 3548 ++++++++++ .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 692 ++ drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | 933 +++ drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 1032 +++ drivers/staging/rtl8192e/ieee80211/internal.h | 115 + drivers/staging/rtl8192e/ieee80211/kmap_types.h | 20 + drivers/staging/rtl8192e/ieee80211/michael_mic.c | 194 + drivers/staging/rtl8192e/ieee80211/proc.c | 116 + drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h | 69 + .../staging/rtl8192e/ieee80211/rtl819x_BAProc.c | 779 +++ drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h | 481 ++ .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 1719 +++++ drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h | 749 ++ drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h | 56 + .../staging/rtl8192e/ieee80211/rtl819x_TSProc.c | 659 ++ drivers/staging/rtl8192e/ieee80211/rtl_crypto.h | 399 ++ drivers/staging/rtl8192e/ieee80211/scatterwalk.c | 126 + drivers/staging/rtl8192e/ieee80211/scatterwalk.h | 51 + drivers/staging/rtl8192e/ieee80211_crypt.h | 86 + drivers/staging/rtl8192e/r8180_93cx6.c | 146 + drivers/staging/rtl8192e/r8180_93cx6.h | 40 + drivers/staging/rtl8192e/r8190_rtl8256.c | 1161 ++++ drivers/staging/rtl8192e/r8190_rtl8256.h | 28 + drivers/staging/rtl8192e/r8192E.h | 1554 +++++ drivers/staging/rtl8192e/r8192E_core.c | 7192 ++++++++++++++++++++ drivers/staging/rtl8192e/r8192E_dm.c | 4257 ++++++++++++ drivers/staging/rtl8192e/r8192E_dm.h | 320 + drivers/staging/rtl8192e/r8192E_hw.h | 811 +++ drivers/staging/rtl8192e/r8192E_wx.c | 1408 ++++ drivers/staging/rtl8192e/r8192E_wx.h | 22 + drivers/staging/rtl8192e/r8192_pm.c | 181 + drivers/staging/rtl8192e/r8192_pm.h | 28 + drivers/staging/rtl8192e/r819xE_cmdpkt.c | 826 +++ drivers/staging/rtl8192e/r819xE_cmdpkt.h | 207 + drivers/staging/rtl8192e/r819xE_firmware.c | 668 ++ drivers/staging/rtl8192e/r819xE_firmware.h | 68 + drivers/staging/rtl8192e/r819xE_firmware_img.h | 2778 ++++++++ drivers/staging/rtl8192e/r819xE_phy.c | 3352 +++++++++ drivers/staging/rtl8192e/r819xE_phy.h | 125 + drivers/staging/rtl8192e/r819xE_phyreg.h | 878 +++ drivers/staging/rtl8192e/r819xP_firmware_img.h | 3637 ++++++++++ 66 files changed, 54785 insertions(+) create mode 100644 drivers/staging/rtl8192e/Kconfig create mode 100644 drivers/staging/rtl8192e/Makefile create mode 100644 drivers/staging/rtl8192e/dot11d.h create mode 100644 drivers/staging/rtl8192e/ieee80211.h create mode 100644 drivers/staging/rtl8192e/ieee80211/EndianFree.h create mode 100644 drivers/staging/rtl8192e/ieee80211/aes.c create mode 100644 drivers/staging/rtl8192e/ieee80211/api.c create mode 100644 drivers/staging/rtl8192e/ieee80211/arc4.c create mode 100644 drivers/staging/rtl8192e/ieee80211/autoload.c create mode 100644 drivers/staging/rtl8192e/ieee80211/cipher.c create mode 100644 drivers/staging/rtl8192e/ieee80211/compress.c create mode 100644 drivers/staging/rtl8192e/ieee80211/crypto_compat.h create mode 100644 drivers/staging/rtl8192e/ieee80211/digest.c create mode 100644 drivers/staging/rtl8192e/ieee80211/dot11d.c create mode 100644 drivers/staging/rtl8192e/ieee80211/dot11d.h create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211.h create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_module.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c create mode 100644 drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c create mode 100644 drivers/staging/rtl8192e/ieee80211/internal.h create mode 100644 drivers/staging/rtl8192e/ieee80211/kmap_types.h create mode 100644 drivers/staging/rtl8192e/ieee80211/michael_mic.c create mode 100644 drivers/staging/rtl8192e/ieee80211/proc.c create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c create mode 100644 drivers/staging/rtl8192e/ieee80211/rtl_crypto.h create mode 100644 drivers/staging/rtl8192e/ieee80211/scatterwalk.c create mode 100644 drivers/staging/rtl8192e/ieee80211/scatterwalk.h create mode 100644 drivers/staging/rtl8192e/ieee80211_crypt.h create mode 100644 drivers/staging/rtl8192e/r8180_93cx6.c create mode 100644 drivers/staging/rtl8192e/r8180_93cx6.h create mode 100644 drivers/staging/rtl8192e/r8190_rtl8256.c create mode 100644 drivers/staging/rtl8192e/r8190_rtl8256.h create mode 100644 drivers/staging/rtl8192e/r8192E.h create mode 100644 drivers/staging/rtl8192e/r8192E_core.c create mode 100644 drivers/staging/rtl8192e/r8192E_dm.c create mode 100644 drivers/staging/rtl8192e/r8192E_dm.h create mode 100644 drivers/staging/rtl8192e/r8192E_hw.h create mode 100644 drivers/staging/rtl8192e/r8192E_wx.c create mode 100644 drivers/staging/rtl8192e/r8192E_wx.h create mode 100644 drivers/staging/rtl8192e/r8192_pm.c create mode 100644 drivers/staging/rtl8192e/r8192_pm.h create mode 100644 drivers/staging/rtl8192e/r819xE_cmdpkt.c create mode 100644 drivers/staging/rtl8192e/r819xE_cmdpkt.h create mode 100644 drivers/staging/rtl8192e/r819xE_firmware.c create mode 100644 drivers/staging/rtl8192e/r819xE_firmware.h create mode 100644 drivers/staging/rtl8192e/r819xE_firmware_img.h create mode 100644 drivers/staging/rtl8192e/r819xE_phy.c create mode 100644 drivers/staging/rtl8192e/r819xE_phy.h create mode 100644 drivers/staging/rtl8192e/r819xE_phyreg.h create mode 100644 drivers/staging/rtl8192e/r819xP_firmware_img.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4d836a02343..2b3c0c45571 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -87,6 +87,8 @@ source "drivers/staging/rtl8187se/Kconfig" source "drivers/staging/rtl8192su/Kconfig" +source "drivers/staging/rtl8192e/Kconfig" + source "drivers/staging/rspiusb/Kconfig" source "drivers/staging/mimio/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f0c33eec012..aa9553cc6a5 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_PANEL) += panel/ obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ obj-$(CONFIG_RTL8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192SU) += rtl8192su/ +obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_USB_RSPI) += rspiusb/ obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig new file mode 100644 index 00000000000..3100aa58c94 --- /dev/null +++ b/drivers/staging/rtl8192e/Kconfig @@ -0,0 +1,6 @@ +config RTL8192E + tristate "RealTek RTL8192E Wireless LAN NIC driver" + depends on PCI + depends on WIRELESS_EXT + default N + ---help--- diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile new file mode 100644 index 00000000000..e24ab23369b --- /dev/null +++ b/drivers/staging/rtl8192e/Makefile @@ -0,0 +1,35 @@ +NIC_SELECT = RTL8192E + + +EXTRA_CFLAGS += -DRTL8192E +EXTRA_CFLAGS += -std=gnu89 +EXTRA_CFLAGS += -O2 +EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y +EXTRA_CFLAGS += -DTHOMAS_TURBO +EXTRA_CFLAGS += -DENABLE_DOT11D + +r8192_pci-objs := \ + r8192E_core.o \ + r8180_93cx6.o \ + r8192E_wx.o \ + r8190_rtl8256.o \ + r819xE_phy.o \ + r819xE_firmware.o \ + r819xE_cmdpkt.o \ + r8192E_dm.o \ + ieee80211/ieee80211_rx.o \ + ieee80211/ieee80211_softmac.o \ + ieee80211/ieee80211_tx.o \ + ieee80211/ieee80211_wx.o \ + ieee80211/ieee80211_module.o \ + ieee80211/ieee80211_softmac_wx.o \ + ieee80211/rtl819x_HTProc.o \ + ieee80211/rtl819x_TSProc.o \ + ieee80211/rtl819x_BAProc.o \ + ieee80211/dot11d.o \ + ieee80211/ieee80211_crypt.o \ + ieee80211/ieee80211_crypt_tkip.o \ + ieee80211/ieee80211_crypt_ccmp.o \ + ieee80211/ieee80211_crypt_wep.o + +obj-$(CONFIG_RTL8192E) += r8192_pci.o diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h new file mode 100644 index 00000000000..15b7a4ba37b --- /dev/null +++ b/drivers/staging/rtl8192e/dot11d.h @@ -0,0 +1,102 @@ +#ifndef __INC_DOT11D_H +#define __INC_DOT11D_H + +#ifdef ENABLE_DOT11D +#include "ieee80211.h" + +//#define ENABLE_DOT11D + +//#define DOT11D_MAX_CHNL_NUM 83 + +typedef struct _CHNL_TXPOWER_TRIPLE { + u8 FirstChnl; + u8 NumChnls; + u8 MaxTxPowerInDbm; +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; + +typedef enum _DOT11D_STATE { + DOT11D_STATE_NONE = 0, + DOT11D_STATE_LEARNED, + DOT11D_STATE_DONE, +}DOT11D_STATE; + +typedef struct _RT_DOT11D_INFO { + //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + + bool bEnabled; // dot11MultiDomainCapabilityEnabled + + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeWatchdog; + + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) + //u8 ChnlListLen; // #Bytes valid in ChnlList[]. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + + DOT11D_STATE State; +}RT_DOT11D_INFO, *PRT_DOT11D_INFO; +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) + +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) + +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ + FALSE : \ + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) + +#define CIE_WATCHDOG_TH 1 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) + +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) + + +void +Dot11d_Init( + struct ieee80211_device *dev + ); + +void +Dot11d_Reset( + struct ieee80211_device *dev + ); + +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ); + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ); + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ); + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +); +#endif //ENABLE_DOT11D +#endif // #ifndef __INC_DOT11D_H diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h new file mode 100644 index 00000000000..896fd17eea2 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211.h @@ -0,0 +1,2802 @@ +/* + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 + * remains copyright by the original authors + * + * Portions of the merged code are based on Host AP (software wireless + * LAN access point) driver for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * Copyright (c) 2004, Intel Corporation + * + * Modified for Realtek's wi-fi cards by Andrea Merello + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ +#ifndef IEEE80211_H +#define IEEE80211_H +#include /* ETH_ALEN */ +#include /* ARRAY_SIZE */ +#include +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#include +#else +#include +#include +#endif +#include +#include + +#include +#include + +#include "ieee80211/rtl819x_HT.h" +#include "ieee80211/rtl819x_BA.h" +#include "ieee80211/rtl819x_TS.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#ifndef bool +typedef enum{false = 0, true} bool; +#endif +#endif + +#ifndef IW_MODE_MONITOR +#define IW_MODE_MONITOR 6 +#endif + +#ifndef IWEVCUSTOM +#define IWEVCUSTOM 0x8c02 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#ifndef __bitwise +#define __bitwise __attribute__((bitwise)) +#endif +typedef __u16 __le16; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) +struct iw_spy_data{ + /* --- Standard spy support --- */ + int spy_number; + u_char spy_address[IW_MAX_SPY][ETH_ALEN]; + struct iw_quality spy_stat[IW_MAX_SPY]; + /* --- Enhanced spy support (event) */ + struct iw_quality spy_thr_low; /* Low threshold */ + struct iw_quality spy_thr_high; /* High threshold */ + u_char spy_thr_under[IW_MAX_SPY]; +}; +#endif +#endif + +#ifndef container_of +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#define KEY_TYPE_NA 0x0 +#define KEY_TYPE_WEP40 0x1 +#define KEY_TYPE_TKIP 0x2 +#define KEY_TYPE_CCMP 0x4 +#define KEY_TYPE_WEP104 0x5 + +/* added for rtl819x tx procedure */ +#define MAX_QUEUE_SIZE 0x10 + +// +// 8190 queue mapping +// +#define BK_QUEUE 0 +#define BE_QUEUE 1 +#define VI_QUEUE 2 +#define VO_QUEUE 3 +#define HCCA_QUEUE 4 +#define TXCMD_QUEUE 5 +#define MGNT_QUEUE 6 +#define HIGH_QUEUE 7 +#define BEACON_QUEUE 8 + +#define LOW_QUEUE BE_QUEUE +#define NORMAL_QUEUE MGNT_QUEUE + +//added by amy for ps +#define SWRF_TIMEOUT 50 + +//added by amy for LEAP related +#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. +#define SUPPORT_CKIP_MIC 0x08 // bit3 +#define SUPPORT_CKIP_PK 0x10 // bit4 +/* defined for skb cb field */ +/* At most 28 byte */ +typedef struct cb_desc { + /* Tx Desc Related flags (8-9) */ + u8 bLastIniPkt:1; + u8 bCmdOrInit:1; + u8 bFirstSeg:1; + u8 bLastSeg:1; + u8 bEncrypt:1; + u8 bTxDisableRateFallBack:1; + u8 bTxUseDriverAssingedRate:1; + u8 bHwSec:1; //indicate whether use Hw security. WB + + u8 reserved1; + + /* Tx Firmware Relaged flags (10-11)*/ + u8 bCTSEnable:1; + u8 bRTSEnable:1; + u8 bUseShortGI:1; + u8 bUseShortPreamble:1; + u8 bTxEnableFwCalcDur:1; + u8 bAMPDUEnable:1; + u8 bRTSSTBC:1; + u8 RTSSC:1; + + u8 bRTSBW:1; + u8 bPacketBW:1; + u8 bRTSUseShortPreamble:1; + u8 bRTSUseShortGI:1; + u8 bMulticast:1; + u8 bBroadcast:1; + //u8 reserved2:2; + u8 drv_agg_enable:1; + u8 reserved2:1; + + /* Tx Desc related element(12-19) */ + u8 rata_index; + u8 queue_index; + //u8 reserved3; + //u8 reserved4; + u16 txbuf_size; + //u8 reserved5; + u8 RATRIndex; + u8 reserved6; + u8 reserved7; + u8 reserved8; + + /* Tx firmware related element(20-27) */ + u8 data_rate; + u8 rts_rate; + u8 ampdu_factor; + u8 ampdu_density; + //u8 reserved9; + //u8 reserved10; + //u8 reserved11; + u8 DrvAggrNum; + u16 pkt_size; + u8 reserved12; +}cb_desc, *pcb_desc; + +/*--------------------------Define -------------------------------------------*/ +#define MGN_1M 0x02 +#define MGN_2M 0x04 +#define MGN_5_5M 0x0b +#define MGN_11M 0x16 + +#define MGN_6M 0x0c +#define MGN_9M 0x12 +#define MGN_12M 0x18 +#define MGN_18M 0x24 +#define MGN_24M 0x30 +#define MGN_36M 0x48 +#define MGN_48M 0x60 +#define MGN_54M 0x6c + +#define MGN_MCS0 0x80 +#define MGN_MCS1 0x81 +#define MGN_MCS2 0x82 +#define MGN_MCS3 0x83 +#define MGN_MCS4 0x84 +#define MGN_MCS5 0x85 +#define MGN_MCS6 0x86 +#define MGN_MCS7 0x87 +#define MGN_MCS8 0x88 +#define MGN_MCS9 0x89 +#define MGN_MCS10 0x8a +#define MGN_MCS11 0x8b +#define MGN_MCS12 0x8c +#define MGN_MCS13 0x8d +#define MGN_MCS14 0x8e +#define MGN_MCS15 0x8f + +//---------------------------------------------------------------------------- +// 802.11 Management frame Reason Code field +//---------------------------------------------------------------------------- +enum _ReasonCode{ + unspec_reason = 0x1, + auth_not_valid = 0x2, + deauth_lv_ss = 0x3, + inactivity = 0x4, + ap_overload = 0x5, + class2_err = 0x6, + class3_err = 0x7, + disas_lv_ss = 0x8, + asoc_not_auth = 0x9, + + //----MIC_CHECK + mic_failure = 0xe, + //----END MIC_CHECK + + // Reason code defined in 802.11i D10.0 p.28. + invalid_IE = 0x0d, + four_way_tmout = 0x0f, + two_way_tmout = 0x10, + IE_dismatch = 0x11, + invalid_Gcipher = 0x12, + invalid_Pcipher = 0x13, + invalid_AKMP = 0x14, + unsup_RSNIEver = 0x15, + invalid_RSNIE = 0x16, + auth_802_1x_fail= 0x17, + ciper_reject = 0x18, + + // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15. + QoS_unspec = 0x20, // 32 + QAP_bandwidth = 0x21, // 33 + poor_condition = 0x22, // 34 + no_facility = 0x23, // 35 + // Where is 36??? + req_declined = 0x25, // 37 + invalid_param = 0x26, // 38 + req_not_honored= 0x27, // 39 + TS_not_created = 0x2F, // 47 + DL_not_allowed = 0x30, // 48 + dest_not_exist = 0x31, // 49 + dest_not_QSTA = 0x32, // 50 +}; + + + +#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10) + +#define MGMT_QUEUE_NUM 5 + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +//It should consistent with the driver_XXX.c +// David, 2006.9.26 +#define IEEE_PARAM_WPAX_SELECT 7 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_PROTO_WPA 1 +#define IEEE_PROTO_RSN 2 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_WPAX_USEGROUP 0 +#define IEEE_WPAX_WEP40 1 +#define IEEE_WPAX_TKIP 2 +#define IEEE_WPAX_WRAP 3 +#define IEEE_WPAX_CCMP 4 +#define IEEE_WPAX_WEP104 5 + +#define IEEE_KEY_MGMT_IEEE8021X 1 +#define IEEE_KEY_MGMT_PSK 2 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define MAX_IE_LEN 0xff + +// added for kernel conflict +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rsl +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rsl + +#define ieee80211_ccmp_null ieee80211_ccmp_null_rsl + +#define ieee80211_tkip_null ieee80211_tkip_null_rsl + +#define ieee80211_wep_null ieee80211_wep_null_rsl + +#define free_ieee80211 free_ieee80211_rsl +#define alloc_ieee80211 alloc_ieee80211_rsl + +#define ieee80211_rx ieee80211_rx_rsl +#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl + +#define ieee80211_get_beacon ieee80211_get_beacon_rsl +#define ieee80211_wake_queue ieee80211_wake_queue_rsl +#define ieee80211_stop_queue ieee80211_stop_queue_rsl +#define ieee80211_reset_queue ieee80211_reset_queue_rsl +#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl +#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl +#define ieee80211_is_shortslot ieee80211_is_shortslot_rsl +#define ieee80211_is_54g ieee80211_is_54g_rsl +#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl +#define ieee80211_ps_tx_ack ieee80211_ps_tx_ack_rsl +#define ieee80211_softmac_xmit ieee80211_softmac_xmit_rsl +#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rsl +#define notify_wx_assoc_event notify_wx_assoc_event_rsl +#define SendDisassociation SendDisassociation_rsl +#define ieee80211_disassociate ieee80211_disassociate_rsl +#define ieee80211_start_send_beacons ieee80211_start_send_beacons_rsl +#define ieee80211_stop_scan ieee80211_stop_scan_rsl +#define ieee80211_send_probe_requests ieee80211_send_probe_requests_rsl +#define ieee80211_softmac_scan_syncro ieee80211_softmac_scan_syncro_rsl +#define ieee80211_start_scan_syncro ieee80211_start_scan_syncro_rsl + +#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rsl +#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rsl +#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rsl +#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rsl +#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rsl +#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rsl +#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rsl +#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rsl +#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rsl +#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rsl +#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rsl +#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rsl +#define ieee80211_wx_get_name ieee80211_wx_get_name_rsl +#define ieee80211_wx_set_power ieee80211_wx_set_power_rsl +#define ieee80211_wx_get_power ieee80211_wx_get_power_rsl +#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rsl +#define ieee80211_wx_set_rts ieee80211_wx_set_rts_rsl +#define ieee80211_wx_get_rts ieee80211_wx_get_rts_rsl + +#define ieee80211_txb_free ieee80211_txb_free_rsl + +#define ieee80211_wx_set_gen_ie ieee80211_wx_set_gen_ie_rsl +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl +#if WIRELESS_EXT >= 18 +#define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl +#define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl +#define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl +#endif + + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; + } u; +}ieee_param; + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data) +{ + task->routine = func; + task->data = data; + //task->next = NULL; + INIT_LIST_HEAD(&task->list); + task->sync = 0; +} +#endif + +// linux under 2.6.9 release may not support it, so modify it for common use +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) +static inline unsigned long msleep_interruptible_rsl(unsigned int msecs) +{ + unsigned long timeout = MSECS(msecs) + 1; + + while (timeout) { + set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return timeout; +} +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31)) +static inline void msleep(unsigned int msecs) +{ + unsigned long timeout = MSECS(msecs) + 1; + + while (timeout) { + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } +} +#endif +#else +#define MSECS(t) msecs_to_jiffies(t) +#define msleep_interruptible_rsl msleep_interruptible +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ +#define IEEE80211_1ADDR_LEN 10 +#define IEEE80211_2ADDR_LEN 16 +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + + +/* Frame control field constants */ +#define IEEE80211_FCTL_VERS 0x0003 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_STYPE 0x00f0 +#define IEEE80211_FCTL_FRAMETYPE 0x00fc +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david +#define IEEE80211_FCTL_MOREFRAGS 0x0400 +#define IEEE80211_FCTL_RETRY 0x0800 +#define IEEE80211_FCTL_PM 0x1000 +#define IEEE80211_FCTL_MOREDATA 0x2000 +#define IEEE80211_FCTL_WEP 0x4000 +#define IEEE80211_FCTL_ORDER 0x8000 + +#define IEEE80211_FTYPE_MGMT 0x0000 +#define IEEE80211_FTYPE_CTL 0x0004 +#define IEEE80211_FTYPE_DATA 0x0008 + +/* management */ +#define IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define IEEE80211_STYPE_PROBE_REQ 0x0040 +#define IEEE80211_STYPE_PROBE_RESP 0x0050 +#define IEEE80211_STYPE_BEACON 0x0080 +#define IEEE80211_STYPE_ATIM 0x0090 +#define IEEE80211_STYPE_DISASSOC 0x00A0 +#define IEEE80211_STYPE_AUTH 0x00B0 +#define IEEE80211_STYPE_DEAUTH 0x00C0 +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 + +/* control */ +#define IEEE80211_STYPE_PSPOLL 0x00A0 +#define IEEE80211_STYPE_RTS 0x00B0 +#define IEEE80211_STYPE_CTS 0x00C0 +#define IEEE80211_STYPE_ACK 0x00D0 +#define IEEE80211_STYPE_CFEND 0x00E0 +#define IEEE80211_STYPE_CFENDACK 0x00F0 +#define IEEE80211_STYPE_BLOCKACK 0x0094 + +/* data */ +#define IEEE80211_STYPE_DATA 0x0000 +#define IEEE80211_STYPE_DATA_CFACK 0x0010 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define IEEE80211_STYPE_NULLFUNC 0x0040 +#define IEEE80211_STYPE_CFACK 0x0050 +#define IEEE80211_STYPE_CFPOLL 0x0060 +#define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 +#define IEEE80211_STYPE_QOS_NULL 0x00C0 + +#define IEEE80211_SCTL_FRAG 0x000F +#define IEEE80211_SCTL_SEQ 0xFFF0 + +/* QOS control */ +#define IEEE80211_QCTL_TID 0x000F + +#define FC_QOS_BIT BIT7 +#define IsDataFrame(pdu) ( ((pdu[0] & 0x0C)==0x08) ? true : false ) +#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) ) +//added by wb. Is this right? +#define IsQoSDataFrame(pframe) ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) +#define Frame_Order(pframe) (*(u16*)pframe&IEEE80211_FCTL_ORDER) +#define SN_LESS(a, b) (((a-b)&0x800)!=0) +#define SN_EQUAL(a, b) (a == b) +#define MAX_DEV_ADDR_SIZE 8 +typedef enum _ACT_CATEGORY{ + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +} ACT_CATEGORY, *PACT_CATEGORY; + +typedef enum _TS_ACTION{ + ACT_ADDTSREQ = 0, + ACT_ADDTSRSP = 1, + ACT_DELTS = 2, + ACT_SCHEDULE = 3, +} TS_ACTION, *PTS_ACTION; + +typedef enum _BA_ACTION{ + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +} BA_ACTION, *PBA_ACTION; + +typedef enum _InitialGainOpType{ + IG_Backup=0, + IG_Restore, + IG_Max +}InitialGainOpType; + +/* debug macros */ +#define CONFIG_IEEE80211_DEBUG +#ifdef CONFIG_IEEE80211_DEBUG +extern u32 ieee80211_debug_level; +#define IEEE80211_DEBUG(level, fmt, args...) \ +do { if (ieee80211_debug_level & (level)) \ + printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) +//wb added to debug out data buf +//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA +#define IEEE80211_DEBUG_DATA(level, data, datalen) \ + do{ if ((ieee80211_debug_level & (level)) == (level)) \ + { \ + int i; \ + u8* pdata = (u8*) data; \ + printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__); \ + for(i=0; i<(int)(datalen); i++) \ + { \ + printk("%2x ", pdata[i]); \ + if ((i+1)%16 == 0) printk("\n"); \ + } \ + printk("\n"); \ + } \ + } while (0) +#else +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) +#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) +#endif /* CONFIG_IEEE80211_DEBUG */ + +/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define IEEE80211_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/ipw/debug_level + * + * you simply need to add your entry to the ipw_debug_levels array. + * + * If you do not see debug_level in /proc/net/ipw then you do not have + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration + * + */ + +#define IEEE80211_DL_INFO (1<<0) +#define IEEE80211_DL_WX (1<<1) +#define IEEE80211_DL_SCAN (1<<2) +#define IEEE80211_DL_STATE (1<<3) +#define IEEE80211_DL_MGMT (1<<4) +#define IEEE80211_DL_FRAG (1<<5) +#define IEEE80211_DL_EAP (1<<6) +#define IEEE80211_DL_DROP (1<<7) + +#define IEEE80211_DL_TX (1<<8) +#define IEEE80211_DL_RX (1<<9) + +#define IEEE80211_DL_HT (1<<10) //HT +#define IEEE80211_DL_BA (1<<11) //ba +#define IEEE80211_DL_TS (1<<12) //TS +#define IEEE80211_DL_QOS (1<<13) +#define IEEE80211_DL_REORDER (1<<14) +#define IEEE80211_DL_IOT (1<<15) +#define IEEE80211_DL_IPS (1<<16) +#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen +#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. +#define IEEE80211_DL_ERR (1<<31) //always open +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) + +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) +#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) + +#ifdef CONFIG_IEEE80211_DEBUG +/* Added by Annie, 2005-11-22. */ +#define MAX_STR_LEN 64 +/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ +#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') +#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ + if((_Comp) & level) \ + { \ + int __i; \ + u8 buffer[MAX_STR_LEN]; \ + int length = (_Len\n", _Len, buffer); \ + } +#else +#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) do {} while (0) +#endif + +#include +#include /* ARPHRD_ETHER */ + +#ifndef WIRELESS_SPY +#define WIRELESS_SPY // enable iwspy support +#endif +#include // new driver API + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __attribute__ ((packed)); + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) + +#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_LEAP 2 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) + +/* 802.11g ERP information element */ +#define WLAN_ERP_NON_ERP_PRESENT (1<<0) +#define WLAN_ERP_USE_PROTECTION (1<<1) +#define WLAN_ERP_BARKER_PREAMBLE (1<<2) + +/* Status codes */ +enum ieee80211_statuscode { + WLAN_STATUS_SUCCESS = 0, + WLAN_STATUS_UNSPECIFIED_FAILURE = 1, + WLAN_STATUS_CAPS_UNSUPPORTED = 10, + WLAN_STATUS_REASSOC_NO_ASSOC = 11, + WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, + WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, + WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, + WLAN_STATUS_CHALLENGE_FAIL = 15, + WLAN_STATUS_AUTH_TIMEOUT = 16, + WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, + WLAN_STATUS_ASSOC_DENIED_RATES = 18, + /* 802.11b */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, + WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, + WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, + /* 802.11h */ + WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, + WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, + WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, + /* 802.11g */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, + WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, + /* 802.11i */ + WLAN_STATUS_INVALID_IE = 40, + WLAN_STATUS_INVALID_GROUP_CIPHER = 41, + WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, + WLAN_STATUS_INVALID_AKMP = 43, + WLAN_STATUS_UNSUPP_RSN_VERSION = 44, + WLAN_STATUS_INVALID_RSN_IE_CAP = 45, + WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, +}; + +/* Reason codes */ +enum ieee80211_reasoncode { + WLAN_REASON_UNSPECIFIED = 1, + WLAN_REASON_PREV_AUTH_NOT_VALID = 2, + WLAN_REASON_DEAUTH_LEAVING = 3, + WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, + WLAN_REASON_DISASSOC_AP_BUSY = 5, + WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, + WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, + WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, + /* 802.11h */ + WLAN_REASON_DISASSOC_BAD_POWER = 10, + WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, + /* 802.11i */ + WLAN_REASON_INVALID_IE = 13, + WLAN_REASON_MIC_FAILURE = 14, + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, + WLAN_REASON_IE_DIFFERENT = 17, + WLAN_REASON_INVALID_GROUP_CIPHER = 18, + WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, + WLAN_REASON_INVALID_AKMP = 20, + WLAN_REASON_UNSUPP_RSN_VERSION = 21, + WLAN_REASON_INVALID_RSN_IE_CAP = 22, + WLAN_REASON_IEEE8021X_FAILED = 23, + WLAN_REASON_CIPHER_SUITE_REJECTED = 24, +}; + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + +/* this is stolen and modified from the madwifi driver*/ +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_DATA 0x08 +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 + +#define IEEE80211_QOS_HAS_SEQ(fc) \ + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num[17]; + u16 frag_num[17]; + unsigned long packet_time[17]; + struct list_head list; +}; + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { +#if 1 + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u16 rate; /* in 100 kbps */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 Length; + // u8 DataRate; // In 0.5 Mbps + u8 SignalQuality; // in 0-100 index. + s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. + s8 RxPower; // in dBm Translate from PWdB + u8 SignalStrength; // in 0-100 index. + u16 bHwError:1; + u16 bCRC:1; + u16 bICV:1; + u16 bShortPreamble:1; + u16 Antenna:1; //for rtl8185 + u16 Decrypted:1; //for rtl8185, rtl8187 + u16 Wakeup:1; //for rtl8185 + u16 Reserved0:1; //for rtl8185 + u8 AGC; + u32 TimeStampLow; + u32 TimeStampHigh; + bool bShift; + bool bIsQosData; // Added by Annie, 2005-12-22. + u8 UserPriority; + + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + //1Attention Please!!!<11n or 8190 specific code should be put below this line> + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + + u8 RxDrvInfoSize; + u8 RxBufShift; + bool bIsAMPDU; + bool bFirstMPDU; + bool bContainHTC; + bool RxIs40MHzPacket; + u32 RxPWDBAll; + u8 RxMIMOSignalStrength[4]; // in 0~100 index + s8 RxMIMOSignalQuality[2]; + bool bPacketMatchBSSID; + bool bIsCCK; + bool bPacketToSelf; + //added by amy + u8* virtual_address; + u16 packetlength; // Total packet length: Must equal to sum of all FragLength + u16 fraglength; // FragLength should equal to PacketLength in non-fragment case + u16 fragoffset; // Data offset for this fragment + u16 ntotalfrag; + bool bisrxaggrsubframe; + bool bPacketBeacon; //cosa add for rssi + bool bToSelfBA; //cosa add for rssi + char cck_adc_pwdb[4]; //cosa add for rx path selection + u16 Seq_Num; +#endif + +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + unsigned long first_frag_time; + unsigned int seq; + unsigned int last_frag; + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +struct ieee80211_stats { + unsigned int tx_unicast_frames; + unsigned int tx_multicast_frames; + unsigned int tx_fragments; + unsigned int tx_unicast_octets; + unsigned int tx_multicast_octets; + unsigned int tx_deferred_transmissions; + unsigned int tx_single_retry_frames; + unsigned int tx_multiple_retry_frames; + unsigned int tx_retry_limit_exceeded; + unsigned int tx_discards; + unsigned int rx_unicast_frames; + unsigned int rx_multicast_frames; + unsigned int rx_fragments; + unsigned int rx_unicast_octets; + unsigned int rx_multicast_octets; + unsigned int rx_fcs_errors; + unsigned int rx_discards_no_buffer; + unsigned int tx_discards_wrong_sa; + unsigned int rx_discards_undecryptable; + unsigned int rx_message_in_msg_fragments; + unsigned int rx_message_in_bad_msg_fragments; +}; + +struct ieee80211_device; + +#include "ieee80211_crypt.h" + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) +#define SEC_ENCRYPT (1<<9) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define SEC_ALG_NONE 0 +#define SEC_ALG_WEP 1 +#define SEC_ALG_TKIP 2 +#define SEC_ALG_CCMP 3 + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 +#define SCM_KEY_LEN 32 +#define SCM_TEMPORAL_KEY_LENGTH 16 + +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1, + encrypt:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][SCM_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + + +/* + 802.11 data frame from AP + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' +Total: 28-2340 bytes +*/ + +/* Management Frame Information Element Types */ +enum ieee80211_mfie { + MFIE_TYPE_SSID = 0, + MFIE_TYPE_RATES = 1, + MFIE_TYPE_FH_SET = 2, + MFIE_TYPE_DS_SET = 3, + MFIE_TYPE_CF_SET = 4, + MFIE_TYPE_TIM = 5, + MFIE_TYPE_IBSS_SET = 6, + MFIE_TYPE_COUNTRY = 7, + MFIE_TYPE_HOP_PARAMS = 8, + MFIE_TYPE_HOP_TABLE = 9, + MFIE_TYPE_REQUEST = 10, + MFIE_TYPE_CHALLENGE = 16, + MFIE_TYPE_POWER_CONSTRAINT = 32, + MFIE_TYPE_POWER_CAPABILITY = 33, + MFIE_TYPE_TPC_REQUEST = 34, + MFIE_TYPE_TPC_REPORT = 35, + MFIE_TYPE_SUPP_CHANNELS = 36, + MFIE_TYPE_CSA = 37, + MFIE_TYPE_MEASURE_REQUEST = 38, + MFIE_TYPE_MEASURE_REPORT = 39, + MFIE_TYPE_QUIET = 40, + MFIE_TYPE_IBSS_DFS = 41, + MFIE_TYPE_ERP = 42, + MFIE_TYPE_RSN = 48, + MFIE_TYPE_RATES_EX = 50, + MFIE_TYPE_HT_CAP= 45, + MFIE_TYPE_HT_INFO= 61, + MFIE_TYPE_AIRONET=133, + MFIE_TYPE_GENERIC = 221, + MFIE_TYPE_QOS_PARAMETER = 222, +}; + +/* Minimal header; can be used for passing 802.11 frames with sufficient + * information to determine what type of underlying data type is actually + * stored in the data. */ +struct ieee80211_hdr { + __le16 frame_ctl; + __le16 duration_id; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_1addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_2addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; + __le16 qos_ctl; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; + __le16 qos_ctl; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); + +struct ieee80211_authentication { + struct ieee80211_hdr_3addr header; + __le16 algorithm; + __le16 transaction; + __le16 status; + /*challenge*/ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_disassoc { + struct ieee80211_hdr_3addr header; + __le16 reason; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_hdr_3addr header; + /* SSID, supported rates */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_probe_response { + struct ieee80211_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +/* Alias beacon for probe_response */ +#define ieee80211_beacon ieee80211_probe_response + +struct ieee80211_assoc_request_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + /* SSID, supported rates, RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_reassoc_request_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + u8 current_ap[ETH_ALEN]; + /* SSID, supported rates, RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 status; + __le16 aid; + struct ieee80211_info_element info_element[0]; /* supported rates */ +} __attribute__ ((packed)); + +struct ieee80211_txb { + u8 nr_frags; + u8 encrypted; + u8 queue_index; + u8 rts_included; + u16 reserved; + __le16 frag_size; + __le16 payload_size; + struct sk_buff *fragments[0]; +}; + +#define MAX_TX_AGG_COUNT 16 +struct ieee80211_drv_agg_txb { + u8 nr_drv_agg_frames; + struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; +}__attribute__((packed)); + +#define MAX_SUBFRAME_COUNT 64 +struct ieee80211_rxb { + u8 nr_subframes; + struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; +}__attribute__((packed)); + +typedef union _frameqos { + u16 shortdata; + u8 chardata[2]; + struct { + u16 tid:4; + u16 eosp:1; + u16 ack_policy:2; + u16 reserved:1; + u16 txop:8; + }field; +}frameqos,*pframeqos; + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 + +#define MAX_CHANNEL_NUMBER 161 +#define IEEE80211_SOFTMAC_SCAN_TIME 100 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN 64 + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +/* QoS structure */ +#define NETWORK_HAS_QOS_PARAMETERS (1<<3) +#define NETWORK_HAS_QOS_INFORMATION (1<<4) +#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ + NETWORK_HAS_QOS_INFORMATION) +/* 802.11h */ +#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) +#define NETWORK_HAS_CSA (1<<6) +#define NETWORK_HAS_QUIET (1<<7) +#define NETWORK_HAS_IBSS_DFS (1<<8) +#define NETWORK_HAS_TPC_REPORT (1<<9) + +#define NETWORK_HAS_ERP_VALUE (1<<10) + +#define QOS_QUEUE_NUM 4 +#define QOS_OUI_LEN 3 +#define QOS_OUI_TYPE 2 +#define QOS_ELEMENT_ID 221 +#define QOS_OUI_INFO_SUB_TYPE 0 +#define QOS_OUI_PARAM_SUB_TYPE 1 +#define QOS_VERSION_1 1 +#define QOS_AIFSN_MIN_VALUE 2 +#if 1 +struct ieee80211_qos_information_element { + u8 elementID; + u8 length; + u8 qui[QOS_OUI_LEN]; + u8 qui_type; + u8 qui_subtype; + u8 version; + u8 ac_info; +} __attribute__ ((packed)); + +struct ieee80211_qos_ac_parameter { + u8 aci_aifsn; + u8 ecw_min_max; + __le16 tx_op_limit; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameter_info { + struct ieee80211_qos_information_element info_element; + u8 reserved; + struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameters { + __le16 cw_min[QOS_QUEUE_NUM]; + __le16 cw_max[QOS_QUEUE_NUM]; + u8 aifs[QOS_QUEUE_NUM]; + u8 flag[QOS_QUEUE_NUM]; + __le16 tx_op_limit[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_data { + struct ieee80211_qos_parameters parameters; + int active; + int supported; + u8 param_count; + u8 old_param_count; +}; + +struct ieee80211_tim_parameters { + u8 tim_count; + u8 tim_period; +} __attribute__ ((packed)); + +//#else +struct ieee80211_wmm_ac_param { + u8 ac_aci_acm_aifsn; + u8 ac_ecwmin_ecwmax; + u16 ac_txop_limit; +}; + +struct ieee80211_wmm_ts_info { + u8 ac_dir_tid; + u8 ac_up_psb; + u8 reserved; +} __attribute__ ((packed)); + +struct ieee80211_wmm_tspec_elem { + struct ieee80211_wmm_ts_info ts_info; + u16 norm_msdu_size; + u16 max_msdu_size; + u32 min_serv_inter; + u32 max_serv_inter; + u32 inact_inter; + u32 suspen_inter; + u32 serv_start_time; + u32 min_data_rate; + u32 mean_data_rate; + u32 peak_data_rate; + u32 max_burst_size; + u32 delay_bound; + u32 min_phy_rate; + u16 surp_band_allow; + u16 medium_time; +}__attribute__((packed)); +#endif +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +static const char *eap_types[] = { + [EAP_PACKET] = "EAP-Packet", + [EAPOL_START] = "EAPOL-Start", + [EAPOL_LOGOFF] = "EAPOL-Logoff", + [EAPOL_KEY] = "EAPOL-Key", + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" +}; + +static inline const char *eap_get_type(int type) +{ + return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; +} +//added by amy for reorder +static inline u8 Frame_QoSTID(u8* buf) +{ + struct ieee80211_hdr_3addr *hdr; + u16 fc; + hdr = (struct ieee80211_hdr_3addr *)buf; + fc = le16_to_cpu(hdr->frame_ctl); + return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid; +} + +//added by amy for reorder + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__ ((packed)); + +struct ieee80211_softmac_stats{ + unsigned int rx_ass_ok; + unsigned int rx_ass_err; + unsigned int rx_probe_rq; + unsigned int tx_probe_rs; + unsigned int tx_beacons; + unsigned int rx_auth_rq; + unsigned int rx_auth_rs_ok; + unsigned int rx_auth_rs_err; + unsigned int tx_auth_rq; + unsigned int no_auth_rs; + unsigned int no_ass_rs; + unsigned int tx_ass_rq; + unsigned int rx_ass_rq; + unsigned int tx_probe_rq; + unsigned int reassoc; + unsigned int swtxstop; + unsigned int swtxawake; + unsigned char CurrentShowTxate; + unsigned char last_packet_rate; + unsigned int txretrycount; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps + +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; +#define MAX_SP_Len (WMM_all_frame << 4) +#define IEEE80211_QOS_TID 0x0f +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST + +//added by David for QoS 2006/6/30 +//#define WMM_Hang_8187 +#ifdef WMM_Hang_8187 +#undef WMM_Hang_8187 +#endif + +#define WME_AC_BK 0x00 +#define WME_AC_BE 0x01 +#define WME_AC_VI 0x02 +#define WME_AC_VO 0x03 +#define WME_ACI_MASK 0x03 +#define WME_AIFSN_MASK 0x03 +#define WME_AC_PRAM_LEN 16 + +#define MAX_RECEIVE_BUFFER_SIZE 9100 + +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) +#if 1 +#define UP2AC(up) ( \ + ((up) < 1) ? WME_AC_BE : \ + ((up) < 3) ? WME_AC_BK : \ + ((up) < 4) ? WME_AC_BE : \ + ((up) < 6) ? WME_AC_VI : \ + WME_AC_VO) +#endif +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue +#define AC2UP(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ +#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address plus ether type*/ + +struct ether_header { + u8 ether_dhost[ETHER_ADDR_LEN]; + u8 ether_shost[ETHER_ADDR_LEN]; + u16 ether_type; +} __attribute__((packed)); + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif + +typedef struct _bss_ht{ + + bool support_ht; + + // HT related elements + u8 ht_cap_buf[32]; + u16 ht_cap_len; + u8 ht_info_buf[32]; + u16 ht_info_len; + + HT_SPEC_VER ht_spec_ver; + //HT_CAPABILITY_ELE bdHTCapEle; + //HT_INFORMATION_ELE bdHTInfoEle; + + bool aggregation; + bool long_slot_time; +}bss_ht, *pbss_ht; + +typedef enum _erp_t{ + ERP_NonERPpresent = 0x01, + ERP_UseProtection = 0x02, + ERP_BarkerPreambleMode = 0x04, +} erp_t; + + +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; +#if 1 + struct ieee80211_qos_data qos_data; +#else + // Qos related. Added by Annie, 2005-11-01. + BSS_QOS BssQos; +#endif + + //added by amy for LEAP + bool bWithAironetIE; + bool bCkipSupported; + bool bCcxRmEnable; + u16 CcxRmState[2]; + // CCXv4 S59, MBSSID. + bool bMBssidValid; + u8 MBssidMask; + u8 MBssid[6]; + // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. + bool bWithCcxVerNum; + u8 BssCcxVerNumber; + /* These are network statistics */ + struct ieee80211_rx_stats stats; + u16 capability; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + unsigned long last_scanned; + u8 mode; + u32 flags; + u32 last_associate; + u32 time_stamp[2]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 erp_value; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + + struct ieee80211_tim_parameters tim; + u8 dtim_period; + u8 dtim_data; + u32 last_dtim_sta_time[2]; + + //appeded for QoS + u8 wmm_info; + struct ieee80211_wmm_ac_param wmm_param[4]; + u8 QoS_Enable; +#ifdef THOMAS_TURBO + u8 Turbo_Enable;//enable turbo mode, added by thomas +#endif +#ifdef ENABLE_DOT11D + u16 CountryIeLen; + u8 CountryIeBuf[MAX_IE_LEN]; +#endif + // HT Related, by amy, 2008.04.29 + BSS_HT bssht; + // Add to handle broadcom AP management frame CCK rate. + bool broadcom_cap_exist; + bool ralink_cap_exist; + bool atheros_cap_exist; + bool cisco_cap_exist; + bool unknown_cap_exist; +// u8 berp_info; + bool berp_info_valid; + bool buseprotection; + //put at the end of the structure. + struct list_head list; +}; + +#if 1 +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, + +}; +#else +enum ieee80211_state { + IEEE80211_UNINITIALIZED = 0, + IEEE80211_INITIALIZED, + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATED, + IEEE80211_AUTHENTICATING, + IEEE80211_AUTHENTICATED, + IEEE80211_SHUTDOWN +}; +#endif + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) +#define CFG_IEEE80211_RTS (1<<2) + +#define IEEE80211_24GHZ_MIN_CHANNEL 1 +#define IEEE80211_24GHZ_MAX_CHANNEL 14 +#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ + IEEE80211_24GHZ_MIN_CHANNEL + 1) + +#define IEEE80211_52GHZ_MIN_CHANNEL 34 +#define IEEE80211_52GHZ_MAX_CHANNEL 165 +#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ + IEEE80211_52GHZ_MIN_CHANNEL + 1) + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)) +extern inline int is_multicast_ether_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} +#endif + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)) +extern inline int is_broadcast_ether_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} +#endif + +typedef struct tx_pending_t{ + int frag; + struct ieee80211_txb *txb; +}tx_pending_t; + +typedef struct _bandwidth_autoswitch +{ + long threshold_20Mhzto40Mhz; + long threshold_40Mhzto20Mhz; + bool bforced_tx20Mhz; + bool bautoswitch_enable; +}bandwidth_autoswitch,*pbandwidth_autoswitch; + + +//added by amy for order + +#define REORDER_WIN_SIZE 128 +#define REORDER_ENTRY_NUM 128 +typedef struct _RX_REORDER_ENTRY +{ + struct list_head List; + u16 SeqNum; + struct ieee80211_rxb* prxb; +} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY; +//added by amy for order +typedef enum _Fsync_State{ + Default_Fsync, + HW_Fsync, + SW_Fsync +}Fsync_State; + +// Power save mode configured. +typedef enum _RT_PS_MODE +{ + eActive, // Active/Continuous access. + eMaxPs, // Max power save mode. + eFastPs // Fast power save mode. +}RT_PS_MODE; + +typedef enum _IPS_CALLBACK_FUNCION +{ + IPS_CALLBACK_NONE = 0, + IPS_CALLBACK_MGNT_LINK_REQUEST = 1, + IPS_CALLBACK_JOIN_REQUEST = 2, +}IPS_CALLBACK_FUNCION; + +typedef enum _RT_JOIN_ACTION{ + RT_JOIN_INFRA = 1, + RT_JOIN_IBSS = 2, + RT_START_IBSS = 3, + RT_NO_ACTION = 4, +}RT_JOIN_ACTION; + +typedef struct _IbssParms{ + u16 atimWin; +}IbssParms, *PIbssParms; +#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. + +// RF state. +typedef enum _RT_RF_POWER_STATE +{ + eRfOn, + eRfSleep, + eRfOff +}RT_RF_POWER_STATE; + +typedef struct _RT_POWER_SAVE_CONTROL +{ + + // + // Inactive Power Save(IPS) : Disable RF when disconnected + // + bool bInactivePs; + bool bIPSModeBackup; + bool bSwRfProcessing; + RT_RF_POWER_STATE eInactivePowerState; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct InactivePsWorkItem; +#else + struct tq_struct InactivePsWorkItem; +#endif + struct timer_list InactivePsTimer; + + // Return point for join action + IPS_CALLBACK_FUNCION ReturnPoint; + + // Recored Parameters for rescheduled JoinRequest + bool bTmpBssDesc; + RT_JOIN_ACTION tmpJoinAction; + struct ieee80211_network tmpBssDesc; + + // Recored Parameters for rescheduled MgntLinkRequest + bool bTmpScanOnly; + bool bTmpActiveScan; + bool bTmpFilterHiddenAP; + bool bTmpUpdateParms; + u8 tmpSsidBuf[33]; + OCTET_STRING tmpSsid2Scan; + bool bTmpSsid2Scan; + u8 tmpNetworkType; + u8 tmpChannelNumber; + u16 tmpBcnPeriod; + u8 tmpDtimPeriod; + u16 tmpmCap; + OCTET_STRING tmpSuppRateSet; + u8 tmpSuppRateBuf[MAX_NUM_RATES]; + bool bTmpSuppRate; + IbssParms tmpIbpm; + bool bTmpIbpm; + + // + // Leisre Poswer Save : Disable RF if connected but traffic is not busy + // + bool bLeisurePs; + +}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; + +typedef u32 RT_RF_CHANGE_SOURCE; +#define RF_CHANGE_BY_SW BIT31 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. + +#ifdef ENABLE_DOT11D +typedef enum +{ + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC, + COUNTRY_CODE_MIC, + COUNTRY_CODE_GLOBAL_DOMAIN +}country_code_type_t; +#endif + +#define RT_MAX_LD_SLOT_NUM 10 +typedef struct _RT_LINK_DETECT_T{ + + u32 NumRecvBcnInPeriod; + u32 NumRecvDataInPeriod; + + u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status + u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status + u16 SlotNum; // number of CheckForHang period to determine link status + u16 SlotIndex; + + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + bool bBusyTraffic; +}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; + + +struct ieee80211_device { + struct net_device *dev; + struct ieee80211_security sec; + + //hw security related +// u8 hwsec_support; //support? + u8 hwsec_active; //hw security active. + bool is_silent_reset; + bool is_roaming; + bool ieee_up; + //added by amy + bool bSupportRemoteWakeUp; + RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. + bool actscanning; + bool beinretry; + RT_RF_POWER_STATE eRFPowerState; + RT_RF_CHANGE_SOURCE RfOffReason; + bool is_set_key; + //11n spec related I wonder if These info structure need to be moved out of ieee80211_device + + //11n HT below + PRT_HIGH_THROUGHPUT pHTInfo; + //struct timer_list SwBwTimer; +// spinlock_t chnlop_spinlock; + spinlock_t bw_spinlock; + + spinlock_t reorder_spinlock; + // for HT operation rate set. we use this one for HT data rate to seperate different descriptors + //the way fill this is the same as in the IE + u8 Regdot11HTOperationalRateSet[16]; //use RATR format + u8 dot11HTOperationalRateSet[16]; //use RATR format + u8 RegHTSuppRateSet[16]; + u8 HTCurrentOperaRate; + u8 HTHighestOperaRate; + //wb added for rate operation mode to firmware + u8 bTxDisableRateFallBack; + u8 bTxUseDriverAssingedRate; + atomic_t atm_chnlop; + atomic_t atm_swbw; +// u8 HTHighestOperaRate; +// u8 HTCurrentOperaRate; + + // 802.11e and WMM Traffic Stream Info (TX) + struct list_head Tx_TS_Admit_List; + struct list_head Tx_TS_Pending_List; + struct list_head Tx_TS_Unused_List; + TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM]; + // 802.11e and WMM Traffic Stream Info (RX) + struct list_head Rx_TS_Admit_List; + struct list_head Rx_TS_Pending_List; + struct list_head Rx_TS_Unused_List; + RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; +//#ifdef TO_DO_LIST + RX_REORDER_ENTRY RxReorderEntry[128]; + struct list_head RxReorder_Unused_List; +//#endif + // Qos related. Added by Annie, 2005-11-01. +// PSTA_QOS pStaQos; + u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) + + + /* Bookkeeping structures */ + struct net_device_stats stats; + struct ieee80211_stats ieee_stats; + struct ieee80211_softmac_stats softmac_stats; + + /* Probe / Beacon management */ + struct list_head network_free_list; + struct list_head network_list; + struct ieee80211_network *networks; + int scans; + int scan_age; + + int iw_mode; /* operating mode (IW_MODE_*) */ + struct iw_spy_data spy_data; + + spinlock_t lock; + spinlock_t wpax_suitlist_lock; + + int tx_headroom; /* Set to size of any additional room needed at front + * of allocated Tx SKBs */ + u32 config; + + /* WEP and other encryption related settings at the device level */ + int open_wep; /* Set to 1 to allow unencrypted frames */ + int auth_mode; + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on + * WEP key changes */ + + /* If the host performs {en,de}cryption, then set to 1 */ + int host_encrypt; + int host_encrypt_msdu; + int host_decrypt; + /* host performs multicast decryption */ + int host_mc_decrypt; + + /* host should strip IV and ICV from protected frames */ + /* meaningful only when hardware decryption is being used */ + int host_strip_iv_icv; + + int host_open_frag; + int host_build_iv; + int ieee802_1x; /* is IEEE 802.1X used */ + + /* WPA data */ + bool bHalfWirelessN24GMode; + int wpa_enabled; + int drop_unencrypted; + int tkip_countermeasures; + int privacy_invoked; + size_t wpa_ie_len; + u8 *wpa_ie; + u8 ap_mac_addr[6]; + u16 pairwise_key_type; + u16 group_key_type; + struct list_head crypt_deinit_list; + struct ieee80211_crypt_data *crypt[WEP_KEYS]; + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ + struct timer_list crypt_deinit_timer; + int crypt_quiesced; + + int bcrx_sta_key; /* use individual keys to override default keys even + * with RX of broad/multicast frames */ + + /* Fragmentation structures */ + // each streaming contain a entry + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; + unsigned int frag_next_idx[17]; + u16 fts; /* Fragmentation Threshold */ +#define DEFAULT_RTS_THRESHOLD 2346U +#define MIN_RTS_THRESHOLD 1 +#define MAX_RTS_THRESHOLD 2346U + u16 rts; /* RTS threshold */ + + /* Association info */ + u8 bssid[ETH_ALEN]; + + /* This stores infos for the current network. + * Either the network we are associated in INFRASTRUCTURE + * or the network that we are creating in MASTER mode. + * ad-hoc is a mixture ;-). + * Note that in infrastructure mode, even when not associated, + * fields bssid and essid may be valid (if wpa_set and essid_set + * are true) as thy carry the value set by the user via iwconfig + */ + struct ieee80211_network current_network; + + enum ieee80211_state state; + + int short_slot; + int reg_mode; + int mode; /* A, B, G */ + int modulation; /* CCK, OFDM */ + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ + int abg_true; /* ABG flag */ + + /* used for forcing the ibss workqueue to terminate + * without wait for the syncro scan to terminate + */ + short sync_scan_hurryup; + + int perfect_rssi; + int worst_rssi; + + u16 prev_seq_ctl; /* used to drop duplicate frames */ + + /* map of allowed channels. 0 is dummy */ + // FIXME: remeber to default to a basic channel plan depending of the PHY type +#ifdef ENABLE_DOT11D + void* pDot11dInfo; + bool bGlobalDomain; +#else + int channel_map[MAX_CHANNEL_NUMBER+1]; +#endif + int rate; /* current rate */ + int basic_rate; + //FIXME: pleace callback, see if redundant with softmac_features + short active_scan; + + /* this contains flags for selectively enable softmac support */ + u16 softmac_features; + + /* if the sequence control field is not filled by HW */ + u16 seq_ctrl[5]; + + /* association procedure transaction sequence number */ + u16 associate_seq; + + /* AID for RTXed association responses */ + u16 assoc_id; + + /* power save mode related*/ + u8 ack_tx_to_ieee; + short ps; + short sta_sleep; + int ps_timeout; + int ps_period; + struct tasklet_struct ps_task; + u32 ps_th; + u32 ps_tl; + + short raw_tx; + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + short queue_stop; + short scanning; + short proto_started; + + struct semaphore wx_sem; + struct semaphore scan_sem; + + spinlock_t mgmt_tx_lock; + spinlock_t beacon_lock; + + short beacon_txing; + + short wap_set; + short ssid_set; + + u8 wpax_type_set; //{added by David, 2006.9.28} + u32 wpax_type_notify; //{added by David, 2006.9.26} + + /* QoS related flag */ + char init_wmmparam_flag; + /* set on initialization */ + u8 qos_support; + + /* for discarding duplicated packets in IBSS */ + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; + + /* for discarding duplicated packets in BSS */ + u16 last_rxseq_num[17]; /* rx seq previous per-tid */ + u16 last_rxfrag_num[17];/* tx frag previous per-tid */ + unsigned long last_packet_time[17]; + + /* for PS mode */ + unsigned long last_rx_ps_time; + + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; + int mgmt_queue_head; + int mgmt_queue_tail; +//{ added for rtl819x +#define IEEE80211_QUEUE_LIMIT 128 + u8 AsocRetryCount; + unsigned int hw_header; + struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; + u32 sta_edca_param[4]; + bool aggregation; + // Enable/Disable Rx immediate BA capability. + bool enable_rx_imm_BA; + bool bibsscoordinator; + + //+by amy for DM ,080515 + //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 + bool bdynamic_txpower_enable; + + bool bCTSToSelfEnable; + u8 CTSToSelfTH; + + u32 fsync_time_interval; + u32 fsync_rate_bitmap; + u8 fsync_rssi_threshold; + bool bfsync_enable; + + u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval + u32 fsync_firstdiff_ratethreshold; // low threshold + u32 fsync_seconddiff_ratethreshold; // decrease threshold + Fsync_State fsync_state; + bool bis_any_nonbepkts; + //20Mhz 40Mhz AutoSwitch Threshold + bandwidth_autoswitch bandwidth_auto_switch; + //for txpower tracking + bool FwRWRF; + + //added by amy for AP roaming + RT_LINK_DETECT_T LinkDetectInfo; + //added by amy for ps + RT_POWER_SAVE_CONTROL PowerSaveControl; +//} + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + struct tx_pending_t tx_pending; + + /* used if IEEE_SOFTMAC_ASSOCIATE is set */ + struct timer_list associate_timer; + + /* used if IEEE_SOFTMAC_BEACONS is set */ + struct timer_list beacon_timer; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct associate_complete_wq; + struct work_struct associate_procedure_wq; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct delayed_work softmac_scan_wq; + struct delayed_work associate_retry_wq; + struct delayed_work start_ibss_wq; + struct delayed_work hw_wakeup_wq; + struct delayed_work hw_sleep_wq; +#else + struct work_struct softmac_scan_wq; + struct work_struct associate_retry_wq; + struct work_struct start_ibss_wq; + struct work_struct hw_wakeup_wq; + struct work_struct hw_sleep_wq; +#endif + struct work_struct wx_sync_scan_wq; + struct workqueue_struct *wq; +#else + /* used for periodly scan */ + struct timer_list scan_timer; + + struct tq_struct associate_complete_wq; + struct tq_struct associate_retry_wq; + struct tq_struct start_ibss_wq; + struct tq_struct associate_procedure_wq; + struct tq_struct softmac_scan_wq; + struct tq_struct wx_sync_scan_wq; + +#endif + // Qos related. Added by Annie, 2005-11-01. + //STA_QOS StaQos; + + //u32 STA_EDCA_PARAM[4]; + //CHANNEL_ACCESS_SETTING ChannelAccessSetting; + + + /* Callback functions */ + void (*set_security)(struct net_device *dev, + struct ieee80211_security *sec); + + /* Used to TX data frame by using txb structs. + * this is not used if in the softmac_features + * is set the flag IEEE_SOFTMAC_TX_QUEUE + */ + int (*hard_start_xmit)(struct ieee80211_txb *txb, + struct net_device *dev); + + int (*reset_port)(struct net_device *dev); + int (*is_queue_full) (struct net_device * dev, int pri); + + int (*handle_management) (struct net_device * dev, + struct ieee80211_network * network, u16 type); + int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); + + /* Softmac-generated frames (mamagement) are TXed via this + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is + * not set. As some cards may have different HW queues that + * one might want to use for data and management frames + * the option to have two callbacks might be useful. + * This fucntion can't sleep. + */ + int (*softmac_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* used instead of hard_start_xmit (not softmac_hard_start_xmit) + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * then also management frames are sent via this callback. + * This function can't sleep. + */ + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev,int rate); + + /* stops the HW queue for DATA frames. Useful to avoid + * waste time to TX data frame when we are reassociating + * This function can sleep. + */ + void (*data_hard_stop)(struct net_device *dev); + + /* OK this is complementar to data_poll_hard_stop */ + void (*data_hard_resume)(struct net_device *dev); + + /* ask to the driver to retune the radio . + * This function can sleep. the driver should ensure + * the radio has been swithced before return. + */ + void (*set_chan)(struct net_device *dev,short ch); + + /* These are not used if the ieee stack takes care of + * scanning (IEEE_SOFTMAC_SCAN feature set). + * In this case only the set_chan is used. + * + * The syncro version is similar to the start_scan but + * does not return until all channels has been scanned. + * this is called in user context and should sleep, + * it is called in a work_queue when swithcing to ad-hoc mode + * or in behalf of iwlist scan when the card is associated + * and root user ask for a scan. + * the fucntion stop_scan should stop both the syncro and + * background scanning and can sleep. + * The fucntion start_scan should initiate the background + * scanning and can't sleep. + */ + void (*scan_syncro)(struct net_device *dev); + void (*start_scan)(struct net_device *dev); + void (*stop_scan)(struct net_device *dev); + + /* indicate the driver that the link state is changed + * for example it may indicate the card is associated now. + * Driver might be interested in this to apply RX filter + * rules or simply light the LINK led + */ + void (*link_change)(struct net_device *dev); + + /* these two function indicates to the HW when to start + * and stop to send beacons. This is used when the + * IEEE_SOFTMAC_BEACONS is not set. For now the + * stop_send_bacons is NOT guaranteed to be called only + * after start_send_beacons. + */ + void (*start_send_beacons) (struct net_device *dev); + void (*stop_send_beacons) (struct net_device *dev); + + /* power save mode related */ + void (*sta_wake_up) (struct net_device *dev); +// void (*ps_request_tx_ack) (struct net_device *dev); + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); + short (*ps_is_queue_empty) (struct net_device *dev); +#if 0 + /* Typical STA methods */ + int (*handle_auth) (struct net_device * dev, + struct ieee80211_auth * auth); + int (*handle_deauth) (struct net_device * dev, + struct ieee80211_deauth * auth); + int (*handle_action) (struct net_device * dev, + struct ieee80211_action * action, + struct ieee80211_rx_stats * stats); + int (*handle_disassoc) (struct net_device * dev, + struct ieee80211_disassoc * assoc); +#endif + int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); +#if 0 + int (*handle_probe_response) (struct net_device * dev, + struct ieee80211_probe_response * resp, + struct ieee80211_network * network); + int (*handle_probe_request) (struct net_device * dev, + struct ieee80211_probe_request * req, + struct ieee80211_rx_stats * stats); +#endif + int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); + +#if 0 + /* Typical AP methods */ + int (*handle_assoc_request) (struct net_device * dev); + int (*handle_reassoc_request) (struct net_device * dev, + struct ieee80211_reassoc_request * req); +#endif + + /* check whether Tx hw resouce available */ + short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); + //added by wb for HT related +// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); + void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); + bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); + void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); + bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); + void (*InitialGainHandler)(struct net_device *dev, u8 Operation); + + /* This must be the last item so that it points to the data + * allocated beyond this structure by alloc_ieee80211 */ + u8 priv[0]; +}; + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_N_24G (1<<4) +#define IEEE_N_5G (1<<5) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +/* Generate a 802.11 header */ + +/* Uses the channel change callback directly + * instead of [start/stop] scan callbacks + */ +#define IEEE_SOFTMAC_SCAN (1<<2) + +/* Perform authentication and association handshake */ +#define IEEE_SOFTMAC_ASSOCIATE (1<<3) + +/* Generate probe requests */ +#define IEEE_SOFTMAC_PROBERQ (1<<4) + +/* Generate respones to probe requests */ +#define IEEE_SOFTMAC_PROBERS (1<<5) + +/* The ieee802.11 stack will manages the netif queue + * wake/stop for the driver, taking care of 802.11 + * fragmentation. See softmac.c for details. */ +#define IEEE_SOFTMAC_TX_QUEUE (1<<7) + +/* Uses only the softmac_data_hard_start_xmit + * even for TX management frames. + */ +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) + +/* Generate beacons. The stack will enqueue beacons + * to the card + */ +#define IEEE_SOFTMAC_BEACONS (1<<6) + +static inline void *ieee80211_priv(struct net_device *dev) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + return ((struct ieee80211_device *)netdev_priv(dev))->priv; +#else + return ((struct ieee80211_device *)dev->priv)->priv; +#endif +} + +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +{ + /* + * It is possible for both access points and our device to support + * combinations of modes, so as long as there is one valid combination + * of ap/device supported modes, then return success + * + */ + if ((mode & IEEE_A) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_52GHZ_BAND)) + return 1; + + if ((mode & IEEE_G) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + if ((mode & IEEE_B) && + (ieee->modulation & IEEE80211_CCK_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + return 0; +} + +extern inline int ieee80211_get_hdrlen(u16 fc) +{ + int hdrlen = IEEE80211_3ADDR_LEN; + + switch (WLAN_FC_GET_TYPE(fc)) { + case IEEE80211_FTYPE_DATA: + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) + hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ + if(IEEE80211_QOS_HAS_SEQ(fc)) + hdrlen += 2; /* QOS ctrl*/ + break; + case IEEE80211_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case IEEE80211_STYPE_CTS: + case IEEE80211_STYPE_ACK: + hdrlen = IEEE80211_1ADDR_LEN; + break; + default: + hdrlen = IEEE80211_2ADDR_LEN; + break; + } + break; + } + + return hdrlen; +} + +static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) +{ + switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { + case IEEE80211_1ADDR_LEN: + return ((struct ieee80211_hdr_1addr *)hdr)->payload; + case IEEE80211_2ADDR_LEN: + return ((struct ieee80211_hdr_2addr *)hdr)->payload; + case IEEE80211_3ADDR_LEN: + return ((struct ieee80211_hdr_3addr *)hdr)->payload; + case IEEE80211_4ADDR_LEN: + return ((struct ieee80211_hdr_4addr *)hdr)->payload; + } + return NULL; +} + +static inline int ieee80211_is_ofdm_rate(u8 rate) +{ + switch (rate & ~IEEE80211_BASIC_RATE_MASK) { + case IEEE80211_OFDM_RATE_6MB: + case IEEE80211_OFDM_RATE_9MB: + case IEEE80211_OFDM_RATE_12MB: + case IEEE80211_OFDM_RATE_18MB: + case IEEE80211_OFDM_RATE_24MB: + case IEEE80211_OFDM_RATE_36MB: + case IEEE80211_OFDM_RATE_48MB: + case IEEE80211_OFDM_RATE_54MB: + return 1; + } + return 0; +} + +static inline int ieee80211_is_cck_rate(u8 rate) +{ + switch (rate & ~IEEE80211_BASIC_RATE_MASK) { + case IEEE80211_CCK_RATE_1MB: + case IEEE80211_CCK_RATE_2MB: + case IEEE80211_CCK_RATE_5MB: + case IEEE80211_CCK_RATE_11MB: + return 1; + } + return 0; +} + + +/* ieee80211.c */ +extern void free_ieee80211(struct net_device *dev); +extern struct net_device *alloc_ieee80211(int sizeof_priv); + +extern int ieee80211_set_encryption(struct ieee80211_device *ieee); + +/* ieee80211_tx.c */ + +extern int ieee80211_encrypt_fragment( + struct ieee80211_device *ieee, + struct sk_buff *frag, + int hdr_len); + +extern int ieee80211_xmit(struct sk_buff *skb, + struct net_device *dev); +extern void ieee80211_txb_free(struct ieee80211_txb *); + + +/* ieee80211_rx.c */ +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats); +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *header, + struct ieee80211_rx_stats *stats); + +/* ieee80211_wx.c */ +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +#if WIRELESS_EXT >= 18 +extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data* wrqu, char *extra); +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data* wrqu, char *extra); +extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra); +extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +#endif +extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); + +/* ieee80211_softmac.c */ +extern short ieee80211_is_54g(struct ieee80211_network net); +extern short ieee80211_is_shortslot(struct ieee80211_network net); +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype); +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); + +void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn); +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); + +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +extern void notify_wx_assoc_event(struct ieee80211_device *ieee); +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_ibss(struct ieee80211_device *ieee); +extern void ieee80211_softmac_init(struct ieee80211_device *ieee); +extern void ieee80211_softmac_free(struct ieee80211_device *ieee); +extern void ieee80211_associate_abort(struct ieee80211_device *ieee); +extern void ieee80211_disassociate(struct ieee80211_device *ieee); +extern void ieee80211_stop_scan(struct ieee80211_device *ieee); +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_reset_queue(struct ieee80211_device *ieee); +extern void ieee80211_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); +extern void notify_wx_assoc_event(struct ieee80211_device *ieee); +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); + +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); + +/* ieee80211_crypt_ccmp&tkip&wep.c */ +extern void ieee80211_tkip_null(void); +extern void ieee80211_wep_null(void); +extern void ieee80211_ccmp_null(void); + +/* ieee80211_softmac_wx.c */ + +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *ext); + +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra); + +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); + +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); +#else + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#endif + + +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +//HT +#define MAX_RECEIVE_BUFFER_SIZE 9100 // +extern void HTDebugHTCapability(u8* CapIE, u8* TitleString ); +extern void HTDebugHTInfo(u8* InfoIE, u8* TitleString); + +void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee); +extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt); +extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt); +extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len); +extern void HTOnAssocRsp(struct ieee80211_device *ieee); +extern void HTInitializeHTInfo(struct ieee80211_device* ieee); +extern void HTInitializeBssDesc(PBSS_HT pBssHT); +extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); +extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); +extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter); +extern u8 MCS_FILTER_ALL[]; +extern u16 MCS_DATA_RATE[2][2][77] ; +extern u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame); +//extern void HTSetConnectBwModeCallback(unsigned long data); +extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); +extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee); +extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate); +extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate); +extern u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate); +//function in BAPROC.c +extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb); +extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb); +extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb); +extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); +extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); +extern void BaSetupTimeOut(unsigned long data); +extern void TxBaInactTimeout(unsigned long data); +extern void RxBaInactTimeout(unsigned long data); +extern void ResetBaEntry( PBA_RECORD pBA); +//function in TS.c +extern bool GetTs( + struct ieee80211_device* ieee, + PTS_COMMON_INFO *ppTS, + u8* Addr, + u8 TID, + TR_SELECT TxRxSelect, //Rx:1, Tx:0 + bool bAddNewTs + ); +extern void TSInitialize(struct ieee80211_device *ieee); +extern void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS); +extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr); +extern void RemoveAllTS(struct ieee80211_device* ieee); +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); + +extern const long ieee80211_wlan_frequencies[]; + +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +{ + ieee->scans++; +} + +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +{ + return ieee->scans; +} + +static inline const char *escape_essid(const char *essid, u8 essid_len) { + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (ieee80211_is_empty_essid(essid, essid_len)) { + memcpy(escaped, "", sizeof("")); + return escaped; + } + + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +/* For the function is more related to hardware setting, it's better to use the + * ieee handler to refer to it. + */ +extern short check_nic_enough_desc(struct net_device *dev, int queue_index); +extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); +extern int ieee80211_parse_info_param(struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + u16 length, + struct ieee80211_network *network, + struct ieee80211_rx_stats *stats); + +void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); +#define RT_ASOC_RETRY_LIMIT 5 +#endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8192e/ieee80211/EndianFree.h b/drivers/staging/rtl8192e/ieee80211/EndianFree.h new file mode 100644 index 00000000000..0c417a6234a --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/EndianFree.h @@ -0,0 +1,199 @@ +#ifndef __INC_ENDIANFREE_H +#define __INC_ENDIANFREE_H + +/* + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#ifndef bool +typedef enum{false = 0, true} bool; +#endif +#endif + +#define __MACHINE_LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define __MACHINE_BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net, ppc */ + +#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN + +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +// Convert data +#define EF1Byte(_val) ((u8)(_val)) +#define EF2Byte(_val) ((u16)(_val)) +#define EF4Byte(_val) ((u32)(_val)) + +#else +// Convert data +#define EF1Byte(_val) ((u8)(_val)) +#define EF2Byte(_val) (((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8)) +#define EF4Byte(_val) (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8)|\ + ((((u32)(_val))&0x00ff0000)>>8)|\ + ((((u32)(_val))&0xff000000)>>24)) +#endif + +// Read data from memory +#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr))) +#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr))) +#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr))) + +// Write data to memory +#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr)))=EF1Byte(_val) +#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr)))=EF2Byte(_val) +#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr)))=EF4Byte(_val) +// Convert Host system specific byte ording (litten or big endia) to Network byte ording (big endian). +// 2006.05.07, by rcnjko. +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +#define H2N1BYTE(_val) ((u8)(_val)) +#define H2N2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\ + ((((u16)(_val))&0xff00)>>8)) +#define H2N4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8) |\ + ((((u32)(_val))&0x00ff0000)>>8) |\ + ((((u32)(_val))&0xff000000)>>24)) +#else +#define H2N1BYTE(_val) ((u8)(_val)) +#define H2N2BYTE(_val) ((u16)(_val)) +#define H2N4BYTE(_val) ((u32)(_val)) +#endif + +// Convert from Network byte ording (big endian) to Host system specific byte ording (litten or big endia). +// 2006.05.07, by rcnjko. +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +#define N2H1BYTE(_val) ((u8)(_val)) +#define N2H2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\ + ((((u16)(_val))&0xff00)>>8)) +#define N2H4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8) |\ + ((((u32)(_val))&0x00ff0000)>>8) |\ + ((((u32)(_val))&0xff000000)>>24)) +#else +#define N2H1BYTE(_val) ((u8)(_val)) +#define N2H2BYTE(_val) ((u16)(_val)) +#define N2H4BYTE(_val) ((u32)(_val)) +#endif + +// +// Example: +// BIT_LEN_MASK_32(0) => 0x00000000 +// BIT_LEN_MASK_32(1) => 0x00000001 +// BIT_LEN_MASK_32(2) => 0x00000003 +// BIT_LEN_MASK_32(32) => 0xFFFFFFFF +// +#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen))) +// +// Example: +// BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +// BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 +// +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) + +// +// Description: +// Return 4-byte value in host byte ordering from +// 4-byte pointer in litten-endian system. +// +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart)))) + +// +// Description: +// Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to +// 4-byte value in host byte ordering. +// +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_32(__BitLen) \ + ) + +// +// Description: +// Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering +// and return the result in 4-byte value in host byte ordering. +// +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \ + ) + +// +// Description: +// Set subfield of little-endian 4-byte value to specified value. +// +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u32 *)(__pStart)) = \ + EF4Byte( \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \ + ); + + +#define BIT_LEN_MASK_16(__BitLen) \ + (0xFFFF >> (16 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_16(__BitLen) << (__BitOffset)) + +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + (EF2Byte(*((u16 *)(__pStart)))) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_16(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u16 *)(__pStart)) = \ + EF2Byte( \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \ + ); + +#define BIT_LEN_MASK_8(__BitLen) \ + (0xFF >> (8 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_8(__BitLen) << (__BitOffset)) + +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + (EF1Byte(*((u8 *)(__pStart)))) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_8(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u8 *)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \ + ); + +#endif // #ifndef __INC_ENDIANFREE_H diff --git a/drivers/staging/rtl8192e/ieee80211/aes.c b/drivers/staging/rtl8192e/ieee80211/aes.c new file mode 100644 index 00000000000..0c176e29a79 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/aes.c @@ -0,0 +1,469 @@ +/* + * Cryptographic API. + * + * AES Cipher Algorithm. + * + * Based on Brian Gladman's code. + * + * Linux developers: + * Alexander Kjeldaas + * Herbert Valerio Riedel + * Kyle McMartin + * Adam J. Richter (conversion to 2.5 API). + * + * 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. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman , Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +/* Some changes from the Gladman version: + s/RIJNDAEL(e_key)/E_KEY/g + s/RIJNDAEL(d_key)/D_KEY/g +*/ + +#include +#include +#include +#include +//#include +#include "rtl_crypto.h" +#include + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_BLOCK_SIZE 16 + +static inline +u32 generic_rotr32 (const u32 x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x >> n) | (x << (32 - n)); +} + +static inline +u32 generic_rotl32 (const u32 x, const unsigned bits) +{ + const unsigned n = bits % 32; + return (x << n) | (x >> (32 - n)); +} + +#define rotl generic_rotl32 +#define rotr generic_rotr32 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +inline static u8 +byte(const u32 x, const unsigned n) +{ + return x >> (n << 3); +} + +#define u32_in(x) le32_to_cpu(*(const u32 *)(x)) +#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from)) + +struct aes_ctx { + int key_length; + u32 E[60]; + u32 D[60]; +}; + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static u8 pow_tab[256] __initdata; +static u8 log_tab[256] __initdata; +static u8 sbx_tab[256] __initdata; +static u8 isb_tab[256] __initdata; +static u32 rco_tab[10]; +static u32 ft_tab[4][256]; +static u32 it_tab[4][256]; + +static u32 fl_tab[4][256]; +static u32 il_tab[4][256]; + +static inline u8 __init +f_mult (u8 a, u8 b) +{ + u8 aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0) + +#define f_rn(bo, bi, n, k) \ + bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ + ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rn(bo, bi, n, k) \ + bo[n] = it_tab[0][byte(bi[n],0)] ^ \ + it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +#define ls_box(x) \ + ( fl_tab[0][byte(x, 0)] ^ \ + fl_tab[1][byte(x, 1)] ^ \ + fl_tab[2][byte(x, 2)] ^ \ + fl_tab[3][byte(x, 3)] ) + +#define f_rl(bo, bi, n, k) \ + bo[n] = fl_tab[0][byte(bi[n],0)] ^ \ + fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ + fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) + +#define i_rl(bo, bi, n, k) \ + bo[n] = il_tab[0][byte(bi[n],0)] ^ \ + il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ + il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ + il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) + +static void __init +gen_tabs (void) +{ + u32 i, t; + u8 p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (u8) p; + log_tab[p] = (u8) i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (u8) i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + fl_tab[0][i] = t; + fl_tab[1][i] = rotl (t, 8); + fl_tab[2][i] = rotl (t, 16); + fl_tab[3][i] = rotl (t, 24); + + t = ((u32) ff_mult (2, p)) | + ((u32) p << 8) | + ((u32) p << 16) | ((u32) ff_mult (3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl (t, 8); + ft_tab[2][i] = rotl (t, 16); + ft_tab[3][i] = rotl (t, 24); + + p = isb_tab[i]; + + t = p; + il_tab[0][i] = t; + il_tab[1][i] = rotl (t, 8); + il_tab[2][i] = rotl (t, 16); + il_tab[3][i] = rotl (t, 24); + + t = ((u32) ff_mult (14, p)) | + ((u32) ff_mult (9, p) << 8) | + ((u32) ff_mult (13, p) << 16) | + ((u32) ff_mult (11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl (t, 8); + it_tab[2][i] = rotl (t, 16); + it_tab[3][i] = rotl (t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y,x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= rotr(u ^ t, 8) ^ \ + rotr(v ^ t, 16) ^ \ + rotr(t,24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ t = rotr(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ t = rotr(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int +aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +{ + struct aes_ctx *ctx = ctx_arg; + u32 i, t, u, v, w; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + E_KEY[0] = u32_in (in_key); + E_KEY[1] = u32_in (in_key + 4); + E_KEY[2] = u32_in (in_key + 8); + E_KEY[3] = u32_in (in_key + 12); + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4 (i); + break; + + case 24: + E_KEY[4] = u32_in (in_key + 16); + t = E_KEY[5] = u32_in (in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = u32_in (in_key + 16); + E_KEY[5] = u32_in (in_key + 20); + E_KEY[6] = u32_in (in_key + 24); + t = E_KEY[7] = u32_in (in_key + 28); + for (i = 0; i < 7; ++i) + loop8 (i); + break; + } + + D_KEY[0] = E_KEY[0]; + D_KEY[1] = E_KEY[1]; + D_KEY[2] = E_KEY[2]; + D_KEY[3] = E_KEY[3]; + + for (i = 4; i < key_len + 24; ++i) { + imix_col (D_KEY[i], E_KEY[i]); + } + + return 0; +} + +/* encrypt a block of text */ + +#define f_nround(bo, bi, k) \ + f_rn(bo, bi, 0, k); \ + f_rn(bo, bi, 1, k); \ + f_rn(bo, bi, 2, k); \ + f_rn(bo, bi, 3, k); \ + k += 4 + +#define f_lround(bo, bi, k) \ + f_rl(bo, bi, 0, k); \ + f_rl(bo, bi, 1, k); \ + f_rl(bo, bi, 2, k); \ + f_rl(bo, bi, 3, k) + +static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in) +{ + const struct aes_ctx *ctx = ctx_arg; + u32 b0[4], b1[4]; + const u32 *kp = E_KEY + 4; + + b0[0] = u32_in (in) ^ E_KEY[0]; + b0[1] = u32_in (in + 4) ^ E_KEY[1]; + b0[2] = u32_in (in + 8) ^ E_KEY[2]; + b0[3] = u32_in (in + 12) ^ E_KEY[3]; + + if (ctx->key_length > 24) { + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + } + + if (ctx->key_length > 16) { + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + } + + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_nround (b0, b1, kp); + f_nround (b1, b0, kp); + f_lround (b0, b1, kp); + + u32_out (out, b0[0]); + u32_out (out + 4, b0[1]); + u32_out (out + 8, b0[2]); + u32_out (out + 12, b0[3]); +} + +/* decrypt a block of text */ + +#define i_nround(bo, bi, k) \ + i_rn(bo, bi, 0, k); \ + i_rn(bo, bi, 1, k); \ + i_rn(bo, bi, 2, k); \ + i_rn(bo, bi, 3, k); \ + k -= 4 + +#define i_lround(bo, bi, k) \ + i_rl(bo, bi, 0, k); \ + i_rl(bo, bi, 1, k); \ + i_rl(bo, bi, 2, k); \ + i_rl(bo, bi, 3, k) + +static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in) +{ + const struct aes_ctx *ctx = ctx_arg; + u32 b0[4], b1[4]; + const int key_len = ctx->key_length; + const u32 *kp = D_KEY + key_len + 20; + + b0[0] = u32_in (in) ^ E_KEY[key_len + 24]; + b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25]; + b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26]; + b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27]; + + if (key_len > 24) { + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + } + + if (key_len > 16) { + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + } + + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_nround (b0, b1, kp); + i_nround (b1, b0, kp); + i_lround (b0, b1, kp); + + u32_out (out, b0[0]); + u32_out (out + 4, b0[1]); + u32_out (out + 8, b0[2]); + u32_out (out + 12, b0[3]); +} + + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +static int __init aes_init(void) +{ + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +static void __exit aes_fini(void) +{ + crypto_unregister_alg(&aes_alg); +} + +module_init(aes_init); +module_exit(aes_fini); + +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); +MODULE_LICENSE("Dual BSD/GPL"); + diff --git a/drivers/staging/rtl8192e/ieee80211/api.c b/drivers/staging/rtl8192e/ieee80211/api.c new file mode 100644 index 00000000000..c627d029528 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/api.c @@ -0,0 +1,246 @@ +/* + * Scatterlist Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * + * Portions derived from Cryptoapi, by Alexander Kjeldaas + * and Nettle, by Niels Mé°ˆler. + * + * 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. + * + */ +#include "kmap_types.h" + +#include +#include +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include "internal.h" + +LIST_HEAD(crypto_alg_list); +DECLARE_RWSEM(crypto_alg_sem); + +static inline int crypto_alg_get(struct crypto_alg *alg) +{ + return try_inc_mod_count(alg->cra_module); +} + +static inline void crypto_alg_put(struct crypto_alg *alg) +{ + if (alg->cra_module) + __MOD_DEC_USE_COUNT(alg->cra_module); +} + +struct crypto_alg *crypto_alg_lookup(const char *name) +{ + struct crypto_alg *q, *alg = NULL; + + if (!name) + return NULL; + + down_read(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (!(strcmp(q->cra_name, name))) { + if (crypto_alg_get(q)) + alg = q; + break; + } + } + + up_read(&crypto_alg_sem); + return alg; +} + +static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) +{ + tfm->crt_flags = 0; + + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_flags(tfm, flags); + + default: + break; + } + + BUG(); + return -EINVAL; +} + +static int crypto_init_ops(struct crypto_tfm *tfm) +{ + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_ops(tfm); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_ops(tfm); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_ops(tfm); + + default: + break; + } + + BUG(); + return -EINVAL; +} + +static void crypto_exit_ops(struct crypto_tfm *tfm) +{ + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + crypto_exit_cipher_ops(tfm); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + crypto_exit_digest_ops(tfm); + break; + + case CRYPTO_ALG_TYPE_COMPRESS: + crypto_exit_compress_ops(tfm); + break; + + default: + BUG(); + + } +} + +struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) +{ + struct crypto_tfm *tfm = NULL; + struct crypto_alg *alg; + + alg = crypto_alg_mod_lookup(name); + if (alg == NULL) + goto out; + + tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + if (tfm == NULL) + goto out_put; + + memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); + + tfm->__crt_alg = alg; + + if (crypto_init_flags(tfm, flags)) + goto out_free_tfm; + + if (crypto_init_ops(tfm)) { + crypto_exit_ops(tfm); + goto out_free_tfm; + } + + goto out; + +out_free_tfm: + kfree(tfm); + tfm = NULL; +out_put: + crypto_alg_put(alg); +out: + return tfm; +} + +void crypto_free_tfm(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + int size = sizeof(*tfm) + alg->cra_ctxsize; + + crypto_exit_ops(tfm); + crypto_alg_put(alg); + memset(tfm, 0, size); + kfree(tfm); +} + +int crypto_register_alg(struct crypto_alg *alg) +{ + int ret = 0; + struct crypto_alg *q; + + down_write(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (!(strcmp(q->cra_name, alg->cra_name))) { + ret = -EEXIST; + goto out; + } + } + + list_add_tail(&alg->cra_list, &crypto_alg_list); +out: + up_write(&crypto_alg_sem); + return ret; +} + +int crypto_unregister_alg(struct crypto_alg *alg) +{ + int ret = -ENOENT; + struct crypto_alg *q; + + BUG_ON(!alg->cra_module); + + down_write(&crypto_alg_sem); + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (alg == q) { + list_del(&alg->cra_list); + ret = 0; + goto out; + } + } +out: + up_write(&crypto_alg_sem); + return ret; +} + +int crypto_alg_available(const char *name, u32 flags) +{ + int ret = 0; + struct crypto_alg *alg = crypto_alg_mod_lookup(name); + + if (alg) { + crypto_alg_put(alg); + ret = 1; + } + + return ret; +} + +static int __init init_crypto(void) +{ + printk(KERN_INFO "Initializing Cryptographic API\n"); + crypto_init_proc(); + return 0; +} + +__initcall(init_crypto); + +/* +EXPORT_SYMBOL_GPL(crypto_register_alg); +EXPORT_SYMBOL_GPL(crypto_unregister_alg); +EXPORT_SYMBOL_GPL(crypto_alloc_tfm); +EXPORT_SYMBOL_GPL(crypto_free_tfm); +EXPORT_SYMBOL_GPL(crypto_alg_available); +*/ + +EXPORT_SYMBOL_NOVERS(crypto_register_alg); +EXPORT_SYMBOL_NOVERS(crypto_unregister_alg); +EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm); +EXPORT_SYMBOL_NOVERS(crypto_free_tfm); +EXPORT_SYMBOL_NOVERS(crypto_alg_available); diff --git a/drivers/staging/rtl8192e/ieee80211/arc4.c b/drivers/staging/rtl8192e/ieee80211/arc4.c new file mode 100644 index 00000000000..e408472af30 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/arc4.c @@ -0,0 +1,103 @@ +/* + * Cryptographic API + * + * ARC4 Cipher Algorithm + * + * Jon Oberheide + * + * 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. + * + */ +#include +#include +#include "rtl_crypto.h" + +#define ARC4_MIN_KEY_SIZE 1 +#define ARC4_MAX_KEY_SIZE 256 +#define ARC4_BLOCK_SIZE 1 + +struct arc4_ctx { + u8 S[256]; + u8 x, y; +}; + +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +{ + struct arc4_ctx *ctx = ctx_arg; + int i, j = 0, k = 0; + + ctx->x = 1; + ctx->y = 0; + + for(i = 0; i < 256; i++) + ctx->S[i] = i; + + for(i = 0; i < 256; i++) + { + u8 a = ctx->S[i]; + j = (j + in_key[k] + a) & 0xff; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = a; + if((unsigned int)++k >= key_len) + k = 0; + } + + return 0; +} + +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in) +{ + struct arc4_ctx *ctx = ctx_arg; + + u8 *const S = ctx->S; + u8 x = ctx->x; + u8 y = ctx->y; + u8 a, b; + + a = S[x]; + y = (y + a) & 0xff; + b = S[y]; + S[x] = b; + S[y] = a; + x = (x + 1) & 0xff; + *out++ = *in ^ S[(a + b) & 0xff]; + + ctx->x = x; + ctx->y = y; +} + +static struct crypto_alg arc4_alg = { + .cra_name = "arc4", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = ARC4_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct arc4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = ARC4_MIN_KEY_SIZE, + .cia_max_keysize = ARC4_MAX_KEY_SIZE, + .cia_setkey = arc4_set_key, + .cia_encrypt = arc4_crypt, + .cia_decrypt = arc4_crypt } } +}; + +static int __init arc4_init(void) +{ + return crypto_register_alg(&arc4_alg); +} + + +static void __exit arc4_exit(void) +{ + crypto_unregister_alg(&arc4_alg); +} + +module_init(arc4_init); +module_exit(arc4_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ARC4 Cipher Algorithm"); +MODULE_AUTHOR("Jon Oberheide "); diff --git a/drivers/staging/rtl8192e/ieee80211/autoload.c b/drivers/staging/rtl8192e/ieee80211/autoload.c new file mode 100644 index 00000000000..c97756f3b2e --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/autoload.c @@ -0,0 +1,40 @@ +/* + * Cryptographic API. + * + * Algorithm autoloader. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#include "kmap_types.h" + +#include +//#include +#include "rtl_crypto.h" +#include +#include +#include "internal.h" + +/* + * A far more intelligent version of this is planned. For now, just + * try an exact match on the name of the algorithm. + */ +void crypto_alg_autoload(const char *name) +{ + request_module(name); +} + +struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + struct crypto_alg *alg = crypto_alg_lookup(name); + if (alg == NULL) { + crypto_alg_autoload(name); + alg = crypto_alg_lookup(name); + } + return alg; +} diff --git a/drivers/staging/rtl8192e/ieee80211/cipher.c b/drivers/staging/rtl8192e/ieee80211/cipher.c new file mode 100644 index 00000000000..1968acfe32b --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/cipher.c @@ -0,0 +1,299 @@ +/* + * Cryptographic API. + * + * Cipher operations. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#include +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include +#include "internal.h" +#include "scatterwalk.h" + +typedef void (cryptfn_t)(void *, u8 *, const u8 *); +typedef void (procfn_t)(struct crypto_tfm *, u8 *, + u8*, cryptfn_t, int enc, void *, int); + +static inline void xor_64(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; +} + +static inline void xor_128(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; + ((u32 *)a)[2] ^= ((u32 *)b)[2]; + ((u32 *)a)[3] ^= ((u32 *)b)[3]; +} + + +/* + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per block. + */ +static int crypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, cryptfn_t crfn, + procfn_t prfn, int enc, void *info) +{ + struct scatter_walk walk_in, walk_out; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + u8 tmp_src[bsize]; + u8 tmp_dst[bsize]; + + if (!nbytes) + return 0; + + if (nbytes % bsize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; + return -EINVAL; + } + + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + u8 *src_p, *dst_p; + int in_place; + + scatterwalk_map(&walk_in, 0); + scatterwalk_map(&walk_out, 1); + src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src); + dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst); + in_place = scatterwalk_samebuf(&walk_in, &walk_out, + src_p, dst_p); + + nbytes -= bsize; + + scatterwalk_copychunks(src_p, &walk_in, bsize, 0); + + prfn(tfm, dst_p, src_p, crfn, enc, info, in_place); + + scatterwalk_done(&walk_in, 0, nbytes); + + scatterwalk_copychunks(dst_p, &walk_out, bsize, 1); + scatterwalk_done(&walk_out, 1, nbytes); + + if (!nbytes) + return 0; + + crypto_yield(tfm); + } +} + +static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, + cryptfn_t fn, int enc, void *info, int in_place) +{ + u8 *iv = info; + + /* Null encryption */ + if (!iv) + return; + + if (enc) { + tfm->crt_u.cipher.cit_xor_block(iv, src); + fn(crypto_tfm_ctx(tfm), dst, iv); + memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm)); + } else { + u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0]; + u8 *buf = in_place ? stack : dst; + + fn(crypto_tfm_ctx(tfm), buf, src); + tfm->crt_u.cipher.cit_xor_block(buf, iv); + memcpy(iv, src, crypto_tfm_alg_blocksize(tfm)); + if (buf != dst) + memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm)); + } +} + +static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, + cryptfn_t fn, int enc, void *info, int in_place) +{ + fn(crypto_tfm_ctx(tfm), dst, src); +} + +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; + + if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } else + return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen, + &tfm->crt_flags); +} + +static int ecb_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + ecb_process, 1, NULL); +} + +static int ecb_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + ecb_process, 1, NULL); +} + +static int cbc_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + cbc_process, 1, tfm->crt_cipher.cit_iv); +} + +static int cbc_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_encrypt, + cbc_process, 1, iv); +} + +static int cbc_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + cbc_process, 0, tfm->crt_cipher.cit_iv); +} + +static int cbc_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return crypt(tfm, dst, src, nbytes, + tfm->__crt_alg->cra_cipher.cia_decrypt, + cbc_process, 0, iv); +} + +static int nocrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return -ENOSYS; +} + +static int nocrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return -ENOSYS; +} + +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) +{ + u32 mode = flags & CRYPTO_TFM_MODE_MASK; + + tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; + if (flags & CRYPTO_TFM_REQ_WEAK_KEY) + tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY; + + return 0; +} + +int crypto_init_cipher_ops(struct crypto_tfm *tfm) +{ + int ret = 0; + struct cipher_tfm *ops = &tfm->crt_cipher; + + ops->cit_setkey = setkey; + + switch (tfm->crt_cipher.cit_mode) { + case CRYPTO_TFM_MODE_ECB: + ops->cit_encrypt = ecb_encrypt; + ops->cit_decrypt = ecb_decrypt; + break; + + case CRYPTO_TFM_MODE_CBC: + ops->cit_encrypt = cbc_encrypt; + ops->cit_decrypt = cbc_decrypt; + ops->cit_encrypt_iv = cbc_encrypt_iv; + ops->cit_decrypt_iv = cbc_decrypt_iv; + break; + + case CRYPTO_TFM_MODE_CFB: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CTR: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + default: + BUG(); + } + + if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { + + switch (crypto_tfm_alg_blocksize(tfm)) { + case 8: + ops->cit_xor_block = xor_64; + break; + + case 16: + ops->cit_xor_block = xor_128; + break; + + default: + printk(KERN_WARNING "%s: block size %u not supported\n", + crypto_tfm_alg_name(tfm), + crypto_tfm_alg_blocksize(tfm)); + ret = -EINVAL; + goto out; + } + + ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); + ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL); + if (ops->cit_iv == NULL) + ret = -ENOMEM; + } + +out: + return ret; +} + +void crypto_exit_cipher_ops(struct crypto_tfm *tfm) +{ + if (tfm->crt_cipher.cit_iv) + kfree(tfm->crt_cipher.cit_iv); +} diff --git a/drivers/staging/rtl8192e/ieee80211/compress.c b/drivers/staging/rtl8192e/ieee80211/compress.c new file mode 100644 index 00000000000..c2df80e2ed9 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/compress.c @@ -0,0 +1,64 @@ +/* + * Cryptographic API. + * + * Compression operations. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#include +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include "internal.h" + +static int crypto_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); +} + +static int crypto_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm), + src, slen, dst, + dlen); +} + +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + +int crypto_init_compress_ops(struct crypto_tfm *tfm) +{ + int ret = 0; + struct compress_tfm *ops = &tfm->crt_compress; + + ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm)); + if (ret) + goto out; + + ops->cot_compress = crypto_compress; + ops->cot_decompress = crypto_decompress; + +out: + return ret; +} + +void crypto_exit_compress_ops(struct crypto_tfm *tfm) +{ + tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm)); +} diff --git a/drivers/staging/rtl8192e/ieee80211/crypto_compat.h b/drivers/staging/rtl8192e/ieee80211/crypto_compat.h new file mode 100644 index 00000000000..587e8bb2db6 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/crypto_compat.h @@ -0,0 +1,90 @@ +/* + * Header file to maintain compatibility among different kernel versions. + * + * Copyright (c) 2004-2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +#include + +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); +} + + +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); +} + +#if 0 +/* + * crypto_free_tfm - Free crypto transform + * @tfm: Transform to free + * + * crypto_free_tfm() frees up the transform and any associated resources, + * then drops the refcount on the associated algorithm. + */ +void crypto_free_tfm(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg; + int size; + + if (unlikely(!tfm)) + return; + + alg = tfm->__crt_alg; + size = sizeof(*tfm) + alg->cra_ctxsize; + + if (alg->cra_exit) + alg->cra_exit(tfm); + crypto_exit_ops(tfm); + crypto_mod_put(alg); + memset(tfm, 0, size); + kfree(tfm); +} + +#endif +#if 1 + struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) +{ + struct crypto_tfm *tfm = NULL; + int err; + printk("call crypto_alloc_tfm!!!\n"); + do { + struct crypto_alg *alg; + + alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC); + err = PTR_ERR(alg); + if (IS_ERR(alg)) + continue; + + tfm = __crypto_alloc_tfm(alg, flags); + err = 0; + if (IS_ERR(tfm)) { + crypto_mod_put(alg); + err = PTR_ERR(tfm); + tfm = NULL; + } + } while (err == -EAGAIN && !signal_pending(current)); + + return tfm; +} +#endif +//EXPORT_SYMBOL_GPL(crypto_alloc_tfm); +//EXPORT_SYMBOL_GPL(crypto_free_tfm); + + diff --git a/drivers/staging/rtl8192e/ieee80211/digest.c b/drivers/staging/rtl8192e/ieee80211/digest.c new file mode 100644 index 00000000000..1a95f2d3783 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/digest.c @@ -0,0 +1,108 @@ +/* + * Cryptographic API. + * + * Digest operations. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include +#include "internal.h" + +static void init(struct crypto_tfm *tfm) +{ + tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm)); +} + +static void update(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg) +{ + unsigned int i; + + for (i = 0; i < nsg; i++) { + + struct page *pg = sg[i].page; + unsigned int offset = sg[i].offset; + unsigned int l = sg[i].length; + + do { + unsigned int bytes_from_page = min(l, ((unsigned int) + (PAGE_SIZE)) - + offset); + char *p = crypto_kmap(pg, 0) + offset; + + tfm->__crt_alg->cra_digest.dia_update + (crypto_tfm_ctx(tfm), p, + bytes_from_page); + crypto_kunmap(p, 0); + crypto_yield(tfm); + offset = 0; + pg++; + l -= bytes_from_page; + } while (l > 0); + } +} + +static void final(struct crypto_tfm *tfm, u8 *out) +{ + tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); +} + +static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) +{ + u32 flags; + if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) + return -ENOSYS; + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); +} + +static void digest(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg, u8 *out) +{ + unsigned int i; + + tfm->crt_digest.dit_init(tfm); + + for (i = 0; i < nsg; i++) { + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; + tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), + p, sg[i].length); + crypto_kunmap(p, 0); + crypto_yield(tfm); + } + crypto_digest_final(tfm, out); +} + +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + +int crypto_init_digest_ops(struct crypto_tfm *tfm) +{ + struct digest_tfm *ops = &tfm->crt_digest; + + ops->dit_init = init; + ops->dit_update = update; + ops->dit_final = final; + ops->dit_digest = digest; + ops->dit_setkey = setkey; + + return crypto_alloc_hmac_block(tfm); +} + +void crypto_exit_digest_ops(struct crypto_tfm *tfm) +{ + crypto_free_hmac_block(tfm); +} diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.c b/drivers/staging/rtl8192e/ieee80211/dot11d.c new file mode 100644 index 00000000000..908f6051d57 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/dot11d.c @@ -0,0 +1,239 @@ +#ifdef ENABLE_DOT11D +//----------------------------------------------------------------------------- +// File: +// Dot11d.c +// +// Description: +// Implement 802.11d. +// +//----------------------------------------------------------------------------- + +#include "dot11d.h" + +void +Dot11d_Init(struct ieee80211_device *ieee) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); + + pDot11dInfo->bEnabled = 0; + + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + RESET_CIE_WATCHDOG(ieee); + + printk("Dot11d_Init()\n"); +} + +// +// Description: +// Reset to the state as we are just entering a regulatory domain. +// +void +Dot11d_Reset(struct ieee80211_device *ieee) +{ + u32 i; + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); +#if 0 + if(!pDot11dInfo->bEnabled) + return; +#endif + // Clear old channel map + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + // Set new channel map + for (i=1; i<=11; i++) { + (pDot11dInfo->channel_map)[i] = 1; + } + for (i=12; i<=14; i++) { + (pDot11dInfo->channel_map)[i] = 2; + } + + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + RESET_CIE_WATCHDOG(ieee); + + //printk("Dot11d_Reset()\n"); +} + +// +// Description: +// Update country IE from Beacon or Probe Resopnse +// and configure PHY for operation in the regulatory domain. +// +// TODO: +// Configure Tx power. +// +// Assumption: +// 1. IS_DOT11D_ENABLE() is TRUE. +// 2. Input IE is an valid one. +// +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 i, j, NumTriples, MaxChnlNum; + PCHNL_TXPOWER_TRIPLE pTriple; + + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + MaxChnlNum = 0; + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string. + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3); + for(i = 0; i < NumTriples; i++) + { + if(MaxChnlNum >= pTriple->FirstChnl) + { // It is not in a monotonically increasing order, so stop processing. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); + return; + } + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls)) + { // It is not a valid set of channel id, so stop processing. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); + return; + } + + for(j = 0 ; j < pTriple->NumChnls; j++) + { + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm; + MaxChnlNum = pTriple->FirstChnl + j; + } + + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3); + } +#if 1 + //printk("Dot11d_UpdateCountryIe(): Channel List:\n"); + printk("Channel List:"); + for(i=1; i<= MAX_CHANNEL_NUMBER; i++) + if(pDot11dInfo->channel_map[i] > 0) + printk(" %d", i); + printk("\n"); +#endif + + UPDATE_CIE_SRC(dev, pTaddr); + + pDot11dInfo->CountryIeLen = CoutryIeLen; + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen); + pDot11dInfo->State = DOT11D_STATE_LEARNED; +} + + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 MaxTxPwrInDbm = 255; + + if(MAX_CHANNEL_NUMBER < Channel) + { + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); + return MaxTxPwrInDbm; + } + if(pDot11dInfo->channel_map[Channel]) + { + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; + } + + return MaxTxPwrInDbm; +} + + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + + switch(pDot11dInfo->State) + { + case DOT11D_STATE_LEARNED: + pDot11dInfo->State = DOT11D_STATE_DONE; + break; + + case DOT11D_STATE_DONE: + if( GET_CIE_WATCHDOG(dev) == 0 ) + { // Reset country IE if previous one is gone. + Dot11d_Reset(dev); + } + break; + case DOT11D_STATE_NONE: + break; + } +} + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + + if(MAX_CHANNEL_NUMBER < channel) + { + printk("IsLegalChannel(): Invalid Channel\n"); + return 0; + } + if(pDot11dInfo->channel_map[channel] > 0) + return 1; + return 0; +} + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +) +{ + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); + u8 default_chn = 0; + u32 i = 0; + + for (i=1; i<= MAX_CHANNEL_NUMBER; i++) + { + if(pDot11dInfo->channel_map[i] > 0) + { + default_chn = i; + break; + } + } + + if(MAX_CHANNEL_NUMBER < channel) + { + printk("IsLegalChannel(): Invalid Channel\n"); + return default_chn; + } + + if(pDot11dInfo->channel_map[channel] > 0) + return channel; + + return default_chn; +} +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(Dot11d_Init); +//EXPORT_SYMBOL(Dot11d_Reset); +//EXPORT_SYMBOL(Dot11d_UpdateCountryIe); +//EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm); +//EXPORT_SYMBOL(DOT11D_ScanComplete); +//EXPORT_SYMBOL(IsLegalChannel); +//EXPORT_SYMBOL(ToLegalChannel); +#else +EXPORT_SYMBOL_NOVERS(Dot11d_Init); +EXPORT_SYMBOL_NOVERS(Dot11d_Reset); +EXPORT_SYMBOL_NOVERS(Dot11d_UpdateCountryIe); +EXPORT_SYMBOL_NOVERS(DOT11D_GetMaxTxPwrInDbm); +EXPORT_SYMBOL_NOVERS(DOT11D_ScanComplete); +EXPORT_SYMBOL_NOVERS(IsLegalChannel); +EXPORT_SYMBOL_NOVERS(ToLegalChannel); +#endif + +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.h b/drivers/staging/rtl8192e/ieee80211/dot11d.h new file mode 100644 index 00000000000..15b7a4ba37b --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/dot11d.h @@ -0,0 +1,102 @@ +#ifndef __INC_DOT11D_H +#define __INC_DOT11D_H + +#ifdef ENABLE_DOT11D +#include "ieee80211.h" + +//#define ENABLE_DOT11D + +//#define DOT11D_MAX_CHNL_NUM 83 + +typedef struct _CHNL_TXPOWER_TRIPLE { + u8 FirstChnl; + u8 NumChnls; + u8 MaxTxPowerInDbm; +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; + +typedef enum _DOT11D_STATE { + DOT11D_STATE_NONE = 0, + DOT11D_STATE_LEARNED, + DOT11D_STATE_DONE, +}DOT11D_STATE; + +typedef struct _RT_DOT11D_INFO { + //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + + bool bEnabled; // dot11MultiDomainCapabilityEnabled + + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeWatchdog; + + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) + //u8 ChnlListLen; // #Bytes valid in ChnlList[]. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + + DOT11D_STATE State; +}RT_DOT11D_INFO, *PRT_DOT11D_INFO; +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) + +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) + +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) + +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ + FALSE : \ + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) + +#define CIE_WATCHDOG_TH 1 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) + +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) + + +void +Dot11d_Init( + struct ieee80211_device *dev + ); + +void +Dot11d_Reset( + struct ieee80211_device *dev + ); + +void +Dot11d_UpdateCountryIe( + struct ieee80211_device *dev, + u8 * pTaddr, + u16 CoutryIeLen, + u8 * pCoutryIe + ); + +u8 +DOT11D_GetMaxTxPwrInDbm( + struct ieee80211_device *dev, + u8 Channel + ); + +void +DOT11D_ScanComplete( + struct ieee80211_device * dev + ); + +int IsLegalChannel( + struct ieee80211_device * dev, + u8 channel +); + +int ToLegalChannel( + struct ieee80211_device * dev, + u8 channel +); +#endif //ENABLE_DOT11D +#endif // #ifndef __INC_DOT11D_H diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h new file mode 100644 index 00000000000..83c8452de37 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -0,0 +1,2802 @@ +/* + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 + * remains copyright by the original authors + * + * Portions of the merged code are based on Host AP (software wireless + * LAN access point) driver for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * Copyright (c) 2004, Intel Corporation + * + * Modified for Realtek's wi-fi cards by Andrea Merello + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ +#ifndef IEEE80211_H +#define IEEE80211_H +#include /* ETH_ALEN */ +#include /* ARRAY_SIZE */ +#include +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#include +#else +#include +#include +#endif +#include +#include + +#include +#include + +#include "rtl819x_HT.h" +#include "rtl819x_BA.h" +#include "rtl819x_TS.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#ifndef bool +typedef enum{false = 0, true} bool; +#endif +#endif + +#ifndef IW_MODE_MONITOR +#define IW_MODE_MONITOR 6 +#endif + +#ifndef IWEVCUSTOM +#define IWEVCUSTOM 0x8c02 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#ifndef __bitwise +#define __bitwise __attribute__((bitwise)) +#endif +typedef __u16 __le16; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) +struct iw_spy_data{ + /* --- Standard spy support --- */ + int spy_number; + u_char spy_address[IW_MAX_SPY][ETH_ALEN]; + struct iw_quality spy_stat[IW_MAX_SPY]; + /* --- Enhanced spy support (event) */ + struct iw_quality spy_thr_low; /* Low threshold */ + struct iw_quality spy_thr_high; /* High threshold */ + u_char spy_thr_under[IW_MAX_SPY]; +}; +#endif +#endif + +#ifndef container_of +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#define KEY_TYPE_NA 0x0 +#define KEY_TYPE_WEP40 0x1 +#define KEY_TYPE_TKIP 0x2 +#define KEY_TYPE_CCMP 0x4 +#define KEY_TYPE_WEP104 0x5 + +/* added for rtl819x tx procedure */ +#define MAX_QUEUE_SIZE 0x10 + +// +// 8190 queue mapping +// +#define BK_QUEUE 0 +#define BE_QUEUE 1 +#define VI_QUEUE 2 +#define VO_QUEUE 3 +#define HCCA_QUEUE 4 +#define TXCMD_QUEUE 5 +#define MGNT_QUEUE 6 +#define HIGH_QUEUE 7 +#define BEACON_QUEUE 8 + +#define LOW_QUEUE BE_QUEUE +#define NORMAL_QUEUE MGNT_QUEUE + +//added by amy for ps +#define SWRF_TIMEOUT 50 + +//added by amy for LEAP related +#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. +#define SUPPORT_CKIP_MIC 0x08 // bit3 +#define SUPPORT_CKIP_PK 0x10 // bit4 +/* defined for skb cb field */ +/* At most 28 byte */ +typedef struct cb_desc { + /* Tx Desc Related flags (8-9) */ + u8 bLastIniPkt:1; + u8 bCmdOrInit:1; + u8 bFirstSeg:1; + u8 bLastSeg:1; + u8 bEncrypt:1; + u8 bTxDisableRateFallBack:1; + u8 bTxUseDriverAssingedRate:1; + u8 bHwSec:1; //indicate whether use Hw security. WB + + u8 reserved1; + + /* Tx Firmware Relaged flags (10-11)*/ + u8 bCTSEnable:1; + u8 bRTSEnable:1; + u8 bUseShortGI:1; + u8 bUseShortPreamble:1; + u8 bTxEnableFwCalcDur:1; + u8 bAMPDUEnable:1; + u8 bRTSSTBC:1; + u8 RTSSC:1; + + u8 bRTSBW:1; + u8 bPacketBW:1; + u8 bRTSUseShortPreamble:1; + u8 bRTSUseShortGI:1; + u8 bMulticast:1; + u8 bBroadcast:1; + //u8 reserved2:2; + u8 drv_agg_enable:1; + u8 reserved2:1; + + /* Tx Desc related element(12-19) */ + u8 rata_index; + u8 queue_index; + //u8 reserved3; + //u8 reserved4; + u16 txbuf_size; + //u8 reserved5; + u8 RATRIndex; + u8 reserved6; + u8 reserved7; + u8 reserved8; + + /* Tx firmware related element(20-27) */ + u8 data_rate; + u8 rts_rate; + u8 ampdu_factor; + u8 ampdu_density; + //u8 reserved9; + //u8 reserved10; + //u8 reserved11; + u8 DrvAggrNum; + u16 pkt_size; + u8 reserved12; +}cb_desc, *pcb_desc; + +/*--------------------------Define -------------------------------------------*/ +#define MGN_1M 0x02 +#define MGN_2M 0x04 +#define MGN_5_5M 0x0b +#define MGN_11M 0x16 + +#define MGN_6M 0x0c +#define MGN_9M 0x12 +#define MGN_12M 0x18 +#define MGN_18M 0x24 +#define MGN_24M 0x30 +#define MGN_36M 0x48 +#define MGN_48M 0x60 +#define MGN_54M 0x6c + +#define MGN_MCS0 0x80 +#define MGN_MCS1 0x81 +#define MGN_MCS2 0x82 +#define MGN_MCS3 0x83 +#define MGN_MCS4 0x84 +#define MGN_MCS5 0x85 +#define MGN_MCS6 0x86 +#define MGN_MCS7 0x87 +#define MGN_MCS8 0x88 +#define MGN_MCS9 0x89 +#define MGN_MCS10 0x8a +#define MGN_MCS11 0x8b +#define MGN_MCS12 0x8c +#define MGN_MCS13 0x8d +#define MGN_MCS14 0x8e +#define MGN_MCS15 0x8f + +//---------------------------------------------------------------------------- +// 802.11 Management frame Reason Code field +//---------------------------------------------------------------------------- +enum _ReasonCode{ + unspec_reason = 0x1, + auth_not_valid = 0x2, + deauth_lv_ss = 0x3, + inactivity = 0x4, + ap_overload = 0x5, + class2_err = 0x6, + class3_err = 0x7, + disas_lv_ss = 0x8, + asoc_not_auth = 0x9, + + //----MIC_CHECK + mic_failure = 0xe, + //----END MIC_CHECK + + // Reason code defined in 802.11i D10.0 p.28. + invalid_IE = 0x0d, + four_way_tmout = 0x0f, + two_way_tmout = 0x10, + IE_dismatch = 0x11, + invalid_Gcipher = 0x12, + invalid_Pcipher = 0x13, + invalid_AKMP = 0x14, + unsup_RSNIEver = 0x15, + invalid_RSNIE = 0x16, + auth_802_1x_fail= 0x17, + ciper_reject = 0x18, + + // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15. + QoS_unspec = 0x20, // 32 + QAP_bandwidth = 0x21, // 33 + poor_condition = 0x22, // 34 + no_facility = 0x23, // 35 + // Where is 36??? + req_declined = 0x25, // 37 + invalid_param = 0x26, // 38 + req_not_honored= 0x27, // 39 + TS_not_created = 0x2F, // 47 + DL_not_allowed = 0x30, // 48 + dest_not_exist = 0x31, // 49 + dest_not_QSTA = 0x32, // 50 +}; + + + +#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10) + +#define MGMT_QUEUE_NUM 5 + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +//It should consistent with the driver_XXX.c +// David, 2006.9.26 +#define IEEE_PARAM_WPAX_SELECT 7 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_PROTO_WPA 1 +#define IEEE_PROTO_RSN 2 +//Added for notify the encryption type selection +// David, 2006.9.26 +#define IEEE_WPAX_USEGROUP 0 +#define IEEE_WPAX_WEP40 1 +#define IEEE_WPAX_TKIP 2 +#define IEEE_WPAX_WRAP 3 +#define IEEE_WPAX_CCMP 4 +#define IEEE_WPAX_WEP104 5 + +#define IEEE_KEY_MGMT_IEEE8021X 1 +#define IEEE_KEY_MGMT_PSK 2 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define MAX_IE_LEN 0xff + +// added for kernel conflict +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rsl +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rsl + +#define ieee80211_ccmp_null ieee80211_ccmp_null_rsl + +#define ieee80211_tkip_null ieee80211_tkip_null_rsl + +#define ieee80211_wep_null ieee80211_wep_null_rsl + +#define free_ieee80211 free_ieee80211_rsl +#define alloc_ieee80211 alloc_ieee80211_rsl + +#define ieee80211_rx ieee80211_rx_rsl +#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl + +#define ieee80211_get_beacon ieee80211_get_beacon_rsl +#define ieee80211_wake_queue ieee80211_wake_queue_rsl +#define ieee80211_stop_queue ieee80211_stop_queue_rsl +#define ieee80211_reset_queue ieee80211_reset_queue_rsl +#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl +#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl +#define ieee80211_is_shortslot ieee80211_is_shortslot_rsl +#define ieee80211_is_54g ieee80211_is_54g_rsl +#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl +#define ieee80211_ps_tx_ack ieee80211_ps_tx_ack_rsl +#define ieee80211_softmac_xmit ieee80211_softmac_xmit_rsl +#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rsl +#define notify_wx_assoc_event notify_wx_assoc_event_rsl +#define SendDisassociation SendDisassociation_rsl +#define ieee80211_disassociate ieee80211_disassociate_rsl +#define ieee80211_start_send_beacons ieee80211_start_send_beacons_rsl +#define ieee80211_stop_scan ieee80211_stop_scan_rsl +#define ieee80211_send_probe_requests ieee80211_send_probe_requests_rsl +#define ieee80211_softmac_scan_syncro ieee80211_softmac_scan_syncro_rsl +#define ieee80211_start_scan_syncro ieee80211_start_scan_syncro_rsl + +#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rsl +#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rsl +#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rsl +#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rsl +#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rsl +#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rsl +#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rsl +#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rsl +#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rsl +#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rsl +#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rsl +#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rsl +#define ieee80211_wx_get_name ieee80211_wx_get_name_rsl +#define ieee80211_wx_set_power ieee80211_wx_set_power_rsl +#define ieee80211_wx_get_power ieee80211_wx_get_power_rsl +#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rsl +#define ieee80211_wx_set_rts ieee80211_wx_set_rts_rsl +#define ieee80211_wx_get_rts ieee80211_wx_get_rts_rsl + +#define ieee80211_txb_free ieee80211_txb_free_rsl + +#define ieee80211_wx_set_gen_ie ieee80211_wx_set_gen_ie_rsl +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl +#if WIRELESS_EXT >= 18 +#define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl +#define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl +#define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl +#endif + + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; + } u; +}ieee_param; + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data) +{ + task->routine = func; + task->data = data; + //task->next = NULL; + INIT_LIST_HEAD(&task->list); + task->sync = 0; +} +#endif + +// linux under 2.6.9 release may not support it, so modify it for common use +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) +static inline unsigned long msleep_interruptible_rsl(unsigned int msecs) +{ + unsigned long timeout = MSECS(msecs) + 1; + + while (timeout) { + set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return timeout; +} +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31)) +static inline void msleep(unsigned int msecs) +{ + unsigned long timeout = MSECS(msecs) + 1; + + while (timeout) { + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } +} +#endif +#else +#define MSECS(t) msecs_to_jiffies(t) +#define msleep_interruptible_rsl msleep_interruptible +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ +#define IEEE80211_1ADDR_LEN 10 +#define IEEE80211_2ADDR_LEN 16 +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + + +/* Frame control field constants */ +#define IEEE80211_FCTL_VERS 0x0003 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_STYPE 0x00f0 +#define IEEE80211_FCTL_FRAMETYPE 0x00fc +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david +#define IEEE80211_FCTL_MOREFRAGS 0x0400 +#define IEEE80211_FCTL_RETRY 0x0800 +#define IEEE80211_FCTL_PM 0x1000 +#define IEEE80211_FCTL_MOREDATA 0x2000 +#define IEEE80211_FCTL_WEP 0x4000 +#define IEEE80211_FCTL_ORDER 0x8000 + +#define IEEE80211_FTYPE_MGMT 0x0000 +#define IEEE80211_FTYPE_CTL 0x0004 +#define IEEE80211_FTYPE_DATA 0x0008 + +/* management */ +#define IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define IEEE80211_STYPE_PROBE_REQ 0x0040 +#define IEEE80211_STYPE_PROBE_RESP 0x0050 +#define IEEE80211_STYPE_BEACON 0x0080 +#define IEEE80211_STYPE_ATIM 0x0090 +#define IEEE80211_STYPE_DISASSOC 0x00A0 +#define IEEE80211_STYPE_AUTH 0x00B0 +#define IEEE80211_STYPE_DEAUTH 0x00C0 +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 + +/* control */ +#define IEEE80211_STYPE_PSPOLL 0x00A0 +#define IEEE80211_STYPE_RTS 0x00B0 +#define IEEE80211_STYPE_CTS 0x00C0 +#define IEEE80211_STYPE_ACK 0x00D0 +#define IEEE80211_STYPE_CFEND 0x00E0 +#define IEEE80211_STYPE_CFENDACK 0x00F0 +#define IEEE80211_STYPE_BLOCKACK 0x0094 + +/* data */ +#define IEEE80211_STYPE_DATA 0x0000 +#define IEEE80211_STYPE_DATA_CFACK 0x0010 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define IEEE80211_STYPE_NULLFUNC 0x0040 +#define IEEE80211_STYPE_CFACK 0x0050 +#define IEEE80211_STYPE_CFPOLL 0x0060 +#define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 +#define IEEE80211_STYPE_QOS_NULL 0x00C0 + +#define IEEE80211_SCTL_FRAG 0x000F +#define IEEE80211_SCTL_SEQ 0xFFF0 + +/* QOS control */ +#define IEEE80211_QCTL_TID 0x000F + +#define FC_QOS_BIT BIT7 +#define IsDataFrame(pdu) ( ((pdu[0] & 0x0C)==0x08) ? true : false ) +#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) ) +//added by wb. Is this right? +#define IsQoSDataFrame(pframe) ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) +#define Frame_Order(pframe) (*(u16*)pframe&IEEE80211_FCTL_ORDER) +#define SN_LESS(a, b) (((a-b)&0x800)!=0) +#define SN_EQUAL(a, b) (a == b) +#define MAX_DEV_ADDR_SIZE 8 +typedef enum _ACT_CATEGORY{ + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +} ACT_CATEGORY, *PACT_CATEGORY; + +typedef enum _TS_ACTION{ + ACT_ADDTSREQ = 0, + ACT_ADDTSRSP = 1, + ACT_DELTS = 2, + ACT_SCHEDULE = 3, +} TS_ACTION, *PTS_ACTION; + +typedef enum _BA_ACTION{ + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +} BA_ACTION, *PBA_ACTION; + +typedef enum _InitialGainOpType{ + IG_Backup=0, + IG_Restore, + IG_Max +}InitialGainOpType; + +/* debug macros */ +#define CONFIG_IEEE80211_DEBUG +#ifdef CONFIG_IEEE80211_DEBUG +extern u32 ieee80211_debug_level; +#define IEEE80211_DEBUG(level, fmt, args...) \ +do { if (ieee80211_debug_level & (level)) \ + printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) +//wb added to debug out data buf +//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA +#define IEEE80211_DEBUG_DATA(level, data, datalen) \ + do{ if ((ieee80211_debug_level & (level)) == (level)) \ + { \ + int i; \ + u8* pdata = (u8*) data; \ + printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__); \ + for(i=0; i<(int)(datalen); i++) \ + { \ + printk("%2x ", pdata[i]); \ + if ((i+1)%16 == 0) printk("\n"); \ + } \ + printk("\n"); \ + } \ + } while (0) +#else +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) +#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) +#endif /* CONFIG_IEEE80211_DEBUG */ + +/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define IEEE80211_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/ipw/debug_level + * + * you simply need to add your entry to the ipw_debug_levels array. + * + * If you do not see debug_level in /proc/net/ipw then you do not have + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration + * + */ + +#define IEEE80211_DL_INFO (1<<0) +#define IEEE80211_DL_WX (1<<1) +#define IEEE80211_DL_SCAN (1<<2) +#define IEEE80211_DL_STATE (1<<3) +#define IEEE80211_DL_MGMT (1<<4) +#define IEEE80211_DL_FRAG (1<<5) +#define IEEE80211_DL_EAP (1<<6) +#define IEEE80211_DL_DROP (1<<7) + +#define IEEE80211_DL_TX (1<<8) +#define IEEE80211_DL_RX (1<<9) + +#define IEEE80211_DL_HT (1<<10) //HT +#define IEEE80211_DL_BA (1<<11) //ba +#define IEEE80211_DL_TS (1<<12) //TS +#define IEEE80211_DL_QOS (1<<13) +#define IEEE80211_DL_REORDER (1<<14) +#define IEEE80211_DL_IOT (1<<15) +#define IEEE80211_DL_IPS (1<<16) +#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen +#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. +#define IEEE80211_DL_ERR (1<<31) //always open +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) + +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) +#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) + +#ifdef CONFIG_IEEE80211_DEBUG +/* Added by Annie, 2005-11-22. */ +#define MAX_STR_LEN 64 +/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ +#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') +#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ + if((_Comp) & level) \ + { \ + int __i; \ + u8 buffer[MAX_STR_LEN]; \ + int length = (_Len\n", _Len, buffer); \ + } +#else +#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) do {} while (0) +#endif + +#include +#include /* ARPHRD_ETHER */ + +#ifndef WIRELESS_SPY +#define WIRELESS_SPY // enable iwspy support +#endif +#include // new driver API + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __attribute__ ((packed)); + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) + +#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_LEAP 2 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) + +/* 802.11g ERP information element */ +#define WLAN_ERP_NON_ERP_PRESENT (1<<0) +#define WLAN_ERP_USE_PROTECTION (1<<1) +#define WLAN_ERP_BARKER_PREAMBLE (1<<2) + +/* Status codes */ +enum ieee80211_statuscode { + WLAN_STATUS_SUCCESS = 0, + WLAN_STATUS_UNSPECIFIED_FAILURE = 1, + WLAN_STATUS_CAPS_UNSUPPORTED = 10, + WLAN_STATUS_REASSOC_NO_ASSOC = 11, + WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, + WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, + WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, + WLAN_STATUS_CHALLENGE_FAIL = 15, + WLAN_STATUS_AUTH_TIMEOUT = 16, + WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, + WLAN_STATUS_ASSOC_DENIED_RATES = 18, + /* 802.11b */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, + WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, + WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, + /* 802.11h */ + WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, + WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, + WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, + /* 802.11g */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, + WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, + /* 802.11i */ + WLAN_STATUS_INVALID_IE = 40, + WLAN_STATUS_INVALID_GROUP_CIPHER = 41, + WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, + WLAN_STATUS_INVALID_AKMP = 43, + WLAN_STATUS_UNSUPP_RSN_VERSION = 44, + WLAN_STATUS_INVALID_RSN_IE_CAP = 45, + WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, +}; + +/* Reason codes */ +enum ieee80211_reasoncode { + WLAN_REASON_UNSPECIFIED = 1, + WLAN_REASON_PREV_AUTH_NOT_VALID = 2, + WLAN_REASON_DEAUTH_LEAVING = 3, + WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, + WLAN_REASON_DISASSOC_AP_BUSY = 5, + WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, + WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, + WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, + /* 802.11h */ + WLAN_REASON_DISASSOC_BAD_POWER = 10, + WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, + /* 802.11i */ + WLAN_REASON_INVALID_IE = 13, + WLAN_REASON_MIC_FAILURE = 14, + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, + WLAN_REASON_IE_DIFFERENT = 17, + WLAN_REASON_INVALID_GROUP_CIPHER = 18, + WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, + WLAN_REASON_INVALID_AKMP = 20, + WLAN_REASON_UNSUPP_RSN_VERSION = 21, + WLAN_REASON_INVALID_RSN_IE_CAP = 22, + WLAN_REASON_IEEE8021X_FAILED = 23, + WLAN_REASON_CIPHER_SUITE_REJECTED = 24, +}; + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + +/* this is stolen and modified from the madwifi driver*/ +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_DATA 0x08 +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 + +#define IEEE80211_QOS_HAS_SEQ(fc) \ + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num[17]; + u16 frag_num[17]; + unsigned long packet_time[17]; + struct list_head list; +}; + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { +#if 1 + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u16 rate; /* in 100 kbps */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 Length; + // u8 DataRate; // In 0.5 Mbps + u8 SignalQuality; // in 0-100 index. + s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. + s8 RxPower; // in dBm Translate from PWdB + u8 SignalStrength; // in 0-100 index. + u16 bHwError:1; + u16 bCRC:1; + u16 bICV:1; + u16 bShortPreamble:1; + u16 Antenna:1; //for rtl8185 + u16 Decrypted:1; //for rtl8185, rtl8187 + u16 Wakeup:1; //for rtl8185 + u16 Reserved0:1; //for rtl8185 + u8 AGC; + u32 TimeStampLow; + u32 TimeStampHigh; + bool bShift; + bool bIsQosData; // Added by Annie, 2005-12-22. + u8 UserPriority; + + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + //1Attention Please!!!<11n or 8190 specific code should be put below this line> + //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + + u8 RxDrvInfoSize; + u8 RxBufShift; + bool bIsAMPDU; + bool bFirstMPDU; + bool bContainHTC; + bool RxIs40MHzPacket; + u32 RxPWDBAll; + u8 RxMIMOSignalStrength[4]; // in 0~100 index + s8 RxMIMOSignalQuality[2]; + bool bPacketMatchBSSID; + bool bIsCCK; + bool bPacketToSelf; + //added by amy + u8* virtual_address; + u16 packetlength; // Total packet length: Must equal to sum of all FragLength + u16 fraglength; // FragLength should equal to PacketLength in non-fragment case + u16 fragoffset; // Data offset for this fragment + u16 ntotalfrag; + bool bisrxaggrsubframe; + bool bPacketBeacon; //cosa add for rssi + bool bToSelfBA; //cosa add for rssi + char cck_adc_pwdb[4]; //cosa add for rx path selection + u16 Seq_Num; +#endif + +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + unsigned long first_frag_time; + unsigned int seq; + unsigned int last_frag; + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +struct ieee80211_stats { + unsigned int tx_unicast_frames; + unsigned int tx_multicast_frames; + unsigned int tx_fragments; + unsigned int tx_unicast_octets; + unsigned int tx_multicast_octets; + unsigned int tx_deferred_transmissions; + unsigned int tx_single_retry_frames; + unsigned int tx_multiple_retry_frames; + unsigned int tx_retry_limit_exceeded; + unsigned int tx_discards; + unsigned int rx_unicast_frames; + unsigned int rx_multicast_frames; + unsigned int rx_fragments; + unsigned int rx_unicast_octets; + unsigned int rx_multicast_octets; + unsigned int rx_fcs_errors; + unsigned int rx_discards_no_buffer; + unsigned int tx_discards_wrong_sa; + unsigned int rx_discards_undecryptable; + unsigned int rx_message_in_msg_fragments; + unsigned int rx_message_in_bad_msg_fragments; +}; + +struct ieee80211_device; + +#include "ieee80211_crypt.h" + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) +#define SEC_ENCRYPT (1<<9) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define SEC_ALG_NONE 0 +#define SEC_ALG_WEP 1 +#define SEC_ALG_TKIP 2 +#define SEC_ALG_CCMP 3 + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 +#define SCM_KEY_LEN 32 +#define SCM_TEMPORAL_KEY_LENGTH 16 + +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1, + encrypt:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][SCM_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + + +/* + 802.11 data frame from AP + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' +Total: 28-2340 bytes +*/ + +/* Management Frame Information Element Types */ +enum ieee80211_mfie { + MFIE_TYPE_SSID = 0, + MFIE_TYPE_RATES = 1, + MFIE_TYPE_FH_SET = 2, + MFIE_TYPE_DS_SET = 3, + MFIE_TYPE_CF_SET = 4, + MFIE_TYPE_TIM = 5, + MFIE_TYPE_IBSS_SET = 6, + MFIE_TYPE_COUNTRY = 7, + MFIE_TYPE_HOP_PARAMS = 8, + MFIE_TYPE_HOP_TABLE = 9, + MFIE_TYPE_REQUEST = 10, + MFIE_TYPE_CHALLENGE = 16, + MFIE_TYPE_POWER_CONSTRAINT = 32, + MFIE_TYPE_POWER_CAPABILITY = 33, + MFIE_TYPE_TPC_REQUEST = 34, + MFIE_TYPE_TPC_REPORT = 35, + MFIE_TYPE_SUPP_CHANNELS = 36, + MFIE_TYPE_CSA = 37, + MFIE_TYPE_MEASURE_REQUEST = 38, + MFIE_TYPE_MEASURE_REPORT = 39, + MFIE_TYPE_QUIET = 40, + MFIE_TYPE_IBSS_DFS = 41, + MFIE_TYPE_ERP = 42, + MFIE_TYPE_RSN = 48, + MFIE_TYPE_RATES_EX = 50, + MFIE_TYPE_HT_CAP= 45, + MFIE_TYPE_HT_INFO= 61, + MFIE_TYPE_AIRONET=133, + MFIE_TYPE_GENERIC = 221, + MFIE_TYPE_QOS_PARAMETER = 222, +}; + +/* Minimal header; can be used for passing 802.11 frames with sufficient + * information to determine what type of underlying data type is actually + * stored in the data. */ +struct ieee80211_hdr { + __le16 frame_ctl; + __le16 duration_id; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_1addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_2addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; + __le16 qos_ctl; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; + __le16 qos_ctl; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); + +struct ieee80211_authentication { + struct ieee80211_hdr_3addr header; + __le16 algorithm; + __le16 transaction; + __le16 status; + /*challenge*/ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_disassoc { + struct ieee80211_hdr_3addr header; + __le16 reason; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_hdr_3addr header; + /* SSID, supported rates */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_probe_response { + struct ieee80211_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +/* Alias beacon for probe_response */ +#define ieee80211_beacon ieee80211_probe_response + +struct ieee80211_assoc_request_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + /* SSID, supported rates, RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_reassoc_request_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + u8 current_ap[ETH_ALEN]; + /* SSID, supported rates, RSN */ + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct ieee80211_hdr_3addr header; + __le16 capability; + __le16 status; + __le16 aid; + struct ieee80211_info_element info_element[0]; /* supported rates */ +} __attribute__ ((packed)); + +struct ieee80211_txb { + u8 nr_frags; + u8 encrypted; + u8 queue_index; + u8 rts_included; + u16 reserved; + __le16 frag_size; + __le16 payload_size; + struct sk_buff *fragments[0]; +}; + +#define MAX_TX_AGG_COUNT 16 +struct ieee80211_drv_agg_txb { + u8 nr_drv_agg_frames; + struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; +}__attribute__((packed)); + +#define MAX_SUBFRAME_COUNT 64 +struct ieee80211_rxb { + u8 nr_subframes; + struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; +}__attribute__((packed)); + +typedef union _frameqos { + u16 shortdata; + u8 chardata[2]; + struct { + u16 tid:4; + u16 eosp:1; + u16 ack_policy:2; + u16 reserved:1; + u16 txop:8; + }field; +}frameqos,*pframeqos; + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 + +#define MAX_CHANNEL_NUMBER 161 +#define IEEE80211_SOFTMAC_SCAN_TIME 100 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN 64 + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +/* QoS structure */ +#define NETWORK_HAS_QOS_PARAMETERS (1<<3) +#define NETWORK_HAS_QOS_INFORMATION (1<<4) +#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ + NETWORK_HAS_QOS_INFORMATION) +/* 802.11h */ +#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) +#define NETWORK_HAS_CSA (1<<6) +#define NETWORK_HAS_QUIET (1<<7) +#define NETWORK_HAS_IBSS_DFS (1<<8) +#define NETWORK_HAS_TPC_REPORT (1<<9) + +#define NETWORK_HAS_ERP_VALUE (1<<10) + +#define QOS_QUEUE_NUM 4 +#define QOS_OUI_LEN 3 +#define QOS_OUI_TYPE 2 +#define QOS_ELEMENT_ID 221 +#define QOS_OUI_INFO_SUB_TYPE 0 +#define QOS_OUI_PARAM_SUB_TYPE 1 +#define QOS_VERSION_1 1 +#define QOS_AIFSN_MIN_VALUE 2 +#if 1 +struct ieee80211_qos_information_element { + u8 elementID; + u8 length; + u8 qui[QOS_OUI_LEN]; + u8 qui_type; + u8 qui_subtype; + u8 version; + u8 ac_info; +} __attribute__ ((packed)); + +struct ieee80211_qos_ac_parameter { + u8 aci_aifsn; + u8 ecw_min_max; + __le16 tx_op_limit; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameter_info { + struct ieee80211_qos_information_element info_element; + u8 reserved; + struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameters { + __le16 cw_min[QOS_QUEUE_NUM]; + __le16 cw_max[QOS_QUEUE_NUM]; + u8 aifs[QOS_QUEUE_NUM]; + u8 flag[QOS_QUEUE_NUM]; + __le16 tx_op_limit[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_data { + struct ieee80211_qos_parameters parameters; + int active; + int supported; + u8 param_count; + u8 old_param_count; +}; + +struct ieee80211_tim_parameters { + u8 tim_count; + u8 tim_period; +} __attribute__ ((packed)); + +//#else +struct ieee80211_wmm_ac_param { + u8 ac_aci_acm_aifsn; + u8 ac_ecwmin_ecwmax; + u16 ac_txop_limit; +}; + +struct ieee80211_wmm_ts_info { + u8 ac_dir_tid; + u8 ac_up_psb; + u8 reserved; +} __attribute__ ((packed)); + +struct ieee80211_wmm_tspec_elem { + struct ieee80211_wmm_ts_info ts_info; + u16 norm_msdu_size; + u16 max_msdu_size; + u32 min_serv_inter; + u32 max_serv_inter; + u32 inact_inter; + u32 suspen_inter; + u32 serv_start_time; + u32 min_data_rate; + u32 mean_data_rate; + u32 peak_data_rate; + u32 max_burst_size; + u32 delay_bound; + u32 min_phy_rate; + u16 surp_band_allow; + u16 medium_time; +}__attribute__((packed)); +#endif +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +static const char *eap_types[] = { + [EAP_PACKET] = "EAP-Packet", + [EAPOL_START] = "EAPOL-Start", + [EAPOL_LOGOFF] = "EAPOL-Logoff", + [EAPOL_KEY] = "EAPOL-Key", + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" +}; + +static inline const char *eap_get_type(int type) +{ + return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; +} +//added by amy for reorder +static inline u8 Frame_QoSTID(u8* buf) +{ + struct ieee80211_hdr_3addr *hdr; + u16 fc; + hdr = (struct ieee80211_hdr_3addr *)buf; + fc = le16_to_cpu(hdr->frame_ctl); + return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid; +} + +//added by amy for reorder + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__ ((packed)); + +struct ieee80211_softmac_stats{ + unsigned int rx_ass_ok; + unsigned int rx_ass_err; + unsigned int rx_probe_rq; + unsigned int tx_probe_rs; + unsigned int tx_beacons; + unsigned int rx_auth_rq; + unsigned int rx_auth_rs_ok; + unsigned int rx_auth_rs_err; + unsigned int tx_auth_rq; + unsigned int no_auth_rs; + unsigned int no_ass_rs; + unsigned int tx_ass_rq; + unsigned int rx_ass_rq; + unsigned int tx_probe_rq; + unsigned int reassoc; + unsigned int swtxstop; + unsigned int swtxawake; + unsigned char CurrentShowTxate; + unsigned char last_packet_rate; + unsigned int txretrycount; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps + +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; +#define MAX_SP_Len (WMM_all_frame << 4) +#define IEEE80211_QOS_TID 0x0f +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST + +//added by David for QoS 2006/6/30 +//#define WMM_Hang_8187 +#ifdef WMM_Hang_8187 +#undef WMM_Hang_8187 +#endif + +#define WME_AC_BK 0x00 +#define WME_AC_BE 0x01 +#define WME_AC_VI 0x02 +#define WME_AC_VO 0x03 +#define WME_ACI_MASK 0x03 +#define WME_AIFSN_MASK 0x03 +#define WME_AC_PRAM_LEN 16 + +#define MAX_RECEIVE_BUFFER_SIZE 9100 + +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) +#if 1 +#define UP2AC(up) ( \ + ((up) < 1) ? WME_AC_BE : \ + ((up) < 3) ? WME_AC_BK : \ + ((up) < 4) ? WME_AC_BE : \ + ((up) < 6) ? WME_AC_VI : \ + WME_AC_VO) +#endif +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue +#define AC2UP(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ +#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address plus ether type*/ + +struct ether_header { + u8 ether_dhost[ETHER_ADDR_LEN]; + u8 ether_shost[ETHER_ADDR_LEN]; + u16 ether_type; +} __attribute__((packed)); + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif + +typedef struct _bss_ht{ + + bool support_ht; + + // HT related elements + u8 ht_cap_buf[32]; + u16 ht_cap_len; + u8 ht_info_buf[32]; + u16 ht_info_len; + + HT_SPEC_VER ht_spec_ver; + //HT_CAPABILITY_ELE bdHTCapEle; + //HT_INFORMATION_ELE bdHTInfoEle; + + bool aggregation; + bool long_slot_time; +}bss_ht, *pbss_ht; + +typedef enum _erp_t{ + ERP_NonERPpresent = 0x01, + ERP_UseProtection = 0x02, + ERP_BarkerPreambleMode = 0x04, +} erp_t; + + +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; +#if 1 + struct ieee80211_qos_data qos_data; +#else + // Qos related. Added by Annie, 2005-11-01. + BSS_QOS BssQos; +#endif + + //added by amy for LEAP + bool bWithAironetIE; + bool bCkipSupported; + bool bCcxRmEnable; + u16 CcxRmState[2]; + // CCXv4 S59, MBSSID. + bool bMBssidValid; + u8 MBssidMask; + u8 MBssid[6]; + // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. + bool bWithCcxVerNum; + u8 BssCcxVerNumber; + /* These are network statistics */ + struct ieee80211_rx_stats stats; + u16 capability; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + unsigned long last_scanned; + u8 mode; + u32 flags; + u32 last_associate; + u32 time_stamp[2]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 erp_value; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + + struct ieee80211_tim_parameters tim; + u8 dtim_period; + u8 dtim_data; + u32 last_dtim_sta_time[2]; + + //appeded for QoS + u8 wmm_info; + struct ieee80211_wmm_ac_param wmm_param[4]; + u8 QoS_Enable; +#ifdef THOMAS_TURBO + u8 Turbo_Enable;//enable turbo mode, added by thomas +#endif +#ifdef ENABLE_DOT11D + u16 CountryIeLen; + u8 CountryIeBuf[MAX_IE_LEN]; +#endif + // HT Related, by amy, 2008.04.29 + BSS_HT bssht; + // Add to handle broadcom AP management frame CCK rate. + bool broadcom_cap_exist; + bool ralink_cap_exist; + bool atheros_cap_exist; + bool cisco_cap_exist; + bool unknown_cap_exist; +// u8 berp_info; + bool berp_info_valid; + bool buseprotection; + //put at the end of the structure. + struct list_head list; +}; + +#if 1 +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, + +}; +#else +enum ieee80211_state { + IEEE80211_UNINITIALIZED = 0, + IEEE80211_INITIALIZED, + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATED, + IEEE80211_AUTHENTICATING, + IEEE80211_AUTHENTICATED, + IEEE80211_SHUTDOWN +}; +#endif + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) +#define CFG_IEEE80211_RTS (1<<2) + +#define IEEE80211_24GHZ_MIN_CHANNEL 1 +#define IEEE80211_24GHZ_MAX_CHANNEL 14 +#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ + IEEE80211_24GHZ_MIN_CHANNEL + 1) + +#define IEEE80211_52GHZ_MIN_CHANNEL 34 +#define IEEE80211_52GHZ_MAX_CHANNEL 165 +#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ + IEEE80211_52GHZ_MIN_CHANNEL + 1) + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)) +extern inline int is_multicast_ether_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} +#endif + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)) +extern inline int is_broadcast_ether_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} +#endif + +typedef struct tx_pending_t{ + int frag; + struct ieee80211_txb *txb; +}tx_pending_t; + +typedef struct _bandwidth_autoswitch +{ + long threshold_20Mhzto40Mhz; + long threshold_40Mhzto20Mhz; + bool bforced_tx20Mhz; + bool bautoswitch_enable; +}bandwidth_autoswitch,*pbandwidth_autoswitch; + + +//added by amy for order + +#define REORDER_WIN_SIZE 128 +#define REORDER_ENTRY_NUM 128 +typedef struct _RX_REORDER_ENTRY +{ + struct list_head List; + u16 SeqNum; + struct ieee80211_rxb* prxb; +} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY; +//added by amy for order +typedef enum _Fsync_State{ + Default_Fsync, + HW_Fsync, + SW_Fsync +}Fsync_State; + +// Power save mode configured. +typedef enum _RT_PS_MODE +{ + eActive, // Active/Continuous access. + eMaxPs, // Max power save mode. + eFastPs // Fast power save mode. +}RT_PS_MODE; + +typedef enum _IPS_CALLBACK_FUNCION +{ + IPS_CALLBACK_NONE = 0, + IPS_CALLBACK_MGNT_LINK_REQUEST = 1, + IPS_CALLBACK_JOIN_REQUEST = 2, +}IPS_CALLBACK_FUNCION; + +typedef enum _RT_JOIN_ACTION{ + RT_JOIN_INFRA = 1, + RT_JOIN_IBSS = 2, + RT_START_IBSS = 3, + RT_NO_ACTION = 4, +}RT_JOIN_ACTION; + +typedef struct _IbssParms{ + u16 atimWin; +}IbssParms, *PIbssParms; +#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. + +// RF state. +typedef enum _RT_RF_POWER_STATE +{ + eRfOn, + eRfSleep, + eRfOff +}RT_RF_POWER_STATE; + +typedef struct _RT_POWER_SAVE_CONTROL +{ + + // + // Inactive Power Save(IPS) : Disable RF when disconnected + // + bool bInactivePs; + bool bIPSModeBackup; + bool bSwRfProcessing; + RT_RF_POWER_STATE eInactivePowerState; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct InactivePsWorkItem; +#else + struct tq_struct InactivePsWorkItem; +#endif + struct timer_list InactivePsTimer; + + // Return point for join action + IPS_CALLBACK_FUNCION ReturnPoint; + + // Recored Parameters for rescheduled JoinRequest + bool bTmpBssDesc; + RT_JOIN_ACTION tmpJoinAction; + struct ieee80211_network tmpBssDesc; + + // Recored Parameters for rescheduled MgntLinkRequest + bool bTmpScanOnly; + bool bTmpActiveScan; + bool bTmpFilterHiddenAP; + bool bTmpUpdateParms; + u8 tmpSsidBuf[33]; + OCTET_STRING tmpSsid2Scan; + bool bTmpSsid2Scan; + u8 tmpNetworkType; + u8 tmpChannelNumber; + u16 tmpBcnPeriod; + u8 tmpDtimPeriod; + u16 tmpmCap; + OCTET_STRING tmpSuppRateSet; + u8 tmpSuppRateBuf[MAX_NUM_RATES]; + bool bTmpSuppRate; + IbssParms tmpIbpm; + bool bTmpIbpm; + + // + // Leisre Poswer Save : Disable RF if connected but traffic is not busy + // + bool bLeisurePs; + +}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; + +typedef u32 RT_RF_CHANGE_SOURCE; +#define RF_CHANGE_BY_SW BIT31 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. + +#ifdef ENABLE_DOT11D +typedef enum +{ + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC, + COUNTRY_CODE_MIC, + COUNTRY_CODE_GLOBAL_DOMAIN +}country_code_type_t; +#endif + +#define RT_MAX_LD_SLOT_NUM 10 +typedef struct _RT_LINK_DETECT_T{ + + u32 NumRecvBcnInPeriod; + u32 NumRecvDataInPeriod; + + u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status + u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status + u16 SlotNum; // number of CheckForHang period to determine link status + u16 SlotIndex; + + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + bool bBusyTraffic; +}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; + + +struct ieee80211_device { + struct net_device *dev; + struct ieee80211_security sec; + + //hw security related +// u8 hwsec_support; //support? + u8 hwsec_active; //hw security active. + bool is_silent_reset; + bool is_roaming; + bool ieee_up; + //added by amy + bool bSupportRemoteWakeUp; + RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. + bool actscanning; + bool beinretry; + RT_RF_POWER_STATE eRFPowerState; + RT_RF_CHANGE_SOURCE RfOffReason; + bool is_set_key; + //11n spec related I wonder if These info structure need to be moved out of ieee80211_device + + //11n HT below + PRT_HIGH_THROUGHPUT pHTInfo; + //struct timer_list SwBwTimer; +// spinlock_t chnlop_spinlock; + spinlock_t bw_spinlock; + + spinlock_t reorder_spinlock; + // for HT operation rate set. we use this one for HT data rate to seperate different descriptors + //the way fill this is the same as in the IE + u8 Regdot11HTOperationalRateSet[16]; //use RATR format + u8 dot11HTOperationalRateSet[16]; //use RATR format + u8 RegHTSuppRateSet[16]; + u8 HTCurrentOperaRate; + u8 HTHighestOperaRate; + //wb added for rate operation mode to firmware + u8 bTxDisableRateFallBack; + u8 bTxUseDriverAssingedRate; + atomic_t atm_chnlop; + atomic_t atm_swbw; +// u8 HTHighestOperaRate; +// u8 HTCurrentOperaRate; + + // 802.11e and WMM Traffic Stream Info (TX) + struct list_head Tx_TS_Admit_List; + struct list_head Tx_TS_Pending_List; + struct list_head Tx_TS_Unused_List; + TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM]; + // 802.11e and WMM Traffic Stream Info (RX) + struct list_head Rx_TS_Admit_List; + struct list_head Rx_TS_Pending_List; + struct list_head Rx_TS_Unused_List; + RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; +//#ifdef TO_DO_LIST + RX_REORDER_ENTRY RxReorderEntry[128]; + struct list_head RxReorder_Unused_List; +//#endif + // Qos related. Added by Annie, 2005-11-01. +// PSTA_QOS pStaQos; + u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) + + + /* Bookkeeping structures */ + struct net_device_stats stats; + struct ieee80211_stats ieee_stats; + struct ieee80211_softmac_stats softmac_stats; + + /* Probe / Beacon management */ + struct list_head network_free_list; + struct list_head network_list; + struct ieee80211_network *networks; + int scans; + int scan_age; + + int iw_mode; /* operating mode (IW_MODE_*) */ + struct iw_spy_data spy_data; + + spinlock_t lock; + spinlock_t wpax_suitlist_lock; + + int tx_headroom; /* Set to size of any additional room needed at front + * of allocated Tx SKBs */ + u32 config; + + /* WEP and other encryption related settings at the device level */ + int open_wep; /* Set to 1 to allow unencrypted frames */ + int auth_mode; + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on + * WEP key changes */ + + /* If the host performs {en,de}cryption, then set to 1 */ + int host_encrypt; + int host_encrypt_msdu; + int host_decrypt; + /* host performs multicast decryption */ + int host_mc_decrypt; + + /* host should strip IV and ICV from protected frames */ + /* meaningful only when hardware decryption is being used */ + int host_strip_iv_icv; + + int host_open_frag; + int host_build_iv; + int ieee802_1x; /* is IEEE 802.1X used */ + + /* WPA data */ + bool bHalfWirelessN24GMode; + int wpa_enabled; + int drop_unencrypted; + int tkip_countermeasures; + int privacy_invoked; + size_t wpa_ie_len; + u8 *wpa_ie; + u8 ap_mac_addr[6]; + u16 pairwise_key_type; + u16 group_key_type; + struct list_head crypt_deinit_list; + struct ieee80211_crypt_data *crypt[WEP_KEYS]; + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ + struct timer_list crypt_deinit_timer; + int crypt_quiesced; + + int bcrx_sta_key; /* use individual keys to override default keys even + * with RX of broad/multicast frames */ + + /* Fragmentation structures */ + // each streaming contain a entry + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; + unsigned int frag_next_idx[17]; + u16 fts; /* Fragmentation Threshold */ +#define DEFAULT_RTS_THRESHOLD 2346U +#define MIN_RTS_THRESHOLD 1 +#define MAX_RTS_THRESHOLD 2346U + u16 rts; /* RTS threshold */ + + /* Association info */ + u8 bssid[ETH_ALEN]; + + /* This stores infos for the current network. + * Either the network we are associated in INFRASTRUCTURE + * or the network that we are creating in MASTER mode. + * ad-hoc is a mixture ;-). + * Note that in infrastructure mode, even when not associated, + * fields bssid and essid may be valid (if wpa_set and essid_set + * are true) as thy carry the value set by the user via iwconfig + */ + struct ieee80211_network current_network; + + enum ieee80211_state state; + + int short_slot; + int reg_mode; + int mode; /* A, B, G */ + int modulation; /* CCK, OFDM */ + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ + int abg_true; /* ABG flag */ + + /* used for forcing the ibss workqueue to terminate + * without wait for the syncro scan to terminate + */ + short sync_scan_hurryup; + + int perfect_rssi; + int worst_rssi; + + u16 prev_seq_ctl; /* used to drop duplicate frames */ + + /* map of allowed channels. 0 is dummy */ + // FIXME: remeber to default to a basic channel plan depending of the PHY type +#ifdef ENABLE_DOT11D + void* pDot11dInfo; + bool bGlobalDomain; +#else + int channel_map[MAX_CHANNEL_NUMBER+1]; +#endif + int rate; /* current rate */ + int basic_rate; + //FIXME: pleace callback, see if redundant with softmac_features + short active_scan; + + /* this contains flags for selectively enable softmac support */ + u16 softmac_features; + + /* if the sequence control field is not filled by HW */ + u16 seq_ctrl[5]; + + /* association procedure transaction sequence number */ + u16 associate_seq; + + /* AID for RTXed association responses */ + u16 assoc_id; + + /* power save mode related*/ + u8 ack_tx_to_ieee; + short ps; + short sta_sleep; + int ps_timeout; + int ps_period; + struct tasklet_struct ps_task; + u32 ps_th; + u32 ps_tl; + + short raw_tx; + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + short queue_stop; + short scanning; + short proto_started; + + struct semaphore wx_sem; + struct semaphore scan_sem; + + spinlock_t mgmt_tx_lock; + spinlock_t beacon_lock; + + short beacon_txing; + + short wap_set; + short ssid_set; + + u8 wpax_type_set; //{added by David, 2006.9.28} + u32 wpax_type_notify; //{added by David, 2006.9.26} + + /* QoS related flag */ + char init_wmmparam_flag; + /* set on initialization */ + u8 qos_support; + + /* for discarding duplicated packets in IBSS */ + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; + + /* for discarding duplicated packets in BSS */ + u16 last_rxseq_num[17]; /* rx seq previous per-tid */ + u16 last_rxfrag_num[17];/* tx frag previous per-tid */ + unsigned long last_packet_time[17]; + + /* for PS mode */ + unsigned long last_rx_ps_time; + + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; + int mgmt_queue_head; + int mgmt_queue_tail; +//{ added for rtl819x +#define IEEE80211_QUEUE_LIMIT 128 + u8 AsocRetryCount; + unsigned int hw_header; + struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; + u32 sta_edca_param[4]; + bool aggregation; + // Enable/Disable Rx immediate BA capability. + bool enable_rx_imm_BA; + bool bibsscoordinator; + + //+by amy for DM ,080515 + //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 + bool bdynamic_txpower_enable; + + bool bCTSToSelfEnable; + u8 CTSToSelfTH; + + u32 fsync_time_interval; + u32 fsync_rate_bitmap; + u8 fsync_rssi_threshold; + bool bfsync_enable; + + u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval + u32 fsync_firstdiff_ratethreshold; // low threshold + u32 fsync_seconddiff_ratethreshold; // decrease threshold + Fsync_State fsync_state; + bool bis_any_nonbepkts; + //20Mhz 40Mhz AutoSwitch Threshold + bandwidth_autoswitch bandwidth_auto_switch; + //for txpower tracking + bool FwRWRF; + + //added by amy for AP roaming + RT_LINK_DETECT_T LinkDetectInfo; + //added by amy for ps + RT_POWER_SAVE_CONTROL PowerSaveControl; +//} + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + struct tx_pending_t tx_pending; + + /* used if IEEE_SOFTMAC_ASSOCIATE is set */ + struct timer_list associate_timer; + + /* used if IEEE_SOFTMAC_BEACONS is set */ + struct timer_list beacon_timer; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct associate_complete_wq; + struct work_struct associate_procedure_wq; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct delayed_work softmac_scan_wq; + struct delayed_work associate_retry_wq; + struct delayed_work start_ibss_wq; + struct delayed_work hw_wakeup_wq; + struct delayed_work hw_sleep_wq; +#else + struct work_struct softmac_scan_wq; + struct work_struct associate_retry_wq; + struct work_struct start_ibss_wq; + struct work_struct hw_wakeup_wq; + struct work_struct hw_sleep_wq; +#endif + struct work_struct wx_sync_scan_wq; + struct workqueue_struct *wq; +#else + /* used for periodly scan */ + struct timer_list scan_timer; + + struct tq_struct associate_complete_wq; + struct tq_struct associate_retry_wq; + struct tq_struct start_ibss_wq; + struct tq_struct associate_procedure_wq; + struct tq_struct softmac_scan_wq; + struct tq_struct wx_sync_scan_wq; + +#endif + // Qos related. Added by Annie, 2005-11-01. + //STA_QOS StaQos; + + //u32 STA_EDCA_PARAM[4]; + //CHANNEL_ACCESS_SETTING ChannelAccessSetting; + + + /* Callback functions */ + void (*set_security)(struct net_device *dev, + struct ieee80211_security *sec); + + /* Used to TX data frame by using txb structs. + * this is not used if in the softmac_features + * is set the flag IEEE_SOFTMAC_TX_QUEUE + */ + int (*hard_start_xmit)(struct ieee80211_txb *txb, + struct net_device *dev); + + int (*reset_port)(struct net_device *dev); + int (*is_queue_full) (struct net_device * dev, int pri); + + int (*handle_management) (struct net_device * dev, + struct ieee80211_network * network, u16 type); + int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); + + /* Softmac-generated frames (mamagement) are TXed via this + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is + * not set. As some cards may have different HW queues that + * one might want to use for data and management frames + * the option to have two callbacks might be useful. + * This fucntion can't sleep. + */ + int (*softmac_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* used instead of hard_start_xmit (not softmac_hard_start_xmit) + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * then also management frames are sent via this callback. + * This function can't sleep. + */ + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev,int rate); + + /* stops the HW queue for DATA frames. Useful to avoid + * waste time to TX data frame when we are reassociating + * This function can sleep. + */ + void (*data_hard_stop)(struct net_device *dev); + + /* OK this is complementar to data_poll_hard_stop */ + void (*data_hard_resume)(struct net_device *dev); + + /* ask to the driver to retune the radio . + * This function can sleep. the driver should ensure + * the radio has been swithced before return. + */ + void (*set_chan)(struct net_device *dev,short ch); + + /* These are not used if the ieee stack takes care of + * scanning (IEEE_SOFTMAC_SCAN feature set). + * In this case only the set_chan is used. + * + * The syncro version is similar to the start_scan but + * does not return until all channels has been scanned. + * this is called in user context and should sleep, + * it is called in a work_queue when swithcing to ad-hoc mode + * or in behalf of iwlist scan when the card is associated + * and root user ask for a scan. + * the fucntion stop_scan should stop both the syncro and + * background scanning and can sleep. + * The fucntion start_scan should initiate the background + * scanning and can't sleep. + */ + void (*scan_syncro)(struct net_device *dev); + void (*start_scan)(struct net_device *dev); + void (*stop_scan)(struct net_device *dev); + + /* indicate the driver that the link state is changed + * for example it may indicate the card is associated now. + * Driver might be interested in this to apply RX filter + * rules or simply light the LINK led + */ + void (*link_change)(struct net_device *dev); + + /* these two function indicates to the HW when to start + * and stop to send beacons. This is used when the + * IEEE_SOFTMAC_BEACONS is not set. For now the + * stop_send_bacons is NOT guaranteed to be called only + * after start_send_beacons. + */ + void (*start_send_beacons) (struct net_device *dev,u16 tx_rate); + void (*stop_send_beacons) (struct net_device *dev); + + /* power save mode related */ + void (*sta_wake_up) (struct net_device *dev); +// void (*ps_request_tx_ack) (struct net_device *dev); + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); + short (*ps_is_queue_empty) (struct net_device *dev); +#if 0 + /* Typical STA methods */ + int (*handle_auth) (struct net_device * dev, + struct ieee80211_auth * auth); + int (*handle_deauth) (struct net_device * dev, + struct ieee80211_deauth * auth); + int (*handle_action) (struct net_device * dev, + struct ieee80211_action * action, + struct ieee80211_rx_stats * stats); + int (*handle_disassoc) (struct net_device * dev, + struct ieee80211_disassoc * assoc); +#endif + int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); +#if 0 + int (*handle_probe_response) (struct net_device * dev, + struct ieee80211_probe_response * resp, + struct ieee80211_network * network); + int (*handle_probe_request) (struct net_device * dev, + struct ieee80211_probe_request * req, + struct ieee80211_rx_stats * stats); +#endif + int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); + +#if 0 + /* Typical AP methods */ + int (*handle_assoc_request) (struct net_device * dev); + int (*handle_reassoc_request) (struct net_device * dev, + struct ieee80211_reassoc_request * req); +#endif + + /* check whether Tx hw resouce available */ + short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); + //added by wb for HT related +// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); + void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); + bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); + void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); + bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); + void (*InitialGainHandler)(struct net_device *dev, u8 Operation); + + /* This must be the last item so that it points to the data + * allocated beyond this structure by alloc_ieee80211 */ + u8 priv[0]; +}; + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_N_24G (1<<4) +#define IEEE_N_5G (1<<5) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +/* Generate a 802.11 header */ + +/* Uses the channel change callback directly + * instead of [start/stop] scan callbacks + */ +#define IEEE_SOFTMAC_SCAN (1<<2) + +/* Perform authentication and association handshake */ +#define IEEE_SOFTMAC_ASSOCIATE (1<<3) + +/* Generate probe requests */ +#define IEEE_SOFTMAC_PROBERQ (1<<4) + +/* Generate respones to probe requests */ +#define IEEE_SOFTMAC_PROBERS (1<<5) + +/* The ieee802.11 stack will manages the netif queue + * wake/stop for the driver, taking care of 802.11 + * fragmentation. See softmac.c for details. */ +#define IEEE_SOFTMAC_TX_QUEUE (1<<7) + +/* Uses only the softmac_data_hard_start_xmit + * even for TX management frames. + */ +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) + +/* Generate beacons. The stack will enqueue beacons + * to the card + */ +#define IEEE_SOFTMAC_BEACONS (1<<6) + +static inline void *ieee80211_priv(struct net_device *dev) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + return ((struct ieee80211_device *)netdev_priv(dev))->priv; +#else + return ((struct ieee80211_device *)dev->priv)->priv; +#endif +} + +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +{ + /* + * It is possible for both access points and our device to support + * combinations of modes, so as long as there is one valid combination + * of ap/device supported modes, then return success + * + */ + if ((mode & IEEE_A) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_52GHZ_BAND)) + return 1; + + if ((mode & IEEE_G) && + (ieee->modulation & IEEE80211_OFDM_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + if ((mode & IEEE_B) && + (ieee->modulation & IEEE80211_CCK_MODULATION) && + (ieee->freq_band & IEEE80211_24GHZ_BAND)) + return 1; + + return 0; +} + +extern inline int ieee80211_get_hdrlen(u16 fc) +{ + int hdrlen = IEEE80211_3ADDR_LEN; + + switch (WLAN_FC_GET_TYPE(fc)) { + case IEEE80211_FTYPE_DATA: + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) + hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ + if(IEEE80211_QOS_HAS_SEQ(fc)) + hdrlen += 2; /* QOS ctrl*/ + break; + case IEEE80211_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case IEEE80211_STYPE_CTS: + case IEEE80211_STYPE_ACK: + hdrlen = IEEE80211_1ADDR_LEN; + break; + default: + hdrlen = IEEE80211_2ADDR_LEN; + break; + } + break; + } + + return hdrlen; +} + +static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) +{ + switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { + case IEEE80211_1ADDR_LEN: + return ((struct ieee80211_hdr_1addr *)hdr)->payload; + case IEEE80211_2ADDR_LEN: + return ((struct ieee80211_hdr_2addr *)hdr)->payload; + case IEEE80211_3ADDR_LEN: + return ((struct ieee80211_hdr_3addr *)hdr)->payload; + case IEEE80211_4ADDR_LEN: + return ((struct ieee80211_hdr_4addr *)hdr)->payload; + } + return NULL; +} + +static inline int ieee80211_is_ofdm_rate(u8 rate) +{ + switch (rate & ~IEEE80211_BASIC_RATE_MASK) { + case IEEE80211_OFDM_RATE_6MB: + case IEEE80211_OFDM_RATE_9MB: + case IEEE80211_OFDM_RATE_12MB: + case IEEE80211_OFDM_RATE_18MB: + case IEEE80211_OFDM_RATE_24MB: + case IEEE80211_OFDM_RATE_36MB: + case IEEE80211_OFDM_RATE_48MB: + case IEEE80211_OFDM_RATE_54MB: + return 1; + } + return 0; +} + +static inline int ieee80211_is_cck_rate(u8 rate) +{ + switch (rate & ~IEEE80211_BASIC_RATE_MASK) { + case IEEE80211_CCK_RATE_1MB: + case IEEE80211_CCK_RATE_2MB: + case IEEE80211_CCK_RATE_5MB: + case IEEE80211_CCK_RATE_11MB: + return 1; + } + return 0; +} + + +/* ieee80211.c */ +extern void free_ieee80211(struct net_device *dev); +extern struct net_device *alloc_ieee80211(int sizeof_priv); + +extern int ieee80211_set_encryption(struct ieee80211_device *ieee); + +/* ieee80211_tx.c */ + +extern int ieee80211_encrypt_fragment( + struct ieee80211_device *ieee, + struct sk_buff *frag, + int hdr_len); + +extern int ieee80211_xmit(struct sk_buff *skb, + struct net_device *dev); +extern void ieee80211_txb_free(struct ieee80211_txb *); + + +/* ieee80211_rx.c */ +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats); +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *header, + struct ieee80211_rx_stats *stats); + +/* ieee80211_wx.c */ +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +#if WIRELESS_EXT >= 18 +extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data* wrqu, char *extra); +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data* wrqu, char *extra); +extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra); +extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +#endif +extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); + +/* ieee80211_softmac.c */ +extern short ieee80211_is_54g(struct ieee80211_network net); +extern short ieee80211_is_shortslot(struct ieee80211_network net); +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype); +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); + +void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn); +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); + +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +extern void notify_wx_assoc_event(struct ieee80211_device *ieee); +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); +extern void ieee80211_start_ibss(struct ieee80211_device *ieee); +extern void ieee80211_softmac_init(struct ieee80211_device *ieee); +extern void ieee80211_softmac_free(struct ieee80211_device *ieee); +extern void ieee80211_associate_abort(struct ieee80211_device *ieee); +extern void ieee80211_disassociate(struct ieee80211_device *ieee); +extern void ieee80211_stop_scan(struct ieee80211_device *ieee); +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); +extern void ieee80211_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); +extern void ieee80211_reset_queue(struct ieee80211_device *ieee); +extern void ieee80211_wake_queue(struct ieee80211_device *ieee); +extern void ieee80211_stop_queue(struct ieee80211_device *ieee); +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); +extern void notify_wx_assoc_event(struct ieee80211_device *ieee); +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); + +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); + +/* ieee80211_crypt_ccmp&tkip&wep.c */ +extern void ieee80211_tkip_null(void); +extern void ieee80211_wep_null(void); +extern void ieee80211_ccmp_null(void); + +/* ieee80211_softmac_wx.c */ + +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *ext); + +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra); + +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); + +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); +#else + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); +#endif + + +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +//HT +#define MAX_RECEIVE_BUFFER_SIZE 9100 // +extern void HTDebugHTCapability(u8* CapIE, u8* TitleString ); +extern void HTDebugHTInfo(u8* InfoIE, u8* TitleString); + +void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee); +extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt); +extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt); +extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len); +extern void HTOnAssocRsp(struct ieee80211_device *ieee); +extern void HTInitializeHTInfo(struct ieee80211_device* ieee); +extern void HTInitializeBssDesc(PBSS_HT pBssHT); +extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); +extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); +extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter); +extern u8 MCS_FILTER_ALL[]; +extern u16 MCS_DATA_RATE[2][2][77] ; +extern u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame); +//extern void HTSetConnectBwModeCallback(unsigned long data); +extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); +extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee); +extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate); +extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate); +extern u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate); +//function in BAPROC.c +extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb); +extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb); +extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb); +extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); +extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); +extern void BaSetupTimeOut(unsigned long data); +extern void TxBaInactTimeout(unsigned long data); +extern void RxBaInactTimeout(unsigned long data); +extern void ResetBaEntry( PBA_RECORD pBA); +//function in TS.c +extern bool GetTs( + struct ieee80211_device* ieee, + PTS_COMMON_INFO *ppTS, + u8* Addr, + u8 TID, + TR_SELECT TxRxSelect, //Rx:1, Tx:0 + bool bAddNewTs + ); +extern void TSInitialize(struct ieee80211_device *ieee); +extern void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS); +extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr); +extern void RemoveAllTS(struct ieee80211_device* ieee); +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); + +extern const long ieee80211_wlan_frequencies[]; + +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +{ + ieee->scans++; +} + +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +{ + return ieee->scans; +} + +static inline const char *escape_essid(const char *essid, u8 essid_len) { + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (ieee80211_is_empty_essid(essid, essid_len)) { + memcpy(escaped, "", sizeof("")); + return escaped; + } + + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +/* For the function is more related to hardware setting, it's better to use the + * ieee handler to refer to it. + */ +extern short check_nic_enough_desc(struct net_device *dev, int queue_index); +extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); +extern int ieee80211_parse_info_param(struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + u16 length, + struct ieee80211_network *network, + struct ieee80211_rx_stats *stats); + +void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); +#define RT_ASOC_RETRY_LIMIT 5 +#endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c new file mode 100644 index 00000000000..1a8ea8a40c3 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c @@ -0,0 +1,273 @@ +/* + * Host AP crypto routines + * + * Copyright (c) 2002-2003, Jouni Malinen + * Portions Copyright (C) 2004, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + * + */ + +//#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +//MODULE_AUTHOR("Jouni Malinen"); +//MODULE_DESCRIPTION("HostAP crypto"); +//MODULE_LICENSE("GPL"); + +struct ieee80211_crypto_alg { + struct list_head list; + struct ieee80211_crypto_ops *ops; +}; + + +struct ieee80211_crypto { + struct list_head algs; + spinlock_t lock; +}; + +static struct ieee80211_crypto *hcrypt; + +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, + int force) +{ + struct list_head *ptr, *n; + struct ieee80211_crypt_data *entry; + + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { + entry = list_entry(ptr, struct ieee80211_crypt_data, list); + + if (atomic_read(&entry->refcnt) != 0 && !force) + continue; + + list_del(ptr); + + if (entry->ops) { + entry->ops->deinit(entry->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(entry->ops->owner); +#else + __MOD_DEC_USE_COUNT(entry->ops->owner); +#endif + } + kfree(entry); + } +} + +void ieee80211_crypt_deinit_handler(unsigned long data) +{ + struct ieee80211_device *ieee = (struct ieee80211_device *)data; + unsigned long flags; + + spin_lock_irqsave(&ieee->lock, flags); + ieee80211_crypt_deinit_entries(ieee, 0); + if (!list_empty(&ieee->crypt_deinit_list)) { + printk(KERN_DEBUG "%s: entries remaining in delayed crypt " + "deletion list\n", ieee->dev->name); + ieee->crypt_deinit_timer.expires = jiffies + HZ; + add_timer(&ieee->crypt_deinit_timer); + } + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, + struct ieee80211_crypt_data **crypt) +{ + struct ieee80211_crypt_data *tmp; + unsigned long flags; + + if (*crypt == NULL) + return; + + tmp = *crypt; + *crypt = NULL; + + /* must not run ops->deinit() while there may be pending encrypt or + * decrypt operations. Use a list of delayed deinits to avoid needing + * locking. */ + + spin_lock_irqsave(&ieee->lock, flags); + list_add(&tmp->list, &ieee->crypt_deinit_list); + if (!timer_pending(&ieee->crypt_deinit_timer)) { + ieee->crypt_deinit_timer.expires = jiffies + HZ; + add_timer(&ieee->crypt_deinit_timer); + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) +{ + unsigned long flags; + struct ieee80211_crypto_alg *alg; + + if (hcrypt == NULL) + return -1; + + alg = kmalloc(sizeof(*alg), GFP_KERNEL); + if (alg == NULL) + return -ENOMEM; + + memset(alg, 0, sizeof(*alg)); + alg->ops = ops; + + spin_lock_irqsave(&hcrypt->lock, flags); + list_add(&alg->list, &hcrypt->algs); + spin_unlock_irqrestore(&hcrypt->lock, flags); + + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", + ops->name); + + return 0; +} + +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) +{ + unsigned long flags; + struct list_head *ptr; + struct ieee80211_crypto_alg *del_alg = NULL; + + if (hcrypt == NULL) + return -1; + + spin_lock_irqsave(&hcrypt->lock, flags); + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + if (alg->ops == ops) { + list_del(&alg->list); + del_alg = alg; + break; + } + } + spin_unlock_irqrestore(&hcrypt->lock, flags); + + if (del_alg) { + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + "'%s'\n", ops->name); + kfree(del_alg); + } + + return del_alg ? 0 : -1; +} + + +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) +{ + unsigned long flags; + struct list_head *ptr; + struct ieee80211_crypto_alg *found_alg = NULL; + + if (hcrypt == NULL) + return NULL; + + spin_lock_irqsave(&hcrypt->lock, flags); + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + if (strcmp(alg->ops->name, name) == 0) { + found_alg = alg; + break; + } + } + spin_unlock_irqrestore(&hcrypt->lock, flags); + + if (found_alg) + return found_alg->ops; + else + return NULL; +} + + +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } +static void ieee80211_crypt_null_deinit(void *priv) {} + +static struct ieee80211_crypto_ops ieee80211_crypt_null = { + .name = "NULL", + .init = ieee80211_crypt_null_init, + .deinit = ieee80211_crypt_null_deinit, + .encrypt_mpdu = NULL, + .decrypt_mpdu = NULL, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = NULL, + .get_key = NULL, + .extra_prefix_len = 0, + .extra_postfix_len = 0, + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_init(void) +{ + int ret = -ENOMEM; + + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + if (!hcrypt) + goto out; + + memset(hcrypt, 0, sizeof(*hcrypt)); + INIT_LIST_HEAD(&hcrypt->algs); + spin_lock_init(&hcrypt->lock); + + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); + if (ret < 0) { + kfree(hcrypt); + hcrypt = NULL; + } +out: + return ret; +} + + +void __exit ieee80211_crypto_deinit(void) +{ + struct list_head *ptr, *n; + + if (hcrypt == NULL) + return; + + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; + ptr = n, n = ptr->next) { + struct ieee80211_crypto_alg *alg = + (struct ieee80211_crypto_alg *) ptr; + list_del(ptr); + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + "'%s' (deinit)\n", alg->ops->name); + kfree(alg); + } + + kfree(hcrypt); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); +//EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); +//EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); + +//EXPORT_SYMBOL(ieee80211_register_crypto_ops); +//EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); +//EXPORT_SYMBOL(ieee80211_get_crypto_ops); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries); +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler); +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit); + +EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops); +EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops); +EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops); +#endif + +//module_init(ieee80211_crypto_init); +//module_exit(ieee80211_crypto_deinit); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h new file mode 100644 index 00000000000..a84df4b7648 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h @@ -0,0 +1,93 @@ +/* + * Original code based on Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * + * Copyright (c) 2004, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +/* + * This file defines the interface to the ieee80211 crypto module. + */ +#ifndef IEEE80211_CRYPT_H +#define IEEE80211_CRYPT_H + +#include + +struct ieee80211_crypto_ops { + const char *name; + + /* init new crypto context (e.g., allocate private data space, + * select IV, etc.); returns NULL on failure or pointer to allocated + * private data on success */ + void * (*init)(int keyidx); + + /* deinitialize crypto context and free allocated private data */ + void (*deinit)(void *priv); + + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return + * value from decrypt_mpdu is passed as the keyidx value for + * decrypt_msdu. skb must have enough head and tail room for the + * encryption; if not, error will be returned; these functions are + * called for all MPDUs (i.e., fragments). + */ + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + + /* These functions are called for full MSDUs, i.e. full frames. + * These can be NULL if full MSDU operations are not needed. */ + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, + void *priv); + + int (*set_key)(void *key, int len, u8 *seq, void *priv); + int (*get_key)(void *key, int len, u8 *seq, void *priv); + + /* procfs handler for printing out key information and possible + * statistics */ + char * (*print_stats)(char *p, void *priv); + + /* maximum number of bytes added by encryption; encrypt buf is + * allocated with extra_prefix_len bytes, copy of in_buf, and + * extra_postfix_len; encrypt need not use all this space, but + * the result must start at the beginning of the buffer and correct + * length must be returned */ + int extra_prefix_len, extra_postfix_len; + + struct module *owner; +}; + +struct ieee80211_crypt_data { + struct list_head list; /* delayed deletion list */ + struct ieee80211_crypto_ops *ops; + void *priv; + atomic_t refcnt; +}; + +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); +void ieee80211_crypt_deinit_handler(unsigned long); +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, + struct ieee80211_crypt_data **crypt); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31)) +#define crypto_alloc_tfm crypto_alloc_tfm_rsl +#define crypto_free_tfm crypto_free_tfm_rsl +#endif + +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c new file mode 100644 index 00000000000..ab871b360b5 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c @@ -0,0 +1,534 @@ +/* + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver + * + * Copyright (c) 2003-2004, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif +//#include + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: CCMP"); +MODULE_LICENSE("GPL"); + +#ifndef OPENSUSE_SLED +#define OPENSUSE_SLED 0 +#endif + +#define AES_BLOCK_LEN 16 +#define CCMP_HDR_LEN 8 +#define CCMP_MIC_LEN 8 +#define CCMP_TK_LEN 16 +#define CCMP_PN_LEN 6 + +struct ieee80211_ccmp_data { + u8 key[CCMP_TK_LEN]; + int key_set; + + u8 tx_pn[CCMP_PN_LEN]; + u8 rx_pn[CCMP_PN_LEN]; + + u32 dot11RSNAStatsCCMPFormatErrors; + u32 dot11RSNAStatsCCMPReplays; + u32 dot11RSNAStatsCCMPDecryptErrors; + + int key_idx; + + struct crypto_tfm *tfm; + + /* scratch buffers for virt_to_page() (crypto API) */ + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; +}; + +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, + const u8 pt[16], u8 ct[16]) +{ +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + struct scatterlist src, dst; + + src.page = virt_to_page(pt); + src.offset = offset_in_page(pt); + src.length = AES_BLOCK_LEN; + + dst.page = virt_to_page(ct); + dst.offset = offset_in_page(ct); + dst.length = AES_BLOCK_LEN; + + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); +#else + crypto_cipher_encrypt_one((void*)tfm, ct, pt); +#endif +} + +static void * ieee80211_ccmp_init(int key_idx) +{ + struct ieee80211_ccmp_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = key_idx; + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + priv->tfm = crypto_alloc_tfm("aes", 0); + if (priv->tfm == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " + "crypto API aes\n"); + goto fail; + } + #else + priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " + "crypto API aes\n"); + priv->tfm = NULL; + goto fail; + } + #endif + return priv; + +fail: + if (priv) { + if (priv->tfm) + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_free_tfm(priv->tfm); + #else + crypto_free_cipher((void*)priv->tfm); + #endif + kfree(priv); + } + + return NULL; +} + + +static void ieee80211_ccmp_deinit(void *priv) +{ + struct ieee80211_ccmp_data *_priv = priv; + if (_priv && _priv->tfm) +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + crypto_free_tfm(_priv->tfm); +#else + crypto_free_cipher((void*)_priv->tfm); +#endif + kfree(priv); +} + + +static inline void xor_block(u8 *b, u8 *a, size_t len) +{ + int i; + for (i = 0; i < len; i++) + b[i] ^= a[i]; +} + + + +static void ccmp_init_blocks(struct crypto_tfm *tfm, + struct ieee80211_hdr_4addr *hdr, + u8 *pn, size_t dlen, u8 *b0, u8 *auth, + u8 *s0) +{ + u8 *pos, qc = 0; + size_t aad_len; + u16 fc; + int a4_included, qc_included; + u8 aad[2 * AES_BLOCK_LEN]; + + fc = le16_to_cpu(hdr->frame_ctl); + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); + /* + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + (WLAN_FC_GET_STYPE(fc) & 0x08)); + */ + // fixed by David :2006.9.6 + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + (WLAN_FC_GET_STYPE(fc) & 0x80)); + aad_len = 22; + if (a4_included) + aad_len += 6; + if (qc_included) { + pos = (u8 *) &hdr->addr4; + if (a4_included) + pos += 6; + qc = *pos & 0x0f; + aad_len += 2; + } + /* CCM Initial Block: + * Flag (Include authentication header, M=3 (8-octet MIC), + * L=1 (2-octet Dlen)) + * Nonce: 0x00 | A2 | PN + * Dlen */ + b0[0] = 0x59; + b0[1] = qc; + memcpy(b0 + 2, hdr->addr2, ETH_ALEN); + memcpy(b0 + 8, pn, CCMP_PN_LEN); + b0[14] = (dlen >> 8) & 0xff; + b0[15] = dlen & 0xff; + + /* AAD: + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one + * A1 | A2 | A3 + * SC with bits 4..15 (seq#) masked to zero + * A4 (if present) + * QC (if present) + */ + pos = (u8 *) hdr; + aad[0] = 0; /* aad_len >> 8 */ + aad[1] = aad_len & 0xff; + aad[2] = pos[0] & 0x8f; + aad[3] = pos[1] & 0xc7; + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); + pos = (u8 *) &hdr->seq_ctl; + aad[22] = pos[0] & 0x0f; + aad[23] = 0; /* all bits masked */ + memset(aad + 24, 0, 8); + if (a4_included) + memcpy(aad + 24, hdr->addr4, ETH_ALEN); + if (qc_included) { + aad[a4_included ? 30 : 24] = qc; + /* rest of QC masked */ + } + + /* Start with the first block and AAD */ + ieee80211_ccmp_aes_encrypt(tfm, b0, auth); + xor_block(auth, aad, AES_BLOCK_LEN); + ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); + ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + b0[0] &= 0x07; + b0[14] = b0[15] = 0; + ieee80211_ccmp_aes_encrypt(tfm, b0, s0); +} + + + +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_ccmp_data *key = priv; + int data_len, i; + u8 *pos; + struct ieee80211_hdr_4addr *hdr; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + + if (skb_headroom(skb) < CCMP_HDR_LEN || + skb_tailroom(skb) < CCMP_MIC_LEN || + skb->len < hdr_len) + return -1; + + data_len = skb->len - hdr_len; + pos = skb_push(skb, CCMP_HDR_LEN); + memmove(pos, pos + CCMP_HDR_LEN, hdr_len); + pos += hdr_len; +// mic = skb_put(skb, CCMP_MIC_LEN); + + i = CCMP_PN_LEN - 1; + while (i >= 0) { + key->tx_pn[i]++; + if (key->tx_pn[i] != 0) + break; + i--; + } + + *pos++ = key->tx_pn[5]; + *pos++ = key->tx_pn[4]; + *pos++ = 0; + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; + *pos++ = key->tx_pn[3]; + *pos++ = key->tx_pn[2]; + *pos++ = key->tx_pn[1]; + *pos++ = key->tx_pn[0]; + + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + if (!tcb_desc->bHwSec) + { + int blocks, last, len; + u8 *mic; + u8 *b0 = key->tx_b0; + u8 *b = key->tx_b; + u8 *e = key->tx_e; + u8 *s0 = key->tx_s0; + + //mic is moved to here by john + mic = skb_put(skb, CCMP_MIC_LEN); + + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); + + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + last = data_len % AES_BLOCK_LEN; + + for (i = 1; i <= blocks; i++) { + len = (i == blocks && last) ? last : AES_BLOCK_LEN; + /* Authentication */ + xor_block(b, pos, len); + ieee80211_ccmp_aes_encrypt(key->tfm, b, b); + /* Encryption, with counter */ + b0[14] = (i >> 8) & 0xff; + b0[15] = i & 0xff; + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); + xor_block(pos, e, len); + pos += len; + } + + for (i = 0; i < CCMP_MIC_LEN; i++) + mic[i] = b[i] ^ s0[i]; + } + return 0; +} + + +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_ccmp_data *key = priv; + u8 keyidx, *pos; + struct ieee80211_hdr_4addr *hdr; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + u8 pn[6]; + + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { + key->dot11RSNAStatsCCMPFormatErrors++; + return -1; + } + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + pos = skb->data + hdr_len; + keyidx = pos[3]; + if (!(keyidx & (1 << 5))) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet without ExtIV" + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + key->dot11RSNAStatsCCMPFormatErrors++; + return -2; + } + keyidx >>= 6; + if (key->key_idx != keyidx) { + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); + return -6; + } + if (!key->key_set) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + " with keyid=%d that does not have a configured" + " key\n", MAC_ARG(hdr->addr2), keyidx); + } + return -3; + } + + pn[0] = pos[7]; + pn[1] = pos[6]; + pn[2] = pos[5]; + pn[3] = pos[4]; + pn[4] = pos[1]; + pn[5] = pos[0]; + pos += 8; + + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT + " previous PN %02x%02x%02x%02x%02x%02x " + "received PN %02x%02x%02x%02x%02x%02x\n", + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), + MAC_ARG(pn)); + } + key->dot11RSNAStatsCCMPReplays++; + return -4; + } + if (!tcb_desc->bHwSec) + { + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; + u8 *b0 = key->rx_b0; + u8 *b = key->rx_b; + u8 *a = key->rx_a; + int i, blocks, last, len; + + + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); + xor_block(mic, b, CCMP_MIC_LEN); + + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + last = data_len % AES_BLOCK_LEN; + + for (i = 1; i <= blocks; i++) { + len = (i == blocks && last) ? last : AES_BLOCK_LEN; + /* Decrypt, with counter */ + b0[14] = (i >> 8) & 0xff; + b0[15] = i & 0xff; + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); + xor_block(pos, b, len); + /* Authentication */ + xor_block(a, pos, len); + ieee80211_ccmp_aes_encrypt(key->tfm, a, a); + pos += len; + } + + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: decrypt failed: STA=" + MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + key->dot11RSNAStatsCCMPDecryptErrors++; + return -5; + } + + memcpy(key->rx_pn, pn, CCMP_PN_LEN); + } + /* Remove hdr and MIC */ + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); + skb_pull(skb, CCMP_HDR_LEN); + skb_trim(skb, skb->len - CCMP_MIC_LEN); + + return keyidx; +} + + +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_ccmp_data *data = priv; + int keyidx; + struct crypto_tfm *tfm = data->tfm; + + keyidx = data->key_idx; + memset(data, 0, sizeof(*data)); + data->key_idx = keyidx; + data->tfm = tfm; + if (len == CCMP_TK_LEN) { + memcpy(data->key, key, CCMP_TK_LEN); + data->key_set = 1; + if (seq) { + data->rx_pn[0] = seq[5]; + data->rx_pn[1] = seq[4]; + data->rx_pn[2] = seq[3]; + data->rx_pn[3] = seq[2]; + data->rx_pn[4] = seq[1]; + data->rx_pn[5] = seq[0]; + } + crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN); + } else if (len == 0) + data->key_set = 0; + else + return -1; + + return 0; +} + + +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_ccmp_data *data = priv; + + if (len < CCMP_TK_LEN) + return -1; + + if (!data->key_set) + return 0; + memcpy(key, data->key, CCMP_TK_LEN); + + if (seq) { + seq[0] = data->tx_pn[5]; + seq[1] = data->tx_pn[4]; + seq[2] = data->tx_pn[3]; + seq[3] = data->tx_pn[2]; + seq[4] = data->tx_pn[1]; + seq[5] = data->tx_pn[0]; + } + + return CCMP_TK_LEN; +} + + +static char * ieee80211_ccmp_print_stats(char *p, void *priv) +{ + struct ieee80211_ccmp_data *ccmp = priv; + p += sprintf(p, "key[%d] alg=CCMP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "format_errors=%d replays=%d decrypt_errors=%d\n", + ccmp->key_idx, ccmp->key_set, + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->dot11RSNAStatsCCMPFormatErrors, + ccmp->dot11RSNAStatsCCMPReplays, + ccmp->dot11RSNAStatsCCMPDecryptErrors); + + return p; +} + +void ieee80211_ccmp_null(void) +{ +// printk("============>%s()\n", __FUNCTION__); + return; +} + +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { + .name = "CCMP", + .init = ieee80211_ccmp_init, + .deinit = ieee80211_ccmp_deinit, + .encrypt_mpdu = ieee80211_ccmp_encrypt, + .decrypt_mpdu = ieee80211_ccmp_decrypt, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = ieee80211_ccmp_set_key, + .get_key = ieee80211_ccmp_get_key, + .print_stats = ieee80211_ccmp_print_stats, + .extra_prefix_len = CCMP_HDR_LEN, + .extra_postfix_len = CCMP_MIC_LEN, + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_ccmp_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); +} + + +void __exit ieee80211_crypto_ccmp_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_ccmp_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null); +#endif + +//module_init(ieee80211_crypto_ccmp_init); +//module_exit(ieee80211_crypto_ccmp_exit); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c new file mode 100644 index 00000000000..a9eddeb66b2 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -0,0 +1,1034 @@ +/* + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver + * + * Copyright (c) 2003-2004, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) +//#include "crypto_compat.h" +#endif + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif +//#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif + +#include + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: TKIP"); +MODULE_LICENSE("GPL"); + +#ifndef OPENSUSE_SLED +#define OPENSUSE_SLED 0 +#endif + +struct ieee80211_tkip_data { +#define TKIP_KEY_LEN 32 + u8 key[TKIP_KEY_LEN]; + int key_set; + + u32 tx_iv32; + u16 tx_iv16; + u16 tx_ttak[5]; + int tx_phase1_done; + + u32 rx_iv32; + u16 rx_iv16; + u16 rx_ttak[5]; + int rx_phase1_done; + u32 rx_iv32_new; + u16 rx_iv16_new; + + u32 dot11RSNAStatsTKIPReplays; + u32 dot11RSNAStatsTKIPICVErrors; + u32 dot11RSNAStatsTKIPLocalMICFailures; + + int key_idx; +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) + struct crypto_blkcipher *rx_tfm_arc4; + struct crypto_hash *rx_tfm_michael; + struct crypto_blkcipher *tx_tfm_arc4; + struct crypto_hash *tx_tfm_michael; +#else + struct crypto_tfm *tx_tfm_arc4; + struct crypto_tfm *tx_tfm_michael; + struct crypto_tfm *rx_tfm_arc4; + struct crypto_tfm *rx_tfm_michael; +#endif + /* scratch buffers for virt_to_page() (crypto API) */ + u8 rx_hdr[16], tx_hdr[16]; +}; + +static void * ieee80211_tkip_init(int key_idx) +{ + struct ieee80211_tkip_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = key_idx; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0); + if (priv->tx_tfm_arc4 == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + goto fail; + } + + priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0); + if (priv->tx_tfm_michael == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + goto fail; + } + + priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0); + if (priv->rx_tfm_arc4 == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + goto fail; + } + + priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0); + if (priv->rx_tfm_michael == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + goto fail; + } +#else + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm_arc4)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + priv->tx_tfm_arc4 = NULL; + goto fail; + } + + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm_michael)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + priv->tx_tfm_michael = NULL; + goto fail; + } + + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm_arc4)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API arc4\n"); + priv->rx_tfm_arc4 = NULL; + goto fail; + } + + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm_michael)) { + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + "crypto API michael_mic\n"); + priv->rx_tfm_michael = NULL; + goto fail; + } +#endif + return priv; + +fail: + if (priv) { +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (priv->tx_tfm_michael) + crypto_free_tfm(priv->tx_tfm_michael); + if (priv->tx_tfm_arc4) + crypto_free_tfm(priv->tx_tfm_arc4); + if (priv->rx_tfm_michael) + crypto_free_tfm(priv->rx_tfm_michael); + if (priv->rx_tfm_arc4) + crypto_free_tfm(priv->rx_tfm_arc4); + +#else + if (priv->tx_tfm_michael) + crypto_free_hash(priv->tx_tfm_michael); + if (priv->tx_tfm_arc4) + crypto_free_blkcipher(priv->tx_tfm_arc4); + if (priv->rx_tfm_michael) + crypto_free_hash(priv->rx_tfm_michael); + if (priv->rx_tfm_arc4) + crypto_free_blkcipher(priv->rx_tfm_arc4); +#endif + kfree(priv); + } + + return NULL; +} + + +static void ieee80211_tkip_deinit(void *priv) +{ + struct ieee80211_tkip_data *_priv = priv; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (_priv->tx_tfm_michael) + crypto_free_tfm(_priv->tx_tfm_michael); + if (_priv->tx_tfm_arc4) + crypto_free_tfm(_priv->tx_tfm_arc4); + if (_priv->rx_tfm_michael) + crypto_free_tfm(_priv->rx_tfm_michael); + if (_priv->rx_tfm_arc4) + crypto_free_tfm(_priv->rx_tfm_arc4); +#else + if (_priv) { + if (_priv->tx_tfm_michael) + crypto_free_hash(_priv->tx_tfm_michael); + if (_priv->tx_tfm_arc4) + crypto_free_blkcipher(_priv->tx_tfm_arc4); + if (_priv->rx_tfm_michael) + crypto_free_hash(_priv->rx_tfm_michael); + if (_priv->rx_tfm_arc4) + crypto_free_blkcipher(_priv->rx_tfm_arc4); + } +#endif + kfree(priv); +} + + +static inline u16 RotR1(u16 val) +{ + return (val >> 1) | (val << 15); +} + + +static inline u8 Lo8(u16 val) +{ + return val & 0xff; +} + + +static inline u8 Hi8(u16 val) +{ + return val >> 8; +} + + +static inline u16 Lo16(u32 val) +{ + return val & 0xffff; +} + + +static inline u16 Hi16(u32 val) +{ + return val >> 16; +} + + +static inline u16 Mk16(u8 hi, u8 lo) +{ + return lo | (((u16) hi) << 8); +} + + +static inline u16 Mk16_le(u16 *v) +{ + return le16_to_cpu(*v); +} + + +static const u16 Sbox[256] = +{ + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, +}; + + +static inline u16 _S_(u16 v) +{ + u16 t = Sbox[Hi8(v)]; + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); +} + + +#define PHASE1_LOOP_COUNT 8 + + +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) +{ + int i, j; + + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ + TTAK[0] = Lo16(IV32); + TTAK[1] = Hi16(IV32); + TTAK[2] = Mk16(TA[1], TA[0]); + TTAK[3] = Mk16(TA[3], TA[2]); + TTAK[4] = Mk16(TA[5], TA[4]); + + for (i = 0; i < PHASE1_LOOP_COUNT; i++) { + j = 2 * (i & 1); + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; + } +} + + +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, + u16 IV16) +{ + /* Make temporary area overlap WEP seed so that the final copy can be + * avoided on little endian hosts. */ + u16 *PPK = (u16 *) &WEPSeed[4]; + + /* Step 1 - make copy of TTAK and bring in TSC */ + PPK[0] = TTAK[0]; + PPK[1] = TTAK[1]; + PPK[2] = TTAK[2]; + PPK[3] = TTAK[3]; + PPK[4] = TTAK[4]; + PPK[5] = TTAK[4] + IV16; + + /* Step 2 - 96-bit bijective mixing using S-box */ + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); + + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); + PPK[2] += RotR1(PPK[1]); + PPK[3] += RotR1(PPK[2]); + PPK[4] += RotR1(PPK[3]); + PPK[5] += RotR1(PPK[4]); + + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value + * WEPSeed[0..2] is transmitted as WEP IV */ + WEPSeed[0] = Hi8(IV16); + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; + WEPSeed[2] = Lo8(IV16); + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); + +#ifdef __BIG_ENDIAN + { + int i; + for (i = 0; i < 6; i++) + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); + } +#endif +} + + +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + int len; + u8 *pos; + struct ieee80211_hdr_4addr *hdr; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; + int ret = 0; + #endif + u8 rc4key[16], *icv; + u32 crc; + struct scatterlist sg; + + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || + skb->len < hdr_len) + return -1; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + +#if 0 +printk("@@ tkey\n"); +printk("%x|", ((u32*)tkey->key)[0]); +printk("%x|", ((u32*)tkey->key)[1]); +printk("%x|", ((u32*)tkey->key)[2]); +printk("%x|", ((u32*)tkey->key)[3]); +printk("%x|", ((u32*)tkey->key)[4]); +printk("%x|", ((u32*)tkey->key)[5]); +printk("%x|", ((u32*)tkey->key)[6]); +printk("%x\n", ((u32*)tkey->key)[7]); +#endif + + if (!tcb_desc->bHwSec) + { + if (!tkey->tx_phase1_done) { + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, + tkey->tx_iv32); + tkey->tx_phase1_done = 1; + } + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); + } + else + tkey->tx_phase1_done = 1; + + + len = skb->len - hdr_len; + pos = skb_push(skb, 8); + memmove(pos, pos + 8, hdr_len); + pos += hdr_len; + + if (tcb_desc->bHwSec) + { + *pos++ = Hi8(tkey->tx_iv16); + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F; + *pos++ = Lo8(tkey->tx_iv16); + } + else + { + *pos++ = rc4key[0]; + *pos++ = rc4key[1]; + *pos++ = rc4key[2]; + } + + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; + *pos++ = tkey->tx_iv32 & 0xff; + *pos++ = (tkey->tx_iv32 >> 8) & 0xff; + *pos++ = (tkey->tx_iv32 >> 16) & 0xff; + *pos++ = (tkey->tx_iv32 >> 24) & 0xff; + + if (!tcb_desc->bHwSec) + { + icv = skb_put(skb, 4); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, len); +#else + crc = ~ether_crc_le(len, pos); +#endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4); +#else + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; +#else + sg_init_one(&sg, pos, len+4); +#endif + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); +#endif + + } + + tkey->tx_iv16++; + if (tkey->tx_iv16 == 0) { + tkey->tx_phase1_done = 0; + tkey->tx_iv32++; + } + + if (!tcb_desc->bHwSec) +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + return 0; + #else + return ret; + #endif + else + return 0; + + +} + +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + u8 keyidx, *pos; + u32 iv32; + u16 iv16; + struct ieee80211_hdr_4addr *hdr; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4}; + #endif + u8 rc4key[16]; + u8 icv[4]; + u32 crc; + struct scatterlist sg; + int plen; + if (skb->len < hdr_len + 8 + 4) + return -1; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + pos = skb->data + hdr_len; + keyidx = pos[3]; + if (!(keyidx & (1 << 5))) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet without ExtIV" + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + return -2; + } + keyidx >>= 6; + if (tkey->key_idx != keyidx) { + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); + return -6; + } + if (!tkey->key_set) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + " with keyid=%d that does not have a configured" + " key\n", MAC_ARG(hdr->addr2), keyidx); + } + return -3; + } + iv16 = (pos[0] << 8) | pos[2]; + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); + pos += 8; + + if (!tcb_desc->bHwSec) + { + if (iv32 < tkey->rx_iv32 || + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT + " previous TSC %08x%04x received TSC " + "%08x%04x\n", MAC_ARG(hdr->addr2), + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); + } + tkey->dot11RSNAStatsTKIPReplays++; + return -4; + } + + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); + tkey->rx_phase1_done = 1; + } + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); + + plen = skb->len - hdr_len - 12; + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4); +#else + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; +#else + sg_init_one(&sg, pos, plen+4); +#endif + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { + if (net_ratelimit()) { + printk(KERN_DEBUG ": TKIP: failed to decrypt " + "received packet from " MAC_FMT "\n", + MAC_ARG(hdr->addr2)); + } + return -7; + } +#endif + + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, plen); + #else + crc = ~ether_crc_le(plen, pos); + #endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + + if (memcmp(icv, pos + plen, 4) != 0) { + if (iv32 != tkey->rx_iv32) { + /* Previously cached Phase1 result was already lost, so + * it needs to be recalculated for the next packet. */ + tkey->rx_phase1_done = 0; + } + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" + MAC_FMT "\n", MAC_ARG(hdr->addr2)); + } + tkey->dot11RSNAStatsTKIPICVErrors++; + return -5; + } + + } + + /* Update real counters only after Michael MIC verification has + * completed */ + tkey->rx_iv32_new = iv32; + tkey->rx_iv16_new = iv16; + + /* Remove IV and ICV */ + memmove(skb->data + 8, skb->data, hdr_len); + skb_pull(skb, 8); + skb_trim(skb, skb->len - 4); + +//john's test +#ifdef JOHN_DUMP +if( ((u16*)skb->data)[0] & 0x4000){ + printk("@@ rx decrypted skb->data"); + int i; + for(i=0;ilen;i++){ + if( (i%24)==0 ) printk("\n"); + printk("%2x ", ((u8*)skb->data)[i]); + } + printk("\n"); +} +#endif /*JOHN_DUMP*/ + return keyidx; +} + + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) +static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr, + u8 *data, size_t data_len, u8 *mic) +{ + struct scatterlist sg[2]; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct hash_desc desc; + int ret = 0; +#endif + + if (tfm_michael == NULL){ + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } + sg[0].page = virt_to_page(hdr); + sg[0].offset = offset_in_page(hdr); + sg[0].length = 16; + + sg[1].page = virt_to_page(data); + sg[1].offset = offset_in_page(data); + sg[1].length = data_len; + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + crypto_digest_init(tfm_michael); + crypto_digest_setkey(tfm_michael, key, 8); + crypto_digest_update(tfm_michael, sg, 2); + crypto_digest_final(tfm_michael, mic); + return 0; +#else +if (crypto_hash_setkey(tkey->tfm_michael, key, 8)) + return -1; + +// return 0; + desc.tfm = tkey->tfm_michael; + desc.flags = 0; + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic); + return ret; +#endif +} +#else +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, + u8 * data, size_t data_len, u8 * mic) +{ + struct hash_desc desc; + struct scatterlist sg[2]; + + if (tfm_michael == NULL) { + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + sg[0].page = virt_to_page(hdr); + sg[0].offset = offset_in_page(hdr); + sg[0].length = 16; + + sg[1].page = virt_to_page(data); + sg[1].offset = offset_in_page(data); + sg[1].length = data_len; +#else + sg_init_table(sg, 2); + sg_set_buf(&sg[0], hdr, 16); + sg_set_buf(&sg[1], data, data_len); +#endif + + if (crypto_hash_setkey(tfm_michael, key, 8)) + return -1; + + desc.tfm = tfm_michael; + desc.flags = 0; + return crypto_hash_digest(&desc, sg, data_len + 16, mic); +} +#endif + + + +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) +{ + struct ieee80211_hdr_4addr *hdr11; + + hdr11 = (struct ieee80211_hdr_4addr *) skb->data; + switch (le16_to_cpu(hdr11->frame_ctl) & + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_TODS: + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + break; + case IEEE80211_FCTL_FROMDS: + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ + break; + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ + break; + case 0: + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ + break; + } + + hdr[12] = 0; /* priority */ + + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ +} + + +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + u8 *pos; + struct ieee80211_hdr_4addr *hdr; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { + printk(KERN_DEBUG "Invalid packet for Michael MIC add " + "(tailroom=%d hdr_len=%d skb->len=%d)\n", + skb_tailroom(skb), hdr_len, skb->len); + return -1; + } + + michael_mic_hdr(skb, tkey->tx_hdr); + + // { david, 2006.9.1 + // fix the wpa process with wmm enabled. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; + } + // } + pos = skb_put(skb, 8); +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) +#else + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) +#endif + return -1; + + return 0; +} + + +#if WIRELESS_EXT >= 18 +static void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr_4addr *hdr, + int keyidx) +{ + union iwreq_data wrqu; + struct iw_michaelmicfailure ev; + + /* TODO: needed parameters: count, keyid, key type, TSC */ + memset(&ev, 0, sizeof(ev)); + ev.flags = keyidx & IW_MICFAILURE_KEY_ID; + if (hdr->addr1[0] & 0x01) + ev.flags |= IW_MICFAILURE_GROUP; + else + ev.flags |= IW_MICFAILURE_PAIRWISE; + ev.src_addr.sa_family = ARPHRD_ETHER; + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(ev); + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); +} +#elif WIRELESS_EXT >= 15 +static void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr_4addr *hdr, + int keyidx) +{ + union iwreq_data wrqu; + char buf[128]; + + /* TODO: needed parameters: count, keyid, key type, TSC */ + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", + MAC_ARG(hdr->addr2)); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(buf); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); +} +#else /* WIRELESS_EXT >= 15 */ +static inline void ieee80211_michael_mic_failure(struct net_device *dev, + struct ieee80211_hdr_4addr *hdr, + int keyidx) +{ +} +#endif /* WIRELESS_EXT >= 15 */ + +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, + int hdr_len, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + u8 mic[8]; + struct ieee80211_hdr_4addr *hdr; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + + if (!tkey->key_set) + return -1; + + michael_mic_hdr(skb, tkey->rx_hdr); + // { david, 2006.9.1 + // fix the wpa process with wmm enabled. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; + } + // } + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) +#else + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, + skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) +#endif + return -1; + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { + struct ieee80211_hdr_4addr *hdr; + hdr = (struct ieee80211_hdr_4addr *) skb->data; + printk(KERN_DEBUG "%s: Michael MIC verification failed for " + "MSDU from " MAC_FMT " keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + keyidx); + if (skb->dev) + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); + tkey->dot11RSNAStatsTKIPLocalMICFailures++; + return -1; + } + + /* Update TSC counters for RX now that the packet verification has + * completed. */ + tkey->rx_iv32 = tkey->rx_iv32_new; + tkey->rx_iv16 = tkey->rx_iv16_new; + + skb_trim(skb, skb->len - 8); + + return 0; +} + + +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + int keyidx; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + struct crypto_tfm *tfm = tkey->tx_tfm_michael; + struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4; + struct crypto_tfm *tfm3 = tkey->rx_tfm_michael; + struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4; +#else + struct crypto_hash *tfm = tkey->tx_tfm_michael; + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; + struct crypto_hash *tfm3 = tkey->rx_tfm_michael; + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4; +#endif + + keyidx = tkey->key_idx; + memset(tkey, 0, sizeof(*tkey)); + tkey->key_idx = keyidx; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + tkey->tx_tfm_michael = tfm; + tkey->tx_tfm_arc4 = tfm2; + tkey->rx_tfm_michael = tfm3; + tkey->rx_tfm_arc4 = tfm4; +#else + tkey->tx_tfm_michael = tfm; + tkey->tx_tfm_arc4 = tfm2; + tkey->rx_tfm_michael = tfm3; + tkey->rx_tfm_arc4 = tfm4; +#endif + + if (len == TKIP_KEY_LEN) { + memcpy(tkey->key, key, TKIP_KEY_LEN); + tkey->key_set = 1; + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ + if (seq) { + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | + (seq[3] << 8) | seq[2]; + tkey->rx_iv16 = (seq[1] << 8) | seq[0]; + } + } else if (len == 0) + tkey->key_set = 0; + else + return -1; + + return 0; +} + + +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct ieee80211_tkip_data *tkey = priv; + + if (len < TKIP_KEY_LEN) + return -1; + + if (!tkey->key_set) + return 0; + memcpy(key, tkey->key, TKIP_KEY_LEN); + + if (seq) { + /* Return the sequence number of the last transmitted frame. */ + u16 iv16 = tkey->tx_iv16; + u32 iv32 = tkey->tx_iv32; + if (iv16 == 0) + iv32--; + iv16--; + seq[0] = tkey->tx_iv16; + seq[1] = tkey->tx_iv16 >> 8; + seq[2] = tkey->tx_iv32; + seq[3] = tkey->tx_iv32 >> 8; + seq[4] = tkey->tx_iv32 >> 16; + seq[5] = tkey->tx_iv32 >> 24; + } + + return TKIP_KEY_LEN; +} + + +static char * ieee80211_tkip_print_stats(char *p, void *priv) +{ + struct ieee80211_tkip_data *tkip = priv; + p += sprintf(p, "key[%d] alg=TKIP key_set=%d " + "tx_pn=%02x%02x%02x%02x%02x%02x " + "rx_pn=%02x%02x%02x%02x%02x%02x " + "replays=%d icv_errors=%d local_mic_failures=%d\n", + tkip->key_idx, tkip->key_set, + (tkip->tx_iv32 >> 24) & 0xff, + (tkip->tx_iv32 >> 16) & 0xff, + (tkip->tx_iv32 >> 8) & 0xff, + tkip->tx_iv32 & 0xff, + (tkip->tx_iv16 >> 8) & 0xff, + tkip->tx_iv16 & 0xff, + (tkip->rx_iv32 >> 24) & 0xff, + (tkip->rx_iv32 >> 16) & 0xff, + (tkip->rx_iv32 >> 8) & 0xff, + tkip->rx_iv32 & 0xff, + (tkip->rx_iv16 >> 8) & 0xff, + tkip->rx_iv16 & 0xff, + tkip->dot11RSNAStatsTKIPReplays, + tkip->dot11RSNAStatsTKIPICVErrors, + tkip->dot11RSNAStatsTKIPLocalMICFailures); + return p; +} + + +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { + .name = "TKIP", + .init = ieee80211_tkip_init, + .deinit = ieee80211_tkip_deinit, + .encrypt_mpdu = ieee80211_tkip_encrypt, + .decrypt_mpdu = ieee80211_tkip_decrypt, + .encrypt_msdu = ieee80211_michael_mic_add, + .decrypt_msdu = ieee80211_michael_mic_verify, + .set_key = ieee80211_tkip_set_key, + .get_key = ieee80211_tkip_get_key, + .print_stats = ieee80211_tkip_print_stats, + .extra_prefix_len = 4 + 4, /* IV + ExtIV */ + .extra_postfix_len = 8 + 4, /* MIC + ICV */ + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_tkip_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); +} + + +void __exit ieee80211_crypto_tkip_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); +} + +void ieee80211_tkip_null(void) +{ +// printk("============>%s()\n", __FUNCTION__); + return; +} +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_tkip_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null); +#endif + +//module_init(ieee80211_crypto_tkip_init); +//module_exit(ieee80211_crypto_tkip_exit); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c new file mode 100644 index 00000000000..63414355135 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c @@ -0,0 +1,397 @@ +/* + * Host AP crypt: host-based WEP encryption implementation for Host AP driver + * + * Copyright (c) 2002-2004, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +//#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) +//#include "crypto_compat.h" +#endif + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + #include +#else + #include +#endif +//#include +#include +// +/* +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include "rtl_crypto.h" +#else +#include +#endif + +#include +#include +*/ +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Host AP crypt: WEP"); +MODULE_LICENSE("GPL"); +#ifndef OPENSUSE_SLED +#define OPENSUSE_SLED 0 +#endif + +struct prism2_wep_data { + u32 iv; +#define WEP_KEY_LEN 13 + u8 key[WEP_KEY_LEN + 1]; + u8 key_len; + u8 key_idx; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + struct crypto_tfm *tfm; + #else + struct crypto_blkcipher *tx_tfm; + struct crypto_blkcipher *rx_tfm; + #endif +}; + + +static void * prism2_wep_init(int keyidx) +{ + struct prism2_wep_data *priv; + + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + if (priv == NULL) + goto fail; + memset(priv, 0, sizeof(*priv)); + priv->key_idx = keyidx; + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + priv->tfm = crypto_alloc_tfm("arc4", 0); + if (priv->tfm == NULL) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + goto fail; + } + #else + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->tx_tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->tx_tfm = NULL; + goto fail; + } + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm)) { + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->rx_tfm = NULL; + goto fail; + } + #endif + + /* start WEP IV from a random value */ + get_random_bytes(&priv->iv, 4); + + return priv; + +fail: +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (priv) { + if (priv->tfm) + crypto_free_tfm(priv->tfm); + kfree(priv); + } + #else + if (priv) { + if (priv->tx_tfm) + crypto_free_blkcipher(priv->tx_tfm); + if (priv->rx_tfm) + crypto_free_blkcipher(priv->rx_tfm); + kfree(priv); + } + #endif + return NULL; +} + + +static void prism2_wep_deinit(void *priv) +{ + struct prism2_wep_data *_priv = priv; +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + if (_priv && _priv->tfm) + crypto_free_tfm(_priv->tfm); + #else + if (_priv) { + if (_priv->tx_tfm) + crypto_free_blkcipher(_priv->tx_tfm); + if (_priv->rx_tfm) + crypto_free_blkcipher(_priv->rx_tfm); + } + #endif + kfree(priv); +} + +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, + * so the payload length increases with 8 bytes. + * + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) + */ +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct prism2_wep_data *wep = priv; + u32 klen, len; + u8 key[WEP_KEY_LEN + 3]; + u8 *pos; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) + struct blkcipher_desc desc = {.tfm = wep->tx_tfm}; + #endif + u32 crc; + u8 *icv; + struct scatterlist sg; + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || + skb->len < hdr_len) + return -1; + + len = skb->len - hdr_len; + pos = skb_push(skb, 4); + memmove(pos, pos + 4, hdr_len); + pos += hdr_len; + + klen = 3 + wep->key_len; + + wep->iv++; + + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) + * can be used to speedup attacks, so avoid using them. */ + if ((wep->iv & 0xff00) == 0xff00) { + u8 B = (wep->iv >> 16) & 0xff; + if (B >= 3 && B < klen) + wep->iv += 0x0100; + } + + /* Prepend 24-bit IV to RC4 key and TX frame */ + *pos++ = key[0] = (wep->iv >> 16) & 0xff; + *pos++ = key[1] = (wep->iv >> 8) & 0xff; + *pos++ = key[2] = wep->iv & 0xff; + *pos++ = wep->key_idx << 6; + + /* Copy rest of the WEP key (the secret part) */ + memcpy(key + 3, wep->key, wep->key_len); + + if (!tcb_desc->bHwSec) + { + + /* Append little-endian CRC32 and encrypt it to produce ICV */ + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, len); + #else + crc = ~ether_crc_le(len, pos); + #endif + icv = skb_put(skb, 4); + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + crypto_cipher_setkey(wep->tfm, key, klen); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); + return 0; + #else + crypto_blkcipher_setkey(wep->tx_tfm, key, klen); + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = len + 4; + #else + sg_init_one(&sg, pos, len+4); + #endif + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); + #endif + } + + return 0; +} + + +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of + * the frame: IV (4 bytes), encrypted payload (including SNAP header), + * ICV (4 bytes). len includes both IV and ICV. + * + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on + * failure. If frame is OK, IV and ICV will be removed. + */ +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +{ + struct prism2_wep_data *wep = priv; + u32 klen, plen; + u8 key[WEP_KEY_LEN + 3]; + u8 keyidx, *pos; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) + struct blkcipher_desc desc = {.tfm = wep->rx_tfm}; + #endif + u32 crc; + u8 icv[4]; + struct scatterlist sg; + if (skb->len < hdr_len + 8) + return -1; + + pos = skb->data + hdr_len; + key[0] = *pos++; + key[1] = *pos++; + key[2] = *pos++; + keyidx = *pos++ >> 6; + if (keyidx != wep->key_idx) + return -1; + + klen = 3 + wep->key_len; + + /* Copy rest of the WEP key (the secret part) */ + memcpy(key + 3, wep->key, wep->key_len); + + /* Apply RC4 to data and compute CRC32 over decrypted data */ + plen = skb->len - hdr_len - 8; + + if (!tcb_desc->bHwSec) + { +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) + crypto_cipher_setkey(wep->tfm, key, klen); + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); + #else + crypto_blkcipher_setkey(wep->rx_tfm, key, klen); + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + sg.page = virt_to_page(pos); + sg.offset = offset_in_page(pos); + sg.length = plen + 4; + #else + sg_init_one(&sg, pos, plen+4); + #endif + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) + return -7; + #endif + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + crc = ~crc32_le(~0, pos, plen); + #else + crc = ~ether_crc_le(plen, pos); + #endif + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + if (memcmp(icv, pos + plen, 4) != 0) { + /* ICV mismatch - drop frame */ + return -2; + } + } + /* Remove IV and ICV */ + memmove(skb->data + 4, skb->data, hdr_len); + skb_pull(skb, 4); + skb_trim(skb, skb->len - 4); + + return 0; +} + + +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) +{ + struct prism2_wep_data *wep = priv; + + if (len < 0 || len > WEP_KEY_LEN) + return -1; + + memcpy(wep->key, key, len); + wep->key_len = len; + + return 0; +} + + +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) +{ + struct prism2_wep_data *wep = priv; + + if (len < wep->key_len) + return -1; + + memcpy(key, wep->key, wep->key_len); + + return wep->key_len; +} + + +static char * prism2_wep_print_stats(char *p, void *priv) +{ + struct prism2_wep_data *wep = priv; + p += sprintf(p, "key[%d] alg=WEP len=%d\n", + wep->key_idx, wep->key_len); + return p; +} + + +static struct ieee80211_crypto_ops ieee80211_crypt_wep = { + .name = "WEP", + .init = prism2_wep_init, + .deinit = prism2_wep_deinit, + .encrypt_mpdu = prism2_wep_encrypt, + .decrypt_mpdu = prism2_wep_decrypt, + .encrypt_msdu = NULL, + .decrypt_msdu = NULL, + .set_key = prism2_wep_set_key, + .get_key = prism2_wep_get_key, + .print_stats = prism2_wep_print_stats, + .extra_prefix_len = 4, /* IV */ + .extra_postfix_len = 4, /* ICV */ + .owner = THIS_MODULE, +}; + + +int __init ieee80211_crypto_wep_init(void) +{ + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); +} + + +void __exit ieee80211_crypto_wep_exit(void) +{ + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); +} + +void ieee80211_wep_null(void) +{ +// printk("============>%s()\n", __FUNCTION__); + return; +} +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_wep_null); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null); +#endif + +//module_init(ieee80211_crypto_wep_init); +//module_exit(ieee80211_crypto_wep_exit); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c new file mode 100644 index 00000000000..16256a31f99 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -0,0 +1,432 @@ +/******************************************************************************* + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + + Copyright (c) 2002-2003, Jouni Malinen + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + +MODULE_DESCRIPTION("802.11 data/management/control stack"); +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation "); +MODULE_LICENSE("GPL"); + +#define DRV_NAME "ieee80211" + +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) +{ + if (ieee->networks) + return 0; + + ieee->networks = kmalloc( + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + GFP_KERNEL); + if (!ieee->networks) { + printk(KERN_WARNING "%s: Out of memory allocating beacons\n", + ieee->dev->name); + return -ENOMEM; + } + + memset(ieee->networks, 0, + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); + + return 0; +} + +static inline void ieee80211_networks_free(struct ieee80211_device *ieee) +{ + if (!ieee->networks) + return; + kfree(ieee->networks); + ieee->networks = NULL; +} + +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) +{ + int i; + + INIT_LIST_HEAD(&ieee->network_free_list); + INIT_LIST_HEAD(&ieee->network_list); + for (i = 0; i < MAX_NETWORK_COUNT; i++) + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); +} + + +struct net_device *alloc_ieee80211(int sizeof_priv) +{ + struct ieee80211_device *ieee; + struct net_device *dev; + int i,err; + + IEEE80211_DEBUG_INFO("Initializing...\n"); + + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); + if (!dev) { + IEEE80211_ERROR("Unable to network device.\n"); + goto failed; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + ieee = netdev_priv(dev); +#else + ieee = (struct ieee80211_device *)dev->priv; +#endif +#if 0 + dev->hard_start_xmit = ieee80211_xmit; +#endif + + memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); + ieee->dev = dev; + + err = ieee80211_networks_allocate(ieee); + if (err) { + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", + err); + goto failed; + } + ieee80211_networks_initialize(ieee); + + + /* Default fragmentation threshold is maximum payload size */ + ieee->fts = DEFAULT_FTS; + ieee->scan_age = DEFAULT_MAX_SCAN_AGE; + ieee->open_wep = 1; + + /* Default to enabling full open WEP with host based encrypt/decrypt */ + ieee->host_encrypt = 1; + ieee->host_decrypt = 1; + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ + + INIT_LIST_HEAD(&ieee->crypt_deinit_list); + init_timer(&ieee->crypt_deinit_timer); + ieee->crypt_deinit_timer.data = (unsigned long)ieee; + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; + + spin_lock_init(&ieee->lock); + spin_lock_init(&ieee->wpax_suitlist_lock); + spin_lock_init(&ieee->bw_spinlock); + spin_lock_init(&ieee->reorder_spinlock); + //added by WB + atomic_set(&(ieee->atm_chnlop), 0); + atomic_set(&(ieee->atm_swbw), 0); + + ieee->wpax_type_set = 0; + ieee->wpa_enabled = 0; + ieee->tkip_countermeasures = 0; + ieee->drop_unencrypted = 0; + ieee->privacy_invoked = 0; + ieee->ieee802_1x = 1; + ieee->raw_tx = 0; + //ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead. + ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary. + + ieee80211_softmac_init(ieee); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) + ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); +#else + ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); + memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT)); +#endif + if (ieee->pHTInfo == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); + return NULL; + } + HTUpdateDefaultSetting(ieee); + HTInitializeHTInfo(ieee); //may move to other place. + TSInitialize(ieee); +#if 0 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq); +#else + INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq, ieee); +#endif +#endif + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); + + for (i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } + +//These function were added to load crypte module autoly + ieee80211_tkip_null(); + ieee80211_wep_null(); + ieee80211_ccmp_null(); + + return dev; + + failed: + if (dev) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + free_netdev(dev); +#else + kfree(dev); +#endif + return NULL; +} + + +void free_ieee80211(struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + int i; + //struct list_head *p, *q; +// del_timer_sync(&ieee->SwBwTimer); +#if 1 + if (ieee->pHTInfo != NULL) + { + kfree(ieee->pHTInfo); + ieee->pHTInfo = NULL; + } +#endif + RemoveAllTS(ieee); + ieee80211_softmac_free(ieee); + del_timer_sync(&ieee->crypt_deinit_timer); + ieee80211_crypt_deinit_entries(ieee, 1); + + for (i = 0; i < WEP_KEYS; i++) { + struct ieee80211_crypt_data *crypt = ieee->crypt[i]; + if (crypt) { + if (crypt->ops) { + crypt->ops->deinit(crypt->priv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + module_put(crypt->ops->owner); +#else + __MOD_DEC_USE_COUNT(crypt->ops->owner); +#endif + } + kfree(crypt); + ieee->crypt[i] = NULL; + } + } + + ieee80211_networks_free(ieee); +#if 0 + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) { + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) { + kfree(list_entry(p, struct ieee_ibss_seq, list)); + list_del(p); + } + } + +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + free_netdev(dev); +#else + kfree(dev); +#endif +} + +#ifdef CONFIG_IEEE80211_DEBUG + +u32 ieee80211_debug_level = 0; +static int debug = \ + // IEEE80211_DL_INFO | + // IEEE80211_DL_WX | + // IEEE80211_DL_SCAN | + // IEEE80211_DL_STATE | + // IEEE80211_DL_MGMT | + // IEEE80211_DL_FRAG | + // IEEE80211_DL_EAP | + // IEEE80211_DL_DROP | + // IEEE80211_DL_TX | + // IEEE80211_DL_RX | + //IEEE80211_DL_QOS | + // IEEE80211_DL_HT | + // IEEE80211_DL_TS | +// IEEE80211_DL_BA | + // IEEE80211_DL_REORDER| +// IEEE80211_DL_TRACE | + //IEEE80211_DL_DATA | + IEEE80211_DL_ERR //awayls open this flags to show error out + ; +struct proc_dir_entry *ieee80211_proc = NULL; + +static int show_debug_level(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level); +} + +static int store_debug_level(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char buf[] = "0x00000000"; + unsigned long len = min(sizeof(buf) - 1, (u32)count); + char *p = (char *)buf; + unsigned long val; + + if (copy_from_user(buf, buffer, len)) + return count; + buf[len] = 0; + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { + p++; + if (p[0] == 'x' || p[0] == 'X') + p++; + val = simple_strtoul(p, &p, 16); + } else + val = simple_strtoul(p, &p, 10); + if (p == buf) + printk(KERN_INFO DRV_NAME + ": %s is not in hex or decimal form.\n", buf); + else + ieee80211_debug_level = val; + + return strnlen(buf, count); +} + +extern int ieee80211_crypto_init(void); +extern void ieee80211_crypto_deinit(void); +extern int ieee80211_crypto_tkip_init(void); +extern void ieee80211_crypto_tkip_exit(void); +extern int ieee80211_crypto_ccmp_init(void); +extern void ieee80211_crypto_ccmp_exit(void); +extern int ieee80211_crypto_wep_init(void); +extern void ieee80211_crypto_wep_exit(void); + +int __init ieee80211_init(void) +{ + struct proc_dir_entry *e; + int retval; + + retval = ieee80211_crypto_init(); + if (retval) + return retval; + retval = ieee80211_crypto_tkip_init(); + if (retval) { + ieee80211_crypto_deinit(); + return retval; + } + retval = ieee80211_crypto_ccmp_init(); + if (retval) { + ieee80211_crypto_tkip_exit(); + ieee80211_crypto_deinit(); + return retval; + } + retval = ieee80211_crypto_wep_init(); + if (retval) { + ieee80211_crypto_ccmp_exit(); + ieee80211_crypto_tkip_exit(); + ieee80211_crypto_deinit(); + return retval; + } + + ieee80211_debug_level = debug; +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net); +#else + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); +#endif + if (ieee80211_proc == NULL) { + IEEE80211_ERROR("Unable to create " DRV_NAME + " proc directory\n"); + return -EIO; + } + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, + ieee80211_proc); + if (!e) { +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(DRV_NAME, proc_net); +#else + remove_proc_entry(DRV_NAME, init_net.proc_net); +#endif + ieee80211_proc = NULL; + return -EIO; + } + e->read_proc = show_debug_level; + e->write_proc = store_debug_level; + e->data = NULL; + + return 0; +} + +void __exit ieee80211_exit(void) +{ + if (ieee80211_proc) { + remove_proc_entry("debug_level", ieee80211_proc); +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(DRV_NAME, proc_net); +#else + remove_proc_entry(DRV_NAME, init_net.proc_net); +#endif + ieee80211_proc = NULL; + } + ieee80211_crypto_wep_exit(); + ieee80211_crypto_ccmp_exit(); + ieee80211_crypto_tkip_exit(); + ieee80211_crypto_deinit(); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#include +module_param(debug, int, 0444); +MODULE_PARM_DESC(debug, "debug output mask"); + + +//module_exit(ieee80211_exit); +//module_init(ieee80211_init); +#endif +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(alloc_ieee80211); +//EXPORT_SYMBOL(free_ieee80211); +#else +EXPORT_SYMBOL_NOVERS(alloc_ieee80211); +EXPORT_SYMBOL_NOVERS(free_ieee80211); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c new file mode 100644 index 00000000000..5dc478b8637 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -0,0 +1,2802 @@ +/* + * Original code based Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3 - hostap.o module, common routines + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * Copyright (c) 2004, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + ****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, + struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats) +{ + struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + + skb->dev = ieee->dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + skb_reset_mac_header(skb); +#else + skb->mac.raw = skb->data; +#endif + + skb_pull(skb, ieee80211_get_hdrlen(fc)); + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_80211_RAW); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); +} + + +/* Called only as a tasklet (software IRQ) */ +static struct ieee80211_frag_entry * +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq, + unsigned int frag, u8 tid,u8 *src, u8 *dst) +{ + struct ieee80211_frag_entry *entry; + int i; + + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) { + entry = &ieee->frag_cache[tid][i]; + if (entry->skb != NULL && + time_after(jiffies, entry->first_frag_time + 2 * HZ)) { + IEEE80211_DEBUG_FRAG( + "expiring fragment cache entry " + "seq=%u last_frag=%u\n", + entry->seq, entry->last_frag); + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; + } + + if (entry->skb != NULL && entry->seq == seq && + (entry->last_frag + 1 == frag || frag == -1) && + memcmp(entry->src_addr, src, ETH_ALEN) == 0 && + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) + return entry; + } + + return NULL; +} + +/* Called only as a tasklet (software IRQ) */ +static struct sk_buff * +ieee80211_frag_cache_get(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *hdr) +{ + struct sk_buff *skb = NULL; + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int frag = WLAN_GET_SEQ_FRAG(sc); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct ieee80211_frag_entry *entry; + struct ieee80211_hdr_3addrqos *hdr_3addrqos; + struct ieee80211_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else if (IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else { + tid = 0; + } + + if (frag == 0) { + /* Reserve enough space to fit maximum frame length */ + skb = dev_alloc_skb(ieee->dev->mtu + + sizeof(struct ieee80211_hdr_4addr) + + 8 /* LLC */ + + 2 /* alignment */ + + 8 /* WEP */ + + ETH_ALEN /* WDS */ + + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */); + if (skb == NULL) + return NULL; + + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; + ieee->frag_next_idx[tid]++; + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN) + ieee->frag_next_idx[tid] = 0; + + if (entry->skb != NULL) + dev_kfree_skb_any(entry->skb); + + entry->first_frag_time = jiffies; + entry->seq = seq; + entry->last_frag = frag; + entry->skb = skb; + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); + } else { + /* received a fragment of a frame for which the head fragment + * should have already been received */ + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2, + hdr->addr1); + if (entry != NULL) { + entry->last_frag = frag; + skb = entry->skb; + } + } + + return skb; +} + + +/* Called only as a tasklet (software IRQ) */ +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *hdr) +{ + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct ieee80211_frag_entry *entry; + struct ieee80211_hdr_3addrqos *hdr_3addrqos; + struct ieee80211_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else if (IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else { + tid = 0; + } + + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2, + hdr->addr1); + + if (entry == NULL) { + IEEE80211_DEBUG_FRAG( + "could not invalidate fragment cache " + "entry (seq=%u)\n", seq); + return -1; + } + + entry->skb = NULL; + return 0; +} + + + +/* ieee80211_rx_frame_mgtmt + * + * Responsible for handling management control frames + * + * Called by ieee80211_rx */ +static inline int +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype) +{ + /* On the struct stats definition there is written that + * this is not mandatory.... but seems that the probe + * response parser uses it + */ + struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data; + + rx_stats->len = skb->len; + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats); + //if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) + if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames + { + dev_kfree_skb_any(skb); + return 0; + } + + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype); + + dev_kfree_skb_any(skb); + + return 0; + + #ifdef NOT_YET + if (ieee->iw_mode == IW_MODE_MASTER) { + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + ieee->dev->name); + return 0; +/* + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *) + skb->data);*/ + } + + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) { + if (stype == WLAN_FC_STYPE_BEACON && + ieee->iw_mode == IW_MODE_MASTER) { + struct sk_buff *skb2; + /* Process beacon frames also in kernel driver to + * update STA(AP) table statistics */ + skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) + hostap_rx(skb2->dev, skb2, rx_stats); + } + + /* send management frames to the user space daemon for + * processing */ + ieee->apdevstats.rx_packets++; + ieee->apdevstats.rx_bytes += skb->len; + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT); + return 0; + } + + if (ieee->iw_mode == IW_MODE_MASTER) { + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { + printk(KERN_DEBUG "%s: unknown management frame " + "(type=0x%02x, stype=0x%02x) dropped\n", + skb->dev->name, type, stype); + return -1; + } + + hostap_rx(skb->dev, skb, rx_stats); + return 0; + } + + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame " + "received in non-Host AP mode\n", skb->dev->name); + return -1; + #endif +} + + + +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ +static unsigned char rfc1042_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ +static unsigned char bridge_tunnel_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; +/* No encapsulation header if EtherType < 0x600 (=length) */ + +/* Called by ieee80211_rx_frame_decrypt */ +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, + struct sk_buff *skb, size_t hdrlen) +{ + struct net_device *dev = ieee->dev; + u16 fc, ethertype; + struct ieee80211_hdr_4addr *hdr; + u8 *pos; + + if (skb->len < 24) + return 0; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + + /* check that the frame is unicast frame to us */ + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_TODS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { + /* ToDS frame with own addr BSSID and DA */ + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_FROMDS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { + /* FromDS frame with own addr as DA */ + } else + return 0; + + if (skb->len < 24 + 8) + return 0; + + /* check for port access entity Ethernet type */ +// pos = skb->data + 24; + pos = skb->data + hdrlen; + ethertype = (pos[6] << 8) | pos[7]; + if (ethertype == ETH_P_PAE) + return 1; + + return 0; +} + +/* Called only as a tasklet (software IRQ), by ieee80211_rx */ +static inline int +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, + struct ieee80211_crypt_data *crypt) +{ + struct ieee80211_hdr_4addr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) + return 0; +#if 1 + if (ieee->hwsec_active) + { + cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); + tcb_desc->bHwSec = 1; + } +#endif + hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + +#ifdef CONFIG_IEEE80211_CRYPT_TKIP + if (ieee->tkip_countermeasures && + strcmp(crypt->ops->name, "TKIP") == 0) { + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " + "received packet from " MAC_FMT "\n", + ieee->dev->name, MAC_ARG(hdr->addr2)); + } + return -1; + } +#endif + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + IEEE80211_DEBUG_DROP( + "decryption failed (SA=" MAC_FMT + ") res=%d\n", MAC_ARG(hdr->addr2), res); + if (res == -2) + IEEE80211_DEBUG_DROP("Decryption failed ICV " + "mismatch (key %d)\n", + skb->data[hdrlen + 3] >> 6); + ieee->ieee_stats.rx_discards_undecryptable++; + return -1; + } + + return res; +} + + +/* Called only as a tasklet (software IRQ), by ieee80211_rx */ +static inline int +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb, + int keyidx, struct ieee80211_crypt_data *crypt) +{ + struct ieee80211_hdr_4addr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) + return 0; + if (ieee->hwsec_active) + { + cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); + tcb_desc->bHwSec = 1; + } + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" + " (SA=" MAC_FMT " keyidx=%d)\n", + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + return -1; + } + + return 0; +} + + +/* this function is stolen from ipw2200 driver*/ +#define IEEE_PACKET_RETRY_TIME (5*HZ) +static int is_duplicate_packet(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *header) +{ + u16 fc = le16_to_cpu(header->frame_ctl); + u16 sc = le16_to_cpu(header->seq_ctl); + u16 seq = WLAN_GET_SEQ_SEQ(sc); + u16 frag = WLAN_GET_SEQ_FRAG(sc); + u16 *last_seq, *last_frag; + unsigned long *last_time; + struct ieee80211_hdr_3addrqos *hdr_3addrqos; + struct ieee80211_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + + //TO2DS and QoS + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS + hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; + tid = UP2AC(tid); + tid ++; + } else { // no QoS + tid = 0; + } + + switch (ieee->iw_mode) { + case IW_MODE_ADHOC: + { + struct list_head *p; + struct ieee_ibss_seq *entry = NULL; + u8 *mac = header->addr2; + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; + //for (pos = (head)->next; pos != (head); pos = pos->next) + //__list_for_each(p, &ieee->ibss_mac_hash[index]) { + list_for_each(p, &ieee->ibss_mac_hash[index]) { + entry = list_entry(p, struct ieee_ibss_seq, list); + if (!memcmp(entry->mac, mac, ETH_ALEN)) + break; + } + // if (memcmp(entry->mac, mac, ETH_ALEN)){ + if (p == &ieee->ibss_mac_hash[index]) { + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); + if (!entry) { + printk(KERN_WARNING "Cannot malloc new mac entry\n"); + return 0; + } + memcpy(entry->mac, mac, ETH_ALEN); + entry->seq_num[tid] = seq; + entry->frag_num[tid] = frag; + entry->packet_time[tid] = jiffies; + list_add(&entry->list, &ieee->ibss_mac_hash[index]); + return 0; + } + last_seq = &entry->seq_num[tid]; + last_frag = &entry->frag_num[tid]; + last_time = &entry->packet_time[tid]; + break; + } + + case IW_MODE_INFRA: + last_seq = &ieee->last_rxseq_num[tid]; + last_frag = &ieee->last_rxfrag_num[tid]; + last_time = &ieee->last_packet_time[tid]; + + break; + default: + return 0; + } + +// if(tid != 0) { +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl); +// } + if ((*last_seq == seq) && + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { + if (*last_frag == frag){ + //printk(KERN_WARNING "[1] go drop!\n"); + goto drop; + + } + if (*last_frag + 1 != frag) + /* out-of-order fragment */ + //printk(KERN_WARNING "[2] go drop!\n"); + goto drop; + } else + *last_seq = seq; + + *last_frag = frag; + *last_time = jiffies; + return 0; + +drop: +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY)); +// printk("DUP\n"); + + return 1; +} +bool +AddReorderEntry( + PRX_TS_RECORD pTS, + PRX_REORDER_ENTRY pReorderEntry + ) +{ + struct list_head *pList = &pTS->RxPendingPktList; +#if 1 + while(pList->next != &pTS->RxPendingPktList) + { + if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) ) + { + pList = pList->next; + } + else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) ) + { + return false; + } + else + { + break; + } + } +#endif + pReorderEntry->List.next = pList->next; + pReorderEntry->List.next->prev = &pReorderEntry->List; + pReorderEntry->List.prev = pList; + pList->next = &pReorderEntry->List; + + return true; +} + +void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index) +{ + u8 i = 0 , j=0; + u16 ethertype; +// if(index > 1) +// IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index); + for(j = 0; jnr_subframes; i++) { + struct sk_buff *sub_skb = prxb->subframes[i]; + + /* convert hdr + possible LLC headers into Ethernet header */ + ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; + if (sub_skb->len >= 8 && + ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + memcpy(skb_push(sub_skb, 2), &len, 2); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); + } + //stats->rx_packets++; + //stats->rx_bytes += sub_skb->len; + + /* Indicat the packets to upper layer */ + if (sub_skb) { + //printk("0skb_len(%d)\n", skb->len); + sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev); + memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); + sub_skb->dev = ieee->dev; + sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ + ieee->last_rx_ps_time = jiffies; + //printk("1skb_len(%d)\n", skb->len); + netif_rx(sub_skb); + } + } + kfree(prxb); + prxb = NULL; + } +} + + +void RxReorderIndicatePacket( struct ieee80211_device *ieee, + struct ieee80211_rxb* prxb, + PRX_TS_RECORD pTS, + u16 SeqNum) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + PRX_REORDER_ENTRY pReorderEntry = NULL; + struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE]; + u8 WinSize = pHTInfo->RxReorderWinSize; + u16 WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096; + u8 index = 0; + bool bMatchWinStart = false, bPktInBuf = false; + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize); +#if 0 + if(!list_empty(&ieee->RxReorder_Unused_List)) + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): ieee->RxReorder_Unused_List is nut NULL\n"); +#endif + /* Rx Reorder initialize condition.*/ + if(pTS->RxIndicateSeq == 0xffff) { + pTS->RxIndicateSeq = SeqNum; + } + + /* Drop out the packet which SeqNum is smaller than WinStart */ + if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) { + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); + pHTInfo->RxReorderDropCounter++; + { + int i; + for(i =0; i < prxb->nr_subframes; i++) { + dev_kfree_skb(prxb->subframes[i]); + } + kfree(prxb); + prxb = NULL; + } + return; + } + + /* + * Sliding window manipulation. Conditions includes: + * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 + * 2. Incoming SeqNum is larger than the WinEnd => Window shift N + */ + if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) { + pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; + bMatchWinStart = true; + } else if(SN_LESS(WinEnd, SeqNum)) { + if(SeqNum >= (WinSize - 1)) { + pTS->RxIndicateSeq = SeqNum + 1 -WinSize; + } else { + pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1; + } + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); + } + + /* + * Indication process. + * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets + * with the SeqNum smaller than latest WinStart and buffer other packets. + */ + /* For Rx Reorder condition: + * 1. All packets with SeqNum smaller than WinStart => Indicate + * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. + */ + if(bMatchWinStart) { + /* Current packet is going to be indicated.*/ + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\ + pTS->RxIndicateSeq, SeqNum); + prxbIndicateArray[0] = prxb; +// printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum); + index = 1; + } else { + /* Current packet is going to be inserted into pending list.*/ + //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__); + if(!list_empty(&ieee->RxReorder_Unused_List)) { + pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List); + list_del_init(&pReorderEntry->List); + + /* Make a reorder entry and insert into a the packet list.*/ + pReorderEntry->SeqNum = SeqNum; + pReorderEntry->prxb = prxb; + // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum); + +#if 1 + if(!AddReorderEntry(pTS, pReorderEntry)) { + IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", + __FUNCTION__, pTS->RxIndicateSeq, SeqNum); + list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); + { + int i; + for(i =0; i < prxb->nr_subframes; i++) { + dev_kfree_skb(prxb->subframes[i]); + } + kfree(prxb); + prxb = NULL; + } + } else { + IEEE80211_DEBUG(IEEE80211_DL_REORDER, + "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); + } +#endif + } + else { + /* + * Packets are dropped if there is not enough reorder entries. + * This part shall be modified!! We can just indicate all the + * packets in buffer and get reorder entries. + */ + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n"); + { + int i; + for(i =0; i < prxb->nr_subframes; i++) { + dev_kfree_skb(prxb->subframes[i]); + } + kfree(prxb); + prxb = NULL; + } + } + } + + /* Check if there is any packet need indicate.*/ + while(!list_empty(&pTS->RxPendingPktList)) { + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__); +#if 1 + pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); + if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) + { + /* This protect buffer from overflow. */ + if(index >= REORDER_WIN_SIZE) { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n"); + bPktInBuf = true; + break; + } + + list_del_init(&pReorderEntry->List); + + if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) + pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; + + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); + prxbIndicateArray[index] = pReorderEntry->prxb; + // printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum); + index++; + + list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); + } else { + bPktInBuf = true; + break; + } +#endif + } + + /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/ + if(index>0) { + // Cancel previous pending timer. + if (timer_pending(&pTS->RxPktPendingTimer)) + del_timer_sync(&pTS->RxPktPendingTimer); + pTS->RxTimeoutIndicateSeq = 0xffff; + + // Indicate packets + if(index>REORDER_WIN_SIZE){ + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); + return; + } + ieee80211_indicate_packets(ieee, prxbIndicateArray, index); + bPktInBuf = false; + } + +#if 1 + if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) { + // Set new pending timer. + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__); + pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq; +#if 0 + if(timer_pending(&pTS->RxPktPendingTimer)) + del_timer_sync(&pTS->RxPktPendingTimer); + pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime); + add_timer(&pTS->RxPktPendingTimer); +#else + mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime)); +#endif + } +#endif +} + +u8 parse_subframe(struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, + struct ieee80211_rxb *rxb,u8* src,u8* dst) +{ + struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr* )skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + + u16 LLCOffset= sizeof(struct ieee80211_hdr_3addr); + u16 ChkLength; + bool bIsAggregateFrame = false; + u16 nSubframe_Length; + u8 nPadding_Length = 0; + u16 SeqNum=0; + + struct sk_buff *sub_skb; + u8 *data_ptr; + /* just for debug purpose */ + SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl)); + + if((IEEE80211_QOS_HAS_SEQ(fc))&&\ + (((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) { + bIsAggregateFrame = true; + } + + if(IEEE80211_QOS_HAS_SEQ(fc)) { + LLCOffset += 2; + } + + if(rx_stats->bContainHTC) { + LLCOffset += sHTCLng; + } + //printk("ChkLength = %d\n", LLCOffset); + // Null packet, don't indicate it to upper layer + ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ + + if( skb->len <= ChkLength ) { + return 0; + } + + skb_pull(skb, LLCOffset); + + if(!bIsAggregateFrame) { + rxb->nr_subframes = 1; +#ifdef JOHN_NOCPY + rxb->subframes[0] = skb; +#else + rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC); +#endif + + memcpy(rxb->src,src,ETH_ALEN); + memcpy(rxb->dst,dst,ETH_ALEN); + //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len); + return 1; + } else { + rxb->nr_subframes = 0; + memcpy(rxb->src,src,ETH_ALEN); + memcpy(rxb->dst,dst,ETH_ALEN); + while(skb->len > ETHERNET_HEADER_SIZE) { + /* Offset 12 denote 2 mac address */ + nSubframe_Length = *((u16*)(skb->data + 12)); + //==m==>change the length order + nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8); + + if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) { +#if 0//cosa + RT_ASSERT( + (nRemain_Length>=(ETHERNET_HEADER_SIZE + nSubframe_Length)), + ("ParseSubframe(): A-MSDU subframe parse error!! Subframe Length: %d\n", nSubframe_Length) ); +#endif + printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\ + __FUNCTION__,rxb->nr_subframes); + printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length); + printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length); + printk("The Packet SeqNum is %d\n",SeqNum); + return 0; + } + + /* move the data point to data content */ + skb_pull(skb, ETHERNET_HEADER_SIZE); + +#ifdef JOHN_NOCPY + sub_skb = skb_clone(skb, GFP_ATOMIC); + sub_skb->len = nSubframe_Length; + sub_skb->tail = sub_skb->data + nSubframe_Length; +#else + /* Allocate new skb for releasing to upper layer */ + sub_skb = dev_alloc_skb(nSubframe_Length + 12); + skb_reserve(sub_skb, 12); + data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); + memcpy(data_ptr,skb->data,nSubframe_Length); +#endif + rxb->subframes[rxb->nr_subframes++] = sub_skb; + if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { + IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n"); + break; + } + skb_pull(skb,nSubframe_Length); + + if(skb->len != 0) { + nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4); + if(nPadding_Length == 4) { + nPadding_Length = 0; + } + + if(skb->len < nPadding_Length) { + return 0; + } + + skb_pull(skb,nPadding_Length); + } + } +#ifdef JOHN_NOCPY + dev_kfree_skb(skb); +#endif + //{just for debug added by david + //printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes); + //} + return rxb->nr_subframes; + } +} + +/* All received frames are sent to this function. @skb contains the frame in + * IEEE 802.11 format, i.e., in the format it was sent over air. + * This function is called only as a tasklet (software IRQ). */ +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats) +{ + struct net_device *dev = ieee->dev; + struct ieee80211_hdr_4addr *hdr; + //struct ieee80211_hdr_3addrqos *hdr; + + size_t hdrlen; + u16 fc, type, stype, sc; + struct net_device_stats *stats; + unsigned int frag; + u8 *payload; + u16 ethertype; + //added by amy for reorder + u8 TID = 0; + u16 SeqNum = 0; + PRX_TS_RECORD pTS = NULL; + //bool bIsAggregateFrame = false; + //added by amy for reorder +#ifdef NOT_YET + struct net_device *wds = NULL; + struct sk_buff *skb2 = NULL; + struct net_device *wds = NULL; + int frame_authorized = 0; + int from_assoc_ap = 0; + void *sta = NULL; +#endif +// u16 qos_ctl = 0; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + struct ieee80211_crypt_data *crypt = NULL; + int keyidx = 0; + + int i; + struct ieee80211_rxb* rxb = NULL; + // cheat the the hdr type + hdr = (struct ieee80211_hdr_4addr *)skb->data; + stats = &ieee->stats; + + if (skb->len < 10) { + printk(KERN_INFO "%s: SKB length < 10\n", + dev->name); + goto rx_dropped; + } + + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + sc = le16_to_cpu(hdr->seq_ctl); + + frag = WLAN_GET_SEQ_FRAG(sc); + hdrlen = ieee80211_get_hdrlen(fc); + + if(HTCCheck(ieee, skb->data)) + { + if(net_ratelimit()) + printk("find HTCControl\n"); + hdrlen += 4; + rx_stats->bContainHTC = 1; + } + + //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); +#ifdef NOT_YET +#if WIRELESS_EXT > 15 + /* Put this code here so that we avoid duplicating it in all + * Rx paths. - Jean II */ +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ + /* If spy monitoring on */ + if (iface->spy_data.spy_number > 0) { + struct iw_quality wstats; + wstats.level = rx_stats->rssi; + wstats.noise = rx_stats->noise; + wstats.updated = 6; /* No qual value */ + /* Update spy records */ + wireless_spy_update(dev, hdr->addr2, &wstats); + } +#endif /* IW_WIRELESS_SPY */ +#endif /* WIRELESS_EXT > 15 */ + hostap_update_rx_stats(local->ap, hdr, rx_stats); +#endif + +#if WIRELESS_EXT > 15 + if (ieee->iw_mode == IW_MODE_MONITOR) { + ieee80211_monitor_rx(ieee, skb, rx_stats); + stats->rx_packets++; + stats->rx_bytes += skb->len; + return 1; + } +#endif + if (ieee->host_decrypt) { + int idx = 0; + if (skb->len >= hdrlen + 3) + idx = skb->data[hdrlen + 3] >> 6; + crypt = ieee->crypt[idx]; +#ifdef NOT_YET + sta = NULL; + + /* Use station specific key to override default keys if the + * receiver address is a unicast address ("individual RA"). If + * bcrx_sta_key parameter is set, station specific key is used + * even with broad/multicast targets (this is against IEEE + * 802.11, but makes it easier to use different keys with + * stations that do not support WEP key mapping). */ + + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) + (void) hostap_handle_sta_crypto(local, hdr, &crypt, + &sta); +#endif + + /* allow NULL decrypt to indicate an station specific override + * for default encryption */ + if (crypt && (crypt->ops == NULL || + crypt->ops->decrypt_mpdu == NULL)) + crypt = NULL; + + if (!crypt && (fc & IEEE80211_FCTL_WEP)) { + /* This seems to be triggered by some (multicast?) + * frames from other than current BSS, so just drop the + * frames silently instead of filling system log with + * these reports. */ + IEEE80211_DEBUG_DROP("Decryption failed (not set)" + " (SA=" MAC_FMT ")\n", + MAC_ARG(hdr->addr2)); + ieee->ieee_stats.rx_discards_undecryptable++; + goto rx_dropped; + } + } + + if (skb->len < IEEE80211_DATA_HDR3_LEN) + goto rx_dropped; + + // if QoS enabled, should check the sequence for each of the AC + if( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){ + if (is_duplicate_packet(ieee, hdr)) + goto rx_dropped; + + } + else + { + PRX_TS_RECORD pRxTS = NULL; + #if 0 + struct ieee80211_hdr_3addr *hdr; + u16 fc; + hdr = (struct ieee80211_hdr_3addr *)skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + u8 tmp = (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS); + + u8 tid = (*((u8*)skb->data + (((fc& IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))?30:24)))&0xf; + printk("====================>fc:%x, tid:%d, tmp:%d\n", fc, tid, tmp); + //u8 tid = (u8)((frameqos*)(buf + ((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24))->field.tid; + #endif + //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid); +#if 1 + if(GetTs( + ieee, + (PTS_COMMON_INFO*) &pRxTS, + hdr->addr2, + (u8)Frame_QoSTID((u8*)(skb->data)), + RX_DIR, + true)) + { + + // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc)); + if( (fc & (1<<11)) && + (frag == pRxTS->RxLastFragNum) && + (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) ) + { + goto rx_dropped; + } + else + { + pRxTS->RxLastFragNum = frag; + pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc); + } + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__); + goto rx_dropped; + } + } +#endif + if (type == IEEE80211_FTYPE_MGMT) { + + #if 0 + if ( stype == IEEE80211_STYPE_AUTH && + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt && + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) + { + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " + "from " MAC_FMT "\n", dev->name, + MAC_ARG(hdr->addr2)); + /* TODO: could inform hostapd about this so that it + * could send auth failure report */ + goto rx_dropped; + } + #endif + + //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) + goto rx_dropped; + else + goto rx_exit; + } + + /* Data frame - extract src/dst addresses */ + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_FROMDS: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr3, ETH_ALEN); + memcpy(bssid, hdr->addr2, ETH_ALEN); + break; + case IEEE80211_FCTL_TODS: + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr1, ETH_ALEN); + break; + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: + if (skb->len < IEEE80211_DATA_HDR4_LEN) + goto rx_dropped; + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr4, ETH_ALEN); + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); + break; + case 0: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr3, ETH_ALEN); + break; + } + +#ifdef NOT_YET + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds)) + goto rx_dropped; + if (wds) { + skb->dev = dev = wds; + stats = hostap_get_stats(dev); + } + + if (ieee->iw_mode == IW_MODE_MASTER && !wds && + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && + ieee->stadev && + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) { + /* Frame from BSSID of the AP for which we are a client */ + skb->dev = dev = ieee->stadev; + stats = hostap_get_stats(dev); + from_assoc_ap = 1; + } +#endif + + dev->last_rx = jiffies; + +#ifdef NOT_YET + if ((ieee->iw_mode == IW_MODE_MASTER || + ieee->iw_mode == IW_MODE_REPEAT) && + !from_assoc_ap) { + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats, + wds != NULL)) { + case AP_RX_CONTINUE_NOT_AUTHORIZED: + frame_authorized = 0; + break; + case AP_RX_CONTINUE: + frame_authorized = 1; + break; + case AP_RX_DROP: + goto rx_dropped; + case AP_RX_EXIT: + goto rx_exit; + } + } +#endif + //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); + /* Nullfunc frames may have PS-bit set, so they must be passed to + * hostap_handle_sta_rx() before being dropped here. */ + if (stype != IEEE80211_STYPE_DATA && + stype != IEEE80211_STYPE_DATA_CFACK && + stype != IEEE80211_STYPE_DATA_CFPOLL && + stype != IEEE80211_STYPE_DATA_CFACKPOLL&& + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4 + ) { + if (stype != IEEE80211_STYPE_NULLFUNC) + IEEE80211_DEBUG_DROP( + "RX: dropped data frame " + "with no data (type=0x%02x, " + "subtype=0x%02x, len=%d)\n", + type, stype, skb->len); + goto rx_dropped; + } + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) + goto rx_dropped; + + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ + + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) + { + printk("decrypt frame error\n"); + goto rx_dropped; + } + + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + + /* skb: hdr + (possibly fragmented) plaintext payload */ + // PR: FIXME: hostap has additional conditions in the "if" below: + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { + int flen; + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); + + if (!frag_skb) { + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG, + "Rx cannot get skb from fragment " + "cache (morefrag=%d seq=%u frag=%u)\n", + (fc & IEEE80211_FCTL_MOREFRAGS) != 0, + WLAN_GET_SEQ_SEQ(sc), frag); + goto rx_dropped; + } + flen = skb->len; + if (frag != 0) + flen -= hdrlen; + + if (frag_skb->tail + flen > frag_skb->end) { + printk(KERN_WARNING "%s: host decrypted and " + "reassembled frame did not fit skb\n", + dev->name); + ieee80211_frag_cache_invalidate(ieee, hdr); + goto rx_dropped; + } + + if (frag == 0) { + /* copy first fragment (including full headers) into + * beginning of the fragment cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data, flen); + } else { + /* append frame payload to the end of the fragment + * cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, + flen); + } + dev_kfree_skb_any(skb); + skb = NULL; + + if (fc & IEEE80211_FCTL_MOREFRAGS) { + /* more fragments expected - leave the skb in fragment + * cache for now; it will be delivered to upper layers + * after all fragments have been received */ + goto rx_exit; + } + + /* this was the last fragment and the frame will be + * delivered, so remove skb from fragment cache */ + skb = frag_skb; + hdr = (struct ieee80211_hdr_4addr *) skb->data; + ieee80211_frag_cache_invalidate(ieee, hdr); + } + + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still + * encrypted/authenticated */ + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) + { + printk("==>decrypt msdu error\n"); + goto rx_dropped; + } + + //added by amy for AP roaming + ieee->LinkDetectInfo.NumRecvDataInPeriod++; + ieee->LinkDetectInfo.NumRxOkInPeriod++; + + hdr = (struct ieee80211_hdr_4addr *) skb->data; + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { + if (/*ieee->ieee802_1x &&*/ + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + +#ifdef CONFIG_IEEE80211_DEBUG + /* pass unencrypted EAPOL frames even if encryption is + * configured */ + struct eapol *eap = (struct eapol *)(skb->data + + 24); + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); +#endif + } else { + IEEE80211_DEBUG_DROP( + "encryption configured, but RX " + "frame not encrypted (SA=" MAC_FMT ")\n", + MAC_ARG(hdr->addr2)); + goto rx_dropped; + } + } + +#ifdef CONFIG_IEEE80211_DEBUG + if (crypt && !(fc & IEEE80211_FCTL_WEP) && + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + struct eapol *eap = (struct eapol *)(skb->data + + 24); + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); + } +#endif + + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep && + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + IEEE80211_DEBUG_DROP( + "dropped unencrypted RX data " + "frame from " MAC_FMT + " (drop_unencrypted=1)\n", + MAC_ARG(hdr->addr2)); + goto rx_dropped; + } +/* + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n"); + } +*/ +//added by amy for reorder +#if 1 + if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) + && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) + { + TID = Frame_QoSTID(skb->data); + SeqNum = WLAN_GET_SEQ_SEQ(sc); + GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true); + if(TID !=0 && TID !=3) + { + ieee->bis_any_nonbepkts = true; + } + } +#endif +//added by amy for reorder + /* skb: hdr + (possible reassembled) full plaintext payload */ + payload = skb->data + hdrlen; + //ethertype = (payload[6] << 8) | payload[7]; + rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC); + if(rxb == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__); + goto rx_dropped; + } + /* to parse amsdu packets */ + /* qos data packets & reserved bit is 1 */ + if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) { + /* only to free rxb, and not submit the packets to upper layer */ + for(i =0; i < rxb->nr_subframes; i++) { + dev_kfree_skb(rxb->subframes[i]); + } + kfree(rxb); + rxb = NULL; + goto rx_dropped; + } + + ieee->last_rx_ps_time = jiffies; +//added by amy for reorder + if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){ +//added by amy for reorder + for(i = 0; inr_subframes; i++) { + struct sk_buff *sub_skb = rxb->subframes[i]; + + if (sub_skb) { + /* convert hdr + possible LLC headers into Ethernet header */ + ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; + if (sub_skb->len >= 8 && + ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + memcpy(skb_push(sub_skb, 2), &len, 2); + memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + } + + stats->rx_packets++; + stats->rx_bytes += sub_skb->len; + if(is_multicast_ether_addr(dst)) { + stats->multicast++; + } + + /* Indicat the packets to upper layer */ + //printk("0skb_len(%d)\n", skb->len); + sub_skb->protocol = eth_type_trans(sub_skb, dev); + memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); + sub_skb->dev = dev; + sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ + //printk("1skb_len(%d)\n", skb->len); + netif_rx(sub_skb); + } + } + kfree(rxb); + rxb = NULL; + + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__); + RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); + } +#ifndef JOHN_NOCPY + dev_kfree_skb(skb); +#endif + + rx_exit: +#ifdef NOT_YET + if (sta) + hostap_handle_sta_release(sta); +#endif + return 1; + + rx_dropped: + if (rxb != NULL) + { + kfree(rxb); + rxb = NULL; + } + stats->rx_dropped++; + + /* Returning 0 indicates to caller that we have not handled the SKB-- + * so it is still allocated and can be used again by underlying + * hardware as a DMA target */ + return 0; +} + +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 + +static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; + +/* +* Make ther structure we read from the beacon packet has +* the right values +*/ +static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element + *info_element, int sub_type) +{ + + if (info_element->qui_subtype != sub_type) + return -1; + if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) + return -1; + if (info_element->qui_type != QOS_OUI_TYPE) + return -1; + if (info_element->version != QOS_VERSION_1) + return -1; + + return 0; +} + + +/* + * Parse a QoS parameter element + */ +static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info + *element_param, struct ieee80211_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2; + + if ((info_element == NULL) || (element_param == NULL)) + return -1; + + if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) { + memcpy(element_param->info_element.qui, info_element->data, + info_element->len); + element_param->info_element.elementID = info_element->id; + element_param->info_element.length = info_element->len; + } else + ret = -1; + if (ret == 0) + ret = ieee80211_verify_qos_info(&element_param->info_element, + QOS_OUI_PARAM_SUB_TYPE); + return ret; +} + +/* + * Parse a QoS information element + */ +static int ieee80211_read_qos_info_element(struct + ieee80211_qos_information_element + *element_info, struct ieee80211_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct ieee80211_qos_information_element) - 2; + + if (element_info == NULL) + return -1; + if (info_element == NULL) + return -1; + + if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) { + memcpy(element_info->qui, info_element->data, + info_element->len); + element_info->elementID = info_element->id; + element_info->length = info_element->len; + } else + ret = -1; + + if (ret == 0) + ret = ieee80211_verify_qos_info(element_info, + QOS_OUI_INFO_SUB_TYPE); + return ret; +} + + +/* + * Write QoS parameters from the ac parameters. + */ +static int ieee80211_qos_convert_ac_to_parameters(struct + ieee80211_qos_parameter_info + *param_elm, struct + ieee80211_qos_parameters + *qos_param) +{ + int rc = 0; + int i; + struct ieee80211_qos_ac_parameter *ac_params; + u8 aci; + //u8 cw_min; + //u8 cw_max; + + for (i = 0; i < QOS_QUEUE_NUM; i++) { + ac_params = &(param_elm->ac_params_record[i]); + + aci = (ac_params->aci_aifsn & 0x60) >> 5; + + if(aci >= QOS_QUEUE_NUM) + continue; + qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; + + /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ + qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci]; + + qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F; + + qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4; + + qos_param->flag[aci] = + (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; + qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit); + } + return rc; +} + +/* + * we have a generic data element which it may contain QoS information or + * parameters element. check the information element length to decide + * which type to read + */ +static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element + *info_element, + struct ieee80211_network *network) +{ + int rc = 0; + struct ieee80211_qos_parameters *qos_param = NULL; + struct ieee80211_qos_information_element qos_info_element; + + rc = ieee80211_read_qos_info_element(&qos_info_element, info_element); + + if (rc == 0) { + network->qos_data.param_count = qos_info_element.ac_info & 0x0F; + network->flags |= NETWORK_HAS_QOS_INFORMATION; + } else { + struct ieee80211_qos_parameter_info param_element; + + rc = ieee80211_read_qos_param_element(¶m_element, + info_element); + if (rc == 0) { + qos_param = &(network->qos_data.parameters); + ieee80211_qos_convert_ac_to_parameters(¶m_element, + qos_param); + network->flags |= NETWORK_HAS_QOS_PARAMETERS; + network->qos_data.param_count = + param_element.info_element.ac_info & 0x0F; + } + } + + if (rc == 0) { + IEEE80211_DEBUG_QOS("QoS is supported\n"); + network->qos_data.supported = 1; + } + return rc; +} + +#ifdef CONFIG_IEEE80211_DEBUG +#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x + +static const char *get_info_element_string(u16 id) +{ + switch (id) { + MFIE_STRING(SSID); + MFIE_STRING(RATES); + MFIE_STRING(FH_SET); + MFIE_STRING(DS_SET); + MFIE_STRING(CF_SET); + MFIE_STRING(TIM); + MFIE_STRING(IBSS_SET); + MFIE_STRING(COUNTRY); + MFIE_STRING(HOP_PARAMS); + MFIE_STRING(HOP_TABLE); + MFIE_STRING(REQUEST); + MFIE_STRING(CHALLENGE); + MFIE_STRING(POWER_CONSTRAINT); + MFIE_STRING(POWER_CAPABILITY); + MFIE_STRING(TPC_REQUEST); + MFIE_STRING(TPC_REPORT); + MFIE_STRING(SUPP_CHANNELS); + MFIE_STRING(CSA); + MFIE_STRING(MEASURE_REQUEST); + MFIE_STRING(MEASURE_REPORT); + MFIE_STRING(QUIET); + MFIE_STRING(IBSS_DFS); + // MFIE_STRING(ERP_INFO); + MFIE_STRING(RSN); + MFIE_STRING(RATES_EX); + MFIE_STRING(GENERIC); + MFIE_STRING(QOS_PARAMETER); + default: + return "UNKNOWN"; + } +} +#endif + +#ifdef ENABLE_DOT11D +static inline void ieee80211_extract_country_ie( + struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + struct ieee80211_network *network, + u8 * addr2 +) +{ + if(IS_DOT11D_ENABLE(ieee)) + { + if(info_element->len!= 0) + { + memcpy(network->CountryIeBuf, info_element->data, info_element->len); + network->CountryIeLen = info_element->len; + + if(!IS_COUNTRY_IE_VALID(ieee)) + { + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); + } + } + + // + // 070305, rcnjko: I update country IE watch dog here because + // some AP (e.g. Cisco 1242) don't include country IE in their + // probe response frame. + // + if(IS_EQUAL_CIE_SRC(ieee, addr2) ) + { + UPDATE_CIE_WATCHDOG(ieee); + } + } + +} +#endif + +int ieee80211_parse_info_param(struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + u16 length, + struct ieee80211_network *network, + struct ieee80211_rx_stats *stats) +{ + u8 i; + short offset; + u16 tmp_htcap_len=0; + u16 tmp_htinfo_len=0; + u16 ht_realtek_agg_len=0; + u8 ht_realtek_agg_buf[MAX_IE_LEN]; +// u16 broadcom_len = 0; +#ifdef CONFIG_IEEE80211_DEBUG + char rates_str[64]; + char *p; +#endif + + while (length >= sizeof(*info_element)) { + if (sizeof(*info_element) + info_element->len > length) { + IEEE80211_DEBUG_MGMT("Info elem: parse failed: " + "info_element->len + 2 > left : " + "info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + + sizeof(*info_element), + length, info_element->id); + /* We stop processing but don't return an error here + * because some misbehaviour APs break this rule. ie. + * Orinoco AP1000. */ + break; + } + + switch (info_element->id) { + case MFIE_TYPE_SSID: + if (ieee80211_is_empty_essid(info_element->data, + info_element->len)) { + network->flags |= NETWORK_EMPTY_ESSID; + break; + } + + network->ssid_len = min(info_element->len, + (u8) IW_ESSID_MAX_SIZE); + memcpy(network->ssid, info_element->data, network->ssid_len); + if (network->ssid_len < IW_ESSID_MAX_SIZE) + memset(network->ssid + network->ssid_len, 0, + IW_ESSID_MAX_SIZE - network->ssid_len); + + IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n", + network->ssid, network->ssid_len); + break; + + case MFIE_TYPE_RATES: +#ifdef CONFIG_IEEE80211_DEBUG + p = rates_str; +#endif + network->rates_len = min(info_element->len, + MAX_RATES_LENGTH); + for (i = 0; i < network->rates_len; i++) { + network->rates[i] = info_element->data[i]; +#ifdef CONFIG_IEEE80211_DEBUG + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); +#endif + if (ieee80211_is_ofdm_rate + (info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + IEEE80211_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + } + + IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n", + rates_str, network->rates_len); + break; + + case MFIE_TYPE_RATES_EX: +#ifdef CONFIG_IEEE80211_DEBUG + p = rates_str; +#endif + network->rates_ex_len = min(info_element->len, + MAX_RATES_EX_LENGTH); + for (i = 0; i < network->rates_ex_len; i++) { + network->rates_ex[i] = info_element->data[i]; +#ifdef CONFIG_IEEE80211_DEBUG + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); +#endif + if (ieee80211_is_ofdm_rate + (info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + IEEE80211_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + } + + IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n", + rates_str, network->rates_ex_len); + break; + + case MFIE_TYPE_DS_SET: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n", + info_element->data[0]); + network->channel = info_element->data[0]; + break; + + case MFIE_TYPE_FH_SET: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n"); + break; + + case MFIE_TYPE_CF_SET: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n"); + break; + + case MFIE_TYPE_TIM: + if(info_element->len < 4) + break; + + network->tim.tim_count = info_element->data[0]; + network->tim.tim_period = info_element->data[1]; + + network->dtim_period = info_element->data[1]; + if(ieee->state != IEEE80211_LINKED) + break; +#if 0 + network->last_dtim_sta_time[0] = stats->mac_time[0]; +#else + //we use jiffies for legacy Power save + network->last_dtim_sta_time[0] = jiffies; +#endif + network->last_dtim_sta_time[1] = stats->mac_time[1]; + + network->dtim_data = IEEE80211_DTIM_VALID; + + if(info_element->data[0] != 0) + break; + + if(info_element->data[2] & 1) + network->dtim_data |= IEEE80211_DTIM_MBCAST; + + offset = (info_element->data[2] >> 1)*2; + + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id); + + if(ieee->assoc_id < 8*offset || + ieee->assoc_id > 8*(offset + info_element->len -3)) + + break; + + offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ; + + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) + network->dtim_data |= IEEE80211_DTIM_UCAST; + + //IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n"); + break; + + case MFIE_TYPE_ERP: + network->erp_value = info_element->data[0]; + network->flags |= NETWORK_HAS_ERP_VALUE; + IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", + network->erp_value); + break; + case MFIE_TYPE_IBSS_SET: + network->atim_window = info_element->data[0]; + IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n", + network->atim_window); + break; + + case MFIE_TYPE_CHALLENGE: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n"); + break; + + case MFIE_TYPE_GENERIC: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n", + info_element->len); + if (!ieee80211_parse_qos_info_param_IE(info_element, + network)) + break; + + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x01) { + network->wpa_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->wpa_ie, info_element, + network->wpa_ie_len); + break; + } + +#ifdef THOMAS_TURBO + if (info_element->len == 7 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x01 && + info_element->data[4] == 0x02) { + network->Turbo_Enable = 1; + } +#endif + + //for HTcap and HTinfo parameters + if(tmp_htcap_len == 0){ + if(info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x033){ + + tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); + if(tmp_htcap_len != 0){ + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ + sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); + } + } + if(tmp_htcap_len != 0) + network->bssht.bdSupportHT = true; + else + network->bssht.bdSupportHT = false; + } + + + if(tmp_htinfo_len == 0){ + if(info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x034){ + + tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); + if(tmp_htinfo_len != 0){ + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + if(tmp_htinfo_len){ + network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ + sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); + } + + } + + } + } + + if(ieee->aggregation){ + if(network->bssht.bdSupportHT){ + if(info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x02){ + + ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN); + memcpy(ht_realtek_agg_buf,info_element->data,info_element->len); + + } + if(ht_realtek_agg_len >= 5){ + network->bssht.bdRT2RTAggregation = true; + + if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) + network->bssht.bdRT2RTLongSlotTime = true; + } + } + + } + + //if(tmp_htcap_len !=0 || tmp_htinfo_len != 0) + { + if((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x05 && + info_element->data[2] == 0xb5) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0a && + info_element->data[2] == 0xf7) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x10 && + info_element->data[2] == 0x18)){ + + network->broadcom_cap_exist = true; + + } + } +#if 0 + if (tmp_htcap_len !=0) + { + u16 cap_ext = ((PHT_CAPABILITY_ELE)&info_element->data[0])->ExtHTCapInfo; + if ((cap_ext & 0x0c00) == 0x0c00) + { + network->ralink_cap_exist = true; + } + } +#endif + if(info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0c && + info_element->data[2] == 0x43) + { + network->ralink_cap_exist = true; + } + else + network->ralink_cap_exist = false; + //added by amy for atheros AP + if((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x03 && + info_element->data[2] == 0x7f) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x13 && + info_element->data[2] == 0x74)) + { + printk("========>%s(): athros AP is exist\n",__FUNCTION__); + network->atheros_cap_exist = true; + } + else + network->atheros_cap_exist = false; + + if(info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96) + { + network->cisco_cap_exist = true; + } + else + network->cisco_cap_exist = false; + //added by amy for LEAP of cisco + if(info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x01) + { + if(info_element->len == 6) + { + memcpy(network->CcxRmState, &info_element[4], 2); + if(network->CcxRmState[0] != 0) + { + network->bCcxRmEnable = true; + } + else + network->bCcxRmEnable = false; + // + // CCXv4 Table 59-1 MBSSID Masks. + // + network->MBssidMask = network->CcxRmState[1] & 0x07; + if(network->MBssidMask != 0) + { + network->bMBssidValid = true; + network->MBssidMask = 0xff << (network->MBssidMask); + cpMacAddr(network->MBssid, network->bssid); + network->MBssid[5] &= network->MBssidMask; + } + else + { + network->bMBssidValid = false; + } + } + else + { + network->bCcxRmEnable = false; + } + } + if(info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x03) + { + if(info_element->len == 5) + { + network->bWithCcxVerNum = true; + network->BssCcxVerNumber = info_element->data[4]; + } + else + { + network->bWithCcxVerNum = false; + network->BssCcxVerNumber = 0; + } + } + break; + + case MFIE_TYPE_RSN: + IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n", + info_element->len); + network->rsn_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->rsn_ie, info_element, + network->rsn_ie_len); + break; + + //HT related element. + case MFIE_TYPE_HT_CAP: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", + info_element->len); + tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); + if(tmp_htcap_len != 0){ + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ + sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); + + //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() + // windows driver will update WMM parameters each beacon received once connected + // Linux driver is a bit different. + network->bssht.bdSupportHT = true; + } + else + network->bssht.bdSupportHT = false; + break; + + + case MFIE_TYPE_HT_INFO: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", + info_element->len); + tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); + if(tmp_htinfo_len){ + network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; + network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ + sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); + } + break; + + case MFIE_TYPE_AIRONET: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", + info_element->len); + if(info_element->len >IE_CISCO_FLAG_POSITION) + { + network->bWithAironetIE = true; + + // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23): + // "A Cisco access point advertises support for CKIP in beacon and probe response packets, + // by adding an Aironet element and setting one or both of the CKIP negotiation bits." + if( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) || + (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) ) + { + network->bCkipSupported = true; + } + else + { + network->bCkipSupported = false; + } + } + else + { + network->bWithAironetIE = false; + network->bCkipSupported = false; + } + break; + case MFIE_TYPE_QOS_PARAMETER: + printk(KERN_ERR + "QoS Error need to parse QOS_PARAMETER IE\n"); + break; + +#ifdef ENABLE_DOT11D + case MFIE_TYPE_COUNTRY: + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", + info_element->len); + //printk("=====>Receive <%s> Country IE\n",network->ssid); + ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP + break; +#endif +/* TODO */ +#if 0 + /* 802.11h */ + case MFIE_TYPE_POWER_CONSTRAINT: + network->power_constraint = info_element->data[0]; + network->flags |= NETWORK_HAS_POWER_CONSTRAINT; + break; + + case MFIE_TYPE_CSA: + network->power_constraint = info_element->data[0]; + network->flags |= NETWORK_HAS_CSA; + break; + + case MFIE_TYPE_QUIET: + network->quiet.count = info_element->data[0]; + network->quiet.period = info_element->data[1]; + network->quiet.duration = info_element->data[2]; + network->quiet.offset = info_element->data[3]; + network->flags |= NETWORK_HAS_QUIET; + break; + + case MFIE_TYPE_IBSS_DFS: + if (network->ibss_dfs) + break; + network->ibss_dfs = kmemdup(info_element->data, + info_element->len, + GFP_ATOMIC); + if (!network->ibss_dfs) + return 1; + network->flags |= NETWORK_HAS_IBSS_DFS; + break; + + case MFIE_TYPE_TPC_REPORT: + network->tpc_report.transmit_power = + info_element->data[0]; + network->tpc_report.link_margin = info_element->data[1]; + network->flags |= NETWORK_HAS_TPC_REPORT; + break; +#endif + default: + IEEE80211_DEBUG_MGMT + ("Unsupported info element: %s (%d)\n", + get_info_element_string(info_element->id), + info_element->id); + break; + } + + length -= sizeof(*info_element) + info_element->len; + info_element = + (struct ieee80211_info_element *)&info_element-> + data[info_element->len]; + } + + if(!network->atheros_cap_exist && !network->broadcom_cap_exist && + !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) + { + network->unknown_cap_exist = true; + } + else + { + network->unknown_cap_exist = false; + } + return 0; +} + +static inline u8 ieee80211_SignalStrengthTranslate( + u8 CurrSS + ) +{ + u8 RetSS; + + // Step 1. Scale mapping. + if(CurrSS >= 71 && CurrSS <= 100) + { + RetSS = 90 + ((CurrSS - 70) / 3); + } + else if(CurrSS >= 41 && CurrSS <= 70) + { + RetSS = 78 + ((CurrSS - 40) / 3); + } + else if(CurrSS >= 31 && CurrSS <= 40) + { + RetSS = 66 + (CurrSS - 30); + } + else if(CurrSS >= 21 && CurrSS <= 30) + { + RetSS = 54 + (CurrSS - 20); + } + else if(CurrSS >= 5 && CurrSS <= 20) + { + RetSS = 42 + (((CurrSS - 5) * 2) / 3); + } + else if(CurrSS == 4) + { + RetSS = 36; + } + else if(CurrSS == 3) + { + RetSS = 27; + } + else if(CurrSS == 2) + { + RetSS = 18; + } + else if(CurrSS == 1) + { + RetSS = 9; + } + else + { + RetSS = CurrSS; + } + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + // Step 2. Smoothing. + + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); + + return RetSS; +} + +long ieee80211_translate_todbm(u8 signal_strength_index )// 0-100 index. +{ + long signal_power; // in dBm. + + // Translate to dBm (x=0.5y-95). + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + + return signal_power; +} + +static inline int ieee80211_network_init( + struct ieee80211_device *ieee, + struct ieee80211_probe_response *beacon, + struct ieee80211_network *network, + struct ieee80211_rx_stats *stats) +{ +#ifdef CONFIG_IEEE80211_DEBUG + //char rates_str[64]; + //char *p; +#endif + + network->qos_data.active = 0; + network->qos_data.supported = 0; + network->qos_data.param_count = 0; + network->qos_data.old_param_count = 0; + + /* Pull out fixed field data */ + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); + network->capability = le16_to_cpu(beacon->capability); + network->last_scanned = jiffies; + network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); + network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); + network->beacon_interval = le32_to_cpu(beacon->beacon_interval); + /* Where to pull this? beacon->listen_interval;*/ + network->listen_interval = 0x0A; + network->rates_len = network->rates_ex_len = 0; + network->last_associate = 0; + network->ssid_len = 0; + network->flags = 0; + network->atim_window = 0; + network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? + 0x3 : 0x0; + network->berp_info_valid = false; + network->broadcom_cap_exist = false; + network->ralink_cap_exist = false; + network->atheros_cap_exist = false; + network->cisco_cap_exist = false; + network->unknown_cap_exist = false; +#ifdef THOMAS_TURBO + network->Turbo_Enable = 0; +#endif +#ifdef ENABLE_DOT11D + network->CountryIeLen = 0; + memset(network->CountryIeBuf, 0, MAX_IE_LEN); +#endif +//Initialize HT parameters + //ieee80211_ht_initialize(&network->bssht); + HTInitializeBssDesc(&network->bssht); + if (stats->freq == IEEE80211_52GHZ_BAND) { + /* for A band (No DS info) */ + network->channel = stats->received_channel; + } else + network->flags |= NETWORK_HAS_CCK; + + network->wpa_ie_len = 0; + network->rsn_ie_len = 0; + + if (ieee80211_parse_info_param + (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats)) + return 1; + + network->mode = 0; + if (stats->freq == IEEE80211_52GHZ_BAND) + network->mode = IEEE_A; + else { + if (network->flags & NETWORK_HAS_OFDM) + network->mode |= IEEE_G; + if (network->flags & NETWORK_HAS_CCK) + network->mode |= IEEE_B; + } + + if (network->mode == 0) { + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + "network.\n", + escape_essid(network->ssid, + network->ssid_len), + MAC_ARG(network->bssid)); + return 1; + } + + if(network->bssht.bdSupportHT){ + if(network->mode == IEEE_A) + network->mode = IEEE_N_5G; + else if(network->mode & (IEEE_G | IEEE_B)) + network->mode = IEEE_N_24G; + } + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) + network->flags |= NETWORK_EMPTY_ESSID; + +#if 1 + stats->signal = 30 + (stats->SignalStrength * 70) / 100; + //stats->signal = ieee80211_SignalStrengthTranslate(stats->signal); + stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25; +#endif + + memcpy(&network->stats, stats, sizeof(network->stats)); + + return 0; +} + +static inline int is_same_network(struct ieee80211_network *src, + struct ieee80211_network *dst, struct ieee80211_device* ieee) +{ + /* A network is only a duplicate if the channel, BSSID, ESSID + * and the capability field (in particular IBSS and BSS) all match. + * We treat all with the same BSSID and channel + * as one network */ + return //((src->ssid_len == dst->ssid_len) && + (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && + (src->channel == dst->channel) && + !memcmp(src->bssid, dst->bssid, ETH_ALEN) && + //!memcmp(src->ssid, dst->ssid, src->ssid_len) && + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && + ((src->capability & WLAN_CAPABILITY_IBSS) == + (dst->capability & WLAN_CAPABILITY_IBSS)) && + ((src->capability & WLAN_CAPABILITY_BSS) == + (dst->capability & WLAN_CAPABILITY_BSS))); +} + +static inline void update_network(struct ieee80211_network *dst, + struct ieee80211_network *src) +{ + int qos_active; + u8 old_param; + + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); + dst->capability = src->capability; + memcpy(dst->rates, src->rates, src->rates_len); + dst->rates_len = src->rates_len; + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); + dst->rates_ex_len = src->rates_ex_len; + if(src->ssid_len > 0) + { + memset(dst->ssid, 0, dst->ssid_len); + dst->ssid_len = src->ssid_len; + memcpy(dst->ssid, src->ssid, src->ssid_len); + } + dst->mode = src->mode; + dst->flags = src->flags; + dst->time_stamp[0] = src->time_stamp[0]; + dst->time_stamp[1] = src->time_stamp[1]; + if (src->flags & NETWORK_HAS_ERP_VALUE) + { + dst->erp_value = src->erp_value; + dst->berp_info_valid = src->berp_info_valid = true; + } + dst->beacon_interval = src->beacon_interval; + dst->listen_interval = src->listen_interval; + dst->atim_window = src->atim_window; + dst->dtim_period = src->dtim_period; + dst->dtim_data = src->dtim_data; + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0]; + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1]; + memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters)); + + dst->bssht.bdSupportHT = src->bssht.bdSupportHT; + dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation; + dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen; + memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen); + dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen; + memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen); + dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer; + dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime; + dst->broadcom_cap_exist = src->broadcom_cap_exist; + dst->ralink_cap_exist = src->ralink_cap_exist; + dst->atheros_cap_exist = src->atheros_cap_exist; + dst->cisco_cap_exist = src->cisco_cap_exist; + dst->unknown_cap_exist = src->unknown_cap_exist; + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); + dst->wpa_ie_len = src->wpa_ie_len; + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); + dst->rsn_ie_len = src->rsn_ie_len; + + dst->last_scanned = jiffies; + /* qos related parameters */ + //qos_active = src->qos_data.active; + qos_active = dst->qos_data.active; + //old_param = dst->qos_data.old_param_count; + old_param = dst->qos_data.param_count; + if(dst->flags & NETWORK_HAS_QOS_MASK){ + //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB + // printk("====>%s(), aifs:%x, %x\n", __FUNCTION__, dst->qos_data.parameters.aifs[0], src->qos_data.parameters.aifs[0]); + // memcpy(&dst->qos_data, &src->qos_data, + // sizeof(struct ieee80211_qos_data)); + } + else { + dst->qos_data.supported = src->qos_data.supported; + dst->qos_data.param_count = src->qos_data.param_count; + } + + if(dst->qos_data.supported == 1) { + dst->QoS_Enable = 1; + if(dst->ssid_len) + IEEE80211_DEBUG_QOS + ("QoS the network %s is QoS supported\n", + dst->ssid); + else + IEEE80211_DEBUG_QOS + ("QoS the network is QoS supported\n"); + } + dst->qos_data.active = qos_active; + dst->qos_data.old_param_count = old_param; + + /* dst->last_associate is not overwritten */ +#if 1 + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. + if(src->wmm_param[0].ac_aci_acm_aifsn|| \ + src->wmm_param[1].ac_aci_acm_aifsn|| \ + src->wmm_param[2].ac_aci_acm_aifsn|| \ + src->wmm_param[1].ac_aci_acm_aifsn) { + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); + } + //dst->QoS_Enable = src->QoS_Enable; +#else + dst->QoS_Enable = 1;//for Rtl8187 simulation +#endif +#ifdef THOMAS_TURBO + dst->Turbo_Enable = src->Turbo_Enable; +#endif + +#ifdef ENABLE_DOT11D + dst->CountryIeLen = src->CountryIeLen; + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); +#endif + + //added by amy for LEAP + dst->bWithAironetIE = src->bWithAironetIE; + dst->bCkipSupported = src->bCkipSupported; + memcpy(dst->CcxRmState,src->CcxRmState,2); + dst->bCcxRmEnable = src->bCcxRmEnable; + dst->MBssidMask = src->MBssidMask; + dst->bMBssidValid = src->bMBssidValid; + memcpy(dst->MBssid,src->MBssid,6); + dst->bWithCcxVerNum = src->bWithCcxVerNum; + dst->BssCcxVerNumber = src->BssCcxVerNumber; + +} + +static inline int is_beacon(__le16 fc) +{ + return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON); +} + +static inline void ieee80211_process_probe_response( + struct ieee80211_device *ieee, + struct ieee80211_probe_response *beacon, + struct ieee80211_rx_stats *stats) +{ + struct ieee80211_network network; + struct ieee80211_network *target; + struct ieee80211_network *oldest = NULL; +#ifdef CONFIG_IEEE80211_DEBUG + struct ieee80211_info_element *info_element = &beacon->info_element[0]; +#endif + unsigned long flags; + short renew; + //u8 wmm_info; + + memset(&network, 0, sizeof(struct ieee80211_network)); + IEEE80211_DEBUG_SCAN( + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + escape_essid(info_element->data, info_element->len), + MAC_ARG(beacon->header.addr3), + (beacon->capability & (1<<0xf)) ? '1' : '0', + (beacon->capability & (1<<0xe)) ? '1' : '0', + (beacon->capability & (1<<0xd)) ? '1' : '0', + (beacon->capability & (1<<0xc)) ? '1' : '0', + (beacon->capability & (1<<0xb)) ? '1' : '0', + (beacon->capability & (1<<0xa)) ? '1' : '0', + (beacon->capability & (1<<0x9)) ? '1' : '0', + (beacon->capability & (1<<0x8)) ? '1' : '0', + (beacon->capability & (1<<0x7)) ? '1' : '0', + (beacon->capability & (1<<0x6)) ? '1' : '0', + (beacon->capability & (1<<0x5)) ? '1' : '0', + (beacon->capability & (1<<0x4)) ? '1' : '0', + (beacon->capability & (1<<0x3)) ? '1' : '0', + (beacon->capability & (1<<0x2)) ? '1' : '0', + (beacon->capability & (1<<0x1)) ? '1' : '0', + (beacon->capability & (1<<0x0)) ? '1' : '0'); + + if (ieee80211_network_init(ieee, beacon, &network, stats)) { + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + escape_essid(info_element->data, + info_element->len), + MAC_ARG(beacon->header.addr3), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + return; + } + +#ifdef ENABLE_DOT11D + // For Asus EeePc request, + // (1) if wireless adapter receive get any 802.11d country code in AP beacon, + // wireless adapter should follow the country code. + // (2) If there is no any country code in beacon, + // then wireless adapter should do active scan from ch1~11 and + // passive scan from ch12~14 + + if( !IsLegalChannel(ieee, network.channel) ) + return; + if(ieee->bGlobalDomain) + { + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) + { + // Case 1: Country code + if(IS_COUNTRY_IE_VALID(ieee) ) + { + if( !IsLegalChannel(ieee, network.channel) ) + { + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); + return; + } + } + // Case 2: No any country code. + else + { + // Filter over channel ch12~14 + if(network.channel > 11) + { + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel); + return; + } + } + } + else + { + // Case 1: Country code + if(IS_COUNTRY_IE_VALID(ieee) ) + { + if( !IsLegalChannel(ieee, network.channel) ) + { + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel); + return; + } + } + // Case 2: No any country code. + else + { + // Filter over channel ch12~14 + if(network.channel > 14) + { + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel); + return; + } + } + } + } +#endif + + /* The network parsed correctly -- so now we scan our known networks + * to see if we can find it in our list. + * + * NOTE: This search is definitely not optimized. Once its doing + * the "right thing" we'll optimize it for efficiency if + * necessary */ + + /* Search for this entry in the list and update it if it is + * already there. */ + + spin_lock_irqsave(&ieee->lock, flags); + + if(is_same_network(&ieee->current_network, &network, ieee)) { + update_network(&ieee->current_network, &network); + if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G) + && ieee->current_network.berp_info_valid){ + if(ieee->current_network.erp_value& ERP_UseProtection) + ieee->current_network.buseprotection = true; + else + ieee->current_network.buseprotection = false; + } + if(is_beacon(beacon->header.frame_ctl)) + { + if(ieee->state == IEEE80211_LINKED) + ieee->LinkDetectInfo.NumRecvBcnInPeriod++; + } + else //hidden AP + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags); + } + + list_for_each_entry(target, &ieee->network_list, list) { + if (is_same_network(target, &network, ieee)) + break; + if ((oldest == NULL) || + (target->last_scanned < oldest->last_scanned)) + oldest = target; + } + + /* If we didn't find a match, then get a new network slot to initialize + * with this beacon's information */ + if (&target->list == &ieee->network_list) { + if (list_empty(&ieee->network_free_list)) { + /* If there are no more slots, expire the oldest */ + list_del(&oldest->list); + target = oldest; + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + "network list.\n", + escape_essid(target->ssid, + target->ssid_len), + MAC_ARG(target->bssid)); + } else { + /* Otherwise just pull from the free list */ + target = list_entry(ieee->network_free_list.next, + struct ieee80211_network, list); + list_del(ieee->network_free_list.next); + } + + +#ifdef CONFIG_IEEE80211_DEBUG + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + escape_essid(network.ssid, + network.ssid_len), + MAC_ARG(network.bssid), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); +#endif + memcpy(target, &network, sizeof(*target)); + list_add_tail(&target->list, &ieee->network_list); + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) + ieee80211_softmac_new_net(ieee,&network); + } else { + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + escape_essid(target->ssid, + target->ssid_len), + MAC_ARG(target->bssid), + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + IEEE80211_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + + /* we have an entry and we are going to update it. But this entry may + * be already expired. In this case we do the same as we found a new + * net and call the new_net handler + */ + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); + //YJ,add,080819,for hidden ap + if(is_beacon(beacon->header.frame_ctl) == 0) + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags); + //if(strncmp(network.ssid, "linksys-c",9) == 0) + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags); + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\ + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK)))) + renew = 1; + //YJ,add,080819,for hidden ap,end + + update_network(target, &network); + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) + ieee80211_softmac_new_net(ieee,&network); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\ + (ieee->state == IEEE80211_LINKED)) { + if(ieee->handle_beacon != NULL) { + ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network); + } + } +} + +void ieee80211_rx_mgt(struct ieee80211_device *ieee, + struct ieee80211_hdr_4addr *header, + struct ieee80211_rx_stats *stats) +{ + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && + ieee->iw_mode == IW_MODE_INFRA && + ieee->state == IEEE80211_LINKED)) + { + tasklet_schedule(&ieee->ps_task); + } + + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) + ieee->last_rx_ps_time = jiffies; + + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + + case IEEE80211_STYPE_BEACON: + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + IEEE80211_DEBUG_SCAN("Beacon\n"); + ieee80211_process_probe_response( + ieee, (struct ieee80211_probe_response *)header, stats); + break; + + case IEEE80211_STYPE_PROBE_RESP: + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + IEEE80211_DEBUG_SCAN("Probe response\n"); + ieee80211_process_probe_response( + ieee, (struct ieee80211_probe_response *)header, stats); + break; + + } +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_rx_mgt); +//EXPORT_SYMBOL(ieee80211_rx); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt); +EXPORT_SYMBOL_NOVERS(ieee80211_rx); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c new file mode 100644 index 00000000000..a50bfc12552 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -0,0 +1,3548 @@ +/* IEEE 802.11 SoftMAC layer + * Copyright (c) 2005 Andrea Merello + * + * Mostly extracted from the rtl8180-sa2400 driver for the + * in-kernel generic ieee802.11 stack. + * + * Few lines might be stolen from other part of the ieee80211 + * stack. Copyright who own it's copyright + * + * WPA code stolen from the ipw2200 driver. + * Copyright who own it's copyright. + * + * released under the GPL + */ + + +#include "ieee80211.h" + +#include +#include +#include +#include +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +u8 rsn_authen_cipher_suite[16][4] = { + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default} + {0x00,0x0F,0xAC,0x03}, //WRAP-historical + {0x00,0x0F,0xAC,0x04}, //CCMP + {0x00,0x0F,0xAC,0x05}, //WEP-104 +}; + +short ieee80211_is_54g(struct ieee80211_network net) +{ + return ((net.rates_ex_len > 0) || (net.rates_len > 4)); +} + +short ieee80211_is_shortslot(struct ieee80211_network net) +{ + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); +} + +/* returns the total length needed for pleacing the RATE MFIE + * tag and the EXTENDED RATE MFIE tag if needed. + * It encludes two bytes per tag for the tag itself and its len + */ +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) +{ + unsigned int rate_len = 0; + + if (ieee->modulation & IEEE80211_CCK_MODULATION) + rate_len = IEEE80211_CCK_RATE_LEN + 2; + + if (ieee->modulation & IEEE80211_OFDM_MODULATION) + + rate_len += IEEE80211_OFDM_RATE_LEN + 2; + + return rate_len; +} + +/* pleace the MFIE rate, tag to the memory (double) poined. + * Then it updates the pointer so that + * it points after the new MFIE tag added. + */ +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & IEEE80211_CCK_MODULATION){ + *tag++ = MFIE_TYPE_RATES; + *tag++ = 4; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; + } + + /* We may add an option for custom rates that specific HW might support */ + *tag_p = tag; +} + +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & IEEE80211_OFDM_MODULATION){ + + *tag++ = MFIE_TYPE_RATES_EX; + *tag++ = 8; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; + + } + + /* We may add an option for custom rates that specific HW might support */ + *tag_p = tag; +} + + +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; //0 + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0x50; + *tag++ = 0xf2; + *tag++ = 0x02;//5 + *tag++ = 0x00; + *tag++ = 0x01; +#ifdef SUPPORT_USPD + if(ieee->current_network.wmm_info & 0x80) { + *tag++ = 0x0f|MAX_SP_Len; + } else { + *tag++ = MAX_SP_Len; + } +#else + *tag++ = MAX_SP_Len; +#endif + *tag_p = tag; +} + +#ifdef THOMAS_TURBO +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) { + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; //0 + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0xe0; + *tag++ = 0x4c; + *tag++ = 0x01;//5 + *tag++ = 0x02; + *tag++ = 0x11; + *tag++ = 0x00; + + *tag_p = tag; + printk(KERN_ALERT "This is enable turbo mode IE process\n"); +} +#endif + +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + int nh; + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM; + +/* + * if the queue is full but we have newer frames then + * just overwrites the oldest. + * + * if (nh == ieee->mgmt_queue_tail) + * return -1; + */ + ieee->mgmt_queue_head = nh; + ieee->mgmt_queue_ring[nh] = skb; + + //return 0; +} + +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) +{ + struct sk_buff *ret; + + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head) + return NULL; + + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; + + ieee->mgmt_queue_tail = + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM; + + return ret; +} + +void init_mgmt_queue(struct ieee80211_device *ieee) +{ + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; +} + +u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + u8 rate; + + // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. + if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M) + rate = 0x0c; + else + rate = ieee->basic_rate & 0x7f; + + if(rate == 0){ + // 2005.01.26, by rcnjko. + if(ieee->mode == IEEE_A|| + ieee->mode== IEEE_N_5G|| + (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK)) + rate = 0x0c; + else + rate = 0x02; + } + + /* + // Data rate of ProbeReq is already decided. Annie, 2005-03-31 + if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) ) + { + if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A) + rate = 0x0c; + else + rate = 0x02; + } + */ + return rate; +} + + +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); + +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +{ + unsigned long flags; + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct ieee80211_hdr_3addr *header= + (struct ieee80211_hdr_3addr *) skb->data; + + cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); + spin_lock_irqsave(&ieee->lock, flags); + + /* called with 2nd param 0, no mgmt lock required */ + ieee80211_sta_wakeup(ieee,0); + + tcb_desc->queue_index = MGNT_QUEUE; + tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + + if(single){ + if(ieee->queue_stop){ + enqueue_mgmt(ieee,skb); + }else{ + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* avoid watchdog triggers */ + // ieee->dev->trans_start = jiffies; + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + //dev_kfree_skb_any(skb);//edit by thomas + } + + spin_unlock_irqrestore(&ieee->lock, flags); + }else{ + spin_unlock_irqrestore(&ieee->lock, flags); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* check wether the managed packet queued greater than 5 */ + if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\ + (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\ + (ieee->queue_stop) ) { + /* insert the skb packet to the management queue */ + /* as for the completion function, it does not need + * to check it any more. + * */ + printk("%s():insert to waitqueue!\n",__FUNCTION__); + skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); + } else { + //printk("TX packet!\n"); + ieee->softmac_hard_start_xmit(skb,ieee->dev); + //dev_kfree_skb_any(skb);//edit by thomas + } + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); + } +} + +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +{ + + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *) skb->data; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); + + tcb_desc->queue_index = MGNT_QUEUE; + tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + //printk("=============>%s()\n", __FUNCTION__); + if(single){ + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* avoid watchdog triggers */ + // ieee->dev->trans_start = jiffies; + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + + }else{ + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + ieee->softmac_hard_start_xmit(skb,ieee->dev); + + } + //dev_kfree_skb_any(skb);//edit by thomas +} + +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) +{ + unsigned int len,rate_len; + u8 *tag; + struct sk_buff *skb; + struct ieee80211_probe_request *req; + + len = ieee->current_network.ssid_len; + + rate_len = ieee80211_MFIE_rate_len(ieee); + + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + + 2 + len + rate_len + ieee->tx_headroom); + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request)); + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + req->header.duration_id = 0; //FIXME: is this OK ? + + memset(req->header.addr1, 0xff, ETH_ALEN); + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memset(req->header.addr3, 0xff, ETH_ALEN); + + tag = (u8 *) skb_put(skb,len+2+rate_len); + + *tag++ = MFIE_TYPE_SSID; + *tag++ = len; + memcpy(tag, ieee->current_network.ssid, len); + tag += len; + + ieee80211_MFIE_Brate(ieee,&tag); + ieee80211_MFIE_Grate(ieee,&tag); + return skb; +} + +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); +void ieee80211_send_beacon(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + if(!ieee->ieee_up) + return; + //unsigned long flags; + skb = ieee80211_get_beacon_(ieee); + + if (skb){ + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_beacons++; + //dev_kfree_skb_any(skb);//edit by thomas + } +// ieee->beacon_timer.expires = jiffies + +// (MSECS( ieee->current_network.beacon_interval -5)); + + //spin_lock_irqsave(&ieee->beacon_lock,flags); + if(ieee->beacon_txing && ieee->ieee_up){ +// if(!timer_pending(&ieee->beacon_timer)) +// add_timer(&ieee->beacon_timer); + mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5))); + } + //spin_unlock_irqrestore(&ieee->beacon_lock,flags); +} + + +void ieee80211_send_beacon_cb(unsigned long _ieee) +{ + struct ieee80211_device *ieee = + (struct ieee80211_device *) _ieee; + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock, flags); + ieee80211_send_beacon(ieee); + spin_unlock_irqrestore(&ieee->beacon_lock, flags); +} + + +void ieee80211_send_probe(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + + skb = ieee80211_probe_req(ieee); + if (skb){ + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_probe_rq++; + //dev_kfree_skb_any(skb);//edit by thomas + } +} + +void ieee80211_send_probe_requests(struct ieee80211_device *ieee) +{ + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ + ieee80211_send_probe(ieee); + ieee80211_send_probe(ieee); + } +} + +/* this performs syncro scan blocking the caller until all channels + * in the allowed channel map has been checked. + */ +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) +{ + short ch = 0; +#ifdef ENABLE_DOT11D + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); +#endif + down(&ieee->scan_sem); + + while(1) + { + + do{ + ch++; + if (ch > MAX_CHANNEL_NUMBER) + goto out; /* scan completed */ +#ifdef ENABLE_DOT11D + }while(!channel_map[ch]); +#else + }while(!ieee->channel_map[ch]); +#endif + + /* this fuction can be called in two situations + * 1- We have switched to ad-hoc mode and we are + * performing a complete syncro scan before conclude + * there are no interesting cell and to create a + * new one. In this case the link state is + * IEEE80211_NOLINK until we found an interesting cell. + * If so the ieee8021_new_net, called by the RX path + * will set the state to IEEE80211_LINKED, so we stop + * scanning + * 2- We are linked and the root uses run iwlist scan. + * So we switch to IEEE80211_LINKED_SCANNING to remember + * that we are still logically linked (not interested in + * new network events, despite for updating the net list, + * but we are temporarly 'unlinked' as the driver shall + * not filter RX frames and the channel is changing. + * So the only situation in witch are interested is to check + * if the state become LINKED because of the #1 situation + */ + + if (ieee->state == IEEE80211_LINKED) + goto out; + ieee->set_chan(ieee->dev, ch); +#ifdef ENABLE_DOT11D + if(channel_map[ch] == 1) +#endif + ieee80211_send_probe_requests(ieee); + + /* this prevent excessive time wait when we + * need to wait for a syncro scan to end.. + */ + if(ieee->state < IEEE80211_LINKED) + ; + else + if (ieee->sync_scan_hurryup) + goto out; + + + msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME); + + } +out: + if(ieee->state < IEEE80211_LINKED){ + ieee->actscanning = false; + up(&ieee->scan_sem); + } + else{ + ieee->sync_scan_hurryup = 0; +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); +#endif + up(&ieee->scan_sem); +} +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/* called both by wq with ieee->lock held */ +void ieee80211_softmac_scan(struct ieee80211_device *ieee) +{ +#if 0 + short watchdog = 0; + do{ + ieee->current_network.channel = + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; + if (watchdog++ > MAX_CHANNEL_NUMBER) + return; /* no good chans */ + + }while(!ieee->channel_map[ieee->current_network.channel]); +#endif + + schedule_task(&ieee->softmac_scan_wq); +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_softmac_scan_wq(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); +#else +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee) +{ +#endif + static short watchdog = 0; + u8 last_channel = ieee->current_network.channel; +#ifdef ENABLE_DOT11D + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); +#endif + if(!ieee->ieee_up) + return; + down(&ieee->scan_sem); + do{ + ieee->current_network.channel = + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; + if (watchdog++ > MAX_CHANNEL_NUMBER) + { + //if current channel is not in channel map, set to default channel. + #ifdef ENABLE_DOT11D + if (!channel_map[ieee->current_network.channel]); + #else + if (!ieee->channel_map[ieee->current_network.channel]); + #endif + ieee->current_network.channel = 6; + goto out; /* no good chans */ + } +#ifdef ENABLE_DOT11D + }while(!channel_map[ieee->current_network.channel]); +#else + }while(!ieee->channel_map[ieee->current_network.channel]); +#endif + if (ieee->scanning == 0 ) + goto out; + ieee->set_chan(ieee->dev, ieee->current_network.channel); +#ifdef ENABLE_DOT11D + if(channel_map[ieee->current_network.channel] == 1) +#endif + ieee80211_send_probe_requests(ieee); + + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); +#else + //ieee->scan_timer.expires = jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME); + if (ieee->scanning == 1) + mod_timer(&ieee->scan_timer,(jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME))); +#endif + + up(&ieee->scan_sem); + return; +out: +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); +#endif + ieee->current_network.channel = last_channel; + ieee->actscanning = false; + watchdog = 0; + ieee->scanning = 0; + up(&ieee->scan_sem); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +void ieee80211_softmac_scan_cb(unsigned long _dev) +{ + unsigned long flags; + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev; + + spin_lock_irqsave(&ieee->lock, flags); + ieee80211_softmac_scan(ieee); + spin_unlock_irqrestore(&ieee->lock, flags); +} +#endif + + +void ieee80211_beacons_start(struct ieee80211_device *ieee) +{ + unsigned long flags; + spin_lock_irqsave(&ieee->beacon_lock,flags); + + ieee->beacon_txing = 1; + ieee80211_send_beacon(ieee); + + spin_unlock_irqrestore(&ieee->beacon_lock,flags); +} + +void ieee80211_beacons_stop(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock,flags); + + ieee->beacon_txing = 0; + del_timer_sync(&ieee->beacon_timer); + + spin_unlock_irqrestore(&ieee->beacon_lock,flags); + +} + + +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) +{ + if(ieee->stop_send_beacons) + ieee->stop_send_beacons(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + ieee80211_beacons_stop(ieee); +} + + +void ieee80211_start_send_beacons(struct ieee80211_device *ieee) +{ + if(ieee->start_send_beacons) + ieee->start_send_beacons(ieee->dev,ieee->basic_rate); + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + ieee80211_beacons_start(ieee); +} + + +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) +{ +// unsigned long flags; + + //ieee->sync_scan_hurryup = 1; + + down(&ieee->scan_sem); +// spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->scanning == 1){ + ieee->scanning = 0; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->softmac_scan_wq); +#else + del_timer_sync(&ieee->scan_timer); +#endif + } + +// spin_unlock_irqrestore(&ieee->lock, flags); + up(&ieee->scan_sem); +} + +void ieee80211_stop_scan(struct ieee80211_device *ieee) +{ + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) + ieee80211_softmac_stop_scan(ieee); + else + ieee->stop_scan(ieee->dev); +} + +/* called with ieee->lock held */ +void ieee80211_start_scan(struct ieee80211_device *ieee) +{ +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee) ) + { + if(IS_COUNTRY_IE_VALID(ieee)) + { + RESET_CIE_WATCHDOG(ieee); + } + } +#endif + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){ + if (ieee->scanning == 0){ + ieee->scanning = 1; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0); +#else + + queue_work(ieee->wq, &ieee->softmac_scan_wq); +#endif +#else + ieee80211_softmac_scan(ieee); +#endif + } + }else + ieee->start_scan(ieee->dev); + +} + +/* called with wx_sem held */ +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) +{ +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee) ) + { + if(IS_COUNTRY_IE_VALID(ieee)) + { + RESET_CIE_WATCHDOG(ieee); + } + } +#endif + ieee->sync_scan_hurryup = 0; + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) + ieee80211_softmac_scan_syncro(ieee); + else + ieee->scan_syncro(ieee->dev); + +} + +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, + struct ieee80211_device *ieee, int challengelen) +{ + struct sk_buff *skb; + struct ieee80211_authentication *auth; + int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom; + + + skb = dev_alloc_skb(len); + if (!skb) return NULL; + + skb_reserve(skb, ieee->tx_headroom); + auth = (struct ieee80211_authentication *) + skb_put(skb, sizeof(struct ieee80211_authentication)); + + auth->header.frame_ctl = IEEE80211_STYPE_AUTH; + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP; + + auth->header.duration_id = 0x013a; //FIXME + + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); + + //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + if(ieee->auth_mode == 0) + auth->algorithm = WLAN_AUTH_OPEN; + else if(ieee->auth_mode == 1) + auth->algorithm = WLAN_AUTH_SHARED_KEY; + else if(ieee->auth_mode == 2) + auth->algorithm = WLAN_AUTH_OPEN;//0x80; + printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm); + auth->transaction = cpu_to_le16(ieee->associate_seq); + ieee->associate_seq++; + + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); + + return skb; + +} + + +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) +{ + u8 *tag; + int beacon_size; + struct ieee80211_probe_response *beacon_buf; + struct sk_buff *skb = NULL; + int encrypt; + int atim_len,erp_len; + struct ieee80211_crypt_data* crypt; + + char *ssid = ieee->current_network.ssid; + int ssid_len = ieee->current_network.ssid_len; + int rate_len = ieee->current_network.rates_len+2; + int rate_ex_len = ieee->current_network.rates_ex_len; + int wpa_ie_len = ieee->wpa_ie_len; + u8 erpinfo_content = 0; + + u8* tmp_ht_cap_buf; + u8 tmp_ht_cap_len=0; + u8* tmp_ht_info_buf; + u8 tmp_ht_info_len=0; + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + u8* tmp_generic_ie_buf=NULL; + u8 tmp_generic_ie_len=0; + + if(rate_ex_len > 0) rate_ex_len+=2; + + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) + atim_len = 4; + else + atim_len = 0; + +#if 1 + if(ieee80211_is_54g(ieee->current_network)) + erp_len = 3; + else + erp_len = 0; +#else + if((ieee->current_network.mode == IEEE_G) + ||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) { + erp_len = 3; + erpinfo_content = 0; + if(ieee->current_network.buseprotection) + erpinfo_content |= ERP_UseProtection; + } + else + erp_len = 0; +#endif + + + crypt = ieee->crypt[ieee->tx_keyidx]; + + + encrypt = ieee->host_encrypt && crypt && crypt->ops && + ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); + //HT ralated element +#if 1 + tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap); + tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); + tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo); + tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); + HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt); + HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt); + + + if(pHTInfo->bRegRT2RTAggregation) + { + tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; + tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); + HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); + } +// printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len); +#endif + beacon_size = sizeof(struct ieee80211_probe_response)+2+ + ssid_len + +3 //channel + +rate_len + +rate_ex_len + +atim_len + +erp_len + +wpa_ie_len + // +tmp_ht_cap_len + // +tmp_ht_info_len + // +tmp_generic_ie_len +// +wmm_len+2 + +ieee->tx_headroom; + skb = dev_alloc_skb(beacon_size); + if (!skb) + return NULL; + skb_reserve(skb, ieee->tx_headroom); + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom)); + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN); + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); + + beacon_buf->header.duration_id = 0; //FIXME + beacon_buf->beacon_interval = + cpu_to_le16(ieee->current_network.beacon_interval); + beacon_buf->capability = + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); + beacon_buf->capability |= + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here + + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); + + crypt = ieee->crypt[ieee->tx_keyidx]; +#if 0 + encrypt = ieee->host_encrypt && crypt && crypt->ops && + (0 == strcmp(crypt->ops->name, "WEP")); +#endif + if (encrypt) + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); + beacon_buf->info_element[0].id = MFIE_TYPE_SSID; + beacon_buf->info_element[0].len = ssid_len; + + tag = (u8*) beacon_buf->info_element[0].data; + + memcpy(tag, ssid, ssid_len); + + tag += ssid_len; + + *(tag++) = MFIE_TYPE_RATES; + *(tag++) = rate_len-2; + memcpy(tag,ieee->current_network.rates,rate_len-2); + tag+=rate_len-2; + + *(tag++) = MFIE_TYPE_DS_SET; + *(tag++) = 1; + *(tag++) = ieee->current_network.channel; + + if(atim_len){ + u16 val16; + *(tag++) = MFIE_TYPE_IBSS_SET; + *(tag++) = 2; + //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); + val16 = cpu_to_le16(ieee->current_network.atim_window); + memcpy((u8 *)tag, (u8 *)&val16, 2); + tag+=2; + } + + if(erp_len){ + *(tag++) = MFIE_TYPE_ERP; + *(tag++) = 1; + *(tag++) = erpinfo_content; + } +#if 0 + //Include High Throuput capability + + *(tag++) = MFIE_TYPE_HT_CAP; + *(tag++) = tmp_ht_cap_len - 2; + memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2); + tag += tmp_ht_cap_len - 2; +#endif + if(rate_ex_len){ + *(tag++) = MFIE_TYPE_RATES_EX; + *(tag++) = rate_ex_len-2; + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2); + tag+=rate_ex_len-2; + } + +#if 0 + //Include High Throuput info + + *(tag++) = MFIE_TYPE_HT_INFO; + *(tag++) = tmp_ht_info_len - 2; + memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2); + tag += tmp_ht_info_len - 2; +#endif + if (wpa_ie_len) + { + if (ieee->iw_mode == IW_MODE_ADHOC) + {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07 + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); + } + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + tag += wpa_ie_len; + } + +#if 0 + // + // Construct Realtek Proprietary Aggregation mode (Set AMPDU Factor to 2, 32k) + // + if(pHTInfo->bRegRT2RTAggregation) + { + (*tag++) = 0xdd; + (*tag++) = tmp_generic_ie_len - 2; + memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2); + tag += tmp_generic_ie_len -2; + + } +#endif +#if 0 + if(ieee->qos_support) + { + (*tag++) = 0xdd; + (*tag++) = wmm_len; + memcpy(tag,QosOui,wmm_len); + tag += wmm_len; + } +#endif + //skb->dev = ieee->dev; + return skb; +} + + +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest) +{ + struct sk_buff *skb; + u8* tag; + + struct ieee80211_crypt_data* crypt; + struct ieee80211_assoc_response_frame *assoc; + short encrypt; + + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom; + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + assoc = (struct ieee80211_assoc_response_frame *) + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); + + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); + memcpy(assoc->header.addr1, dest,ETH_ALEN); + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); + + + if(ieee->short_slot) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); + + if (ieee->host_encrypt) + crypt = ieee->crypt[ieee->tx_keyidx]; + else crypt = NULL; + + encrypt = ( crypt && crypt->ops); + + if (encrypt) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + assoc->status = 0; + assoc->aid = cpu_to_le16(ieee->assoc_id); + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0; + else ieee->assoc_id++; + + tag = (u8*) skb_put(skb, rate_len); + + ieee80211_MFIE_Brate(ieee, &tag); + ieee80211_MFIE_Grate(ieee, &tag); + + return skb; +} + +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest) +{ + struct sk_buff *skb; + struct ieee80211_authentication *auth; + int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1; + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb->len = sizeof(struct ieee80211_authentication); + + auth = (struct ieee80211_authentication *)skb->data; + + auth->status = cpu_to_le16(status); + auth->transaction = cpu_to_le16(2); + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); + + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr1, dest, ETH_ALEN); + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); + return skb; + + +} + +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) +{ + struct sk_buff *skb; + struct ieee80211_hdr_3addr* hdr; + + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); + + if (!skb) + return NULL; + + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr)); + + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); + + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | + (pwr ? IEEE80211_FCTL_PM:0)); + + return skb; + + +} + + +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) +{ + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); + + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest) +{ + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); + + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) +{ + + + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + //unsigned long flags; + + struct ieee80211_assoc_request_frame *hdr; + u8 *tag;//,*rsn_ie; + //short info_addr = 0; + //int i; + //u16 suite_count = 0; + //u8 suit_select = 0; + //unsigned int wpa_len = beacon->wpa_ie_len; + //for HT + u8* ht_cap_buf = NULL; + u8 ht_cap_len=0; + u8* realtek_ie_buf=NULL; + u8 realtek_ie_len=0; + int wpa_ie_len= ieee->wpa_ie_len; + unsigned int ckip_ie_len=0; + unsigned int ccxrm_ie_len=0; + unsigned int cxvernum_ie_len=0; + struct ieee80211_crypt_data* crypt; + int encrypt; + + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); + unsigned int wmm_info_len = beacon->qos_data.supported?9:0; +#ifdef THOMAS_TURBO + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0; +#endif + + int len = 0; + + crypt = ieee->crypt[ieee->tx_keyidx]; + encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len)); + + //Include High Throuput capability && Realtek proprietary + if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) + { + ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap); + ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); + HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt); + if(ieee->pHTInfo->bCurrentRT2RTAggregation) + { + realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; + realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer); + HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len); + + } + } + if(ieee->qos_support){ + wmm_info_len = beacon->qos_data.supported?9:0; + } + + + if(beacon->bCkipSupported) + { + ckip_ie_len = 30+2; + } + if(beacon->bCcxRmEnable) + { + ccxrm_ie_len = 6+2; + } + if( beacon->BssCcxVerNumber >= 2 ) + { + cxvernum_ie_len = 5+2; + } +#ifdef THOMAS_TURBO + len = sizeof(struct ieee80211_assoc_request_frame)+ 2 + + beacon->ssid_len//essid tagged val + + rate_len//rates tagged val + + wpa_ie_len + + wmm_info_len + + turbo_info_len + + ht_cap_len + + realtek_ie_len + + ckip_ie_len + + ccxrm_ie_len + + cxvernum_ie_len + + ieee->tx_headroom; +#else + len = sizeof(struct ieee80211_assoc_request_frame)+ 2 + + beacon->ssid_len//essid tagged val + + rate_len//rates tagged val + + wpa_ie_len + + wmm_info_len + + ht_cap_len + + realtek_ie_len + + ckip_ie_len + + ccxrm_ie_len + + cxvernum_ie_len + + ieee->tx_headroom; +#endif + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + hdr = (struct ieee80211_assoc_request_frame *) + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2); + + + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; + hdr->header.duration_id= 37; //FIXME + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); + + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John + + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); + if (beacon->capability & WLAN_CAPABILITY_PRIVACY ) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here + + if(ieee->short_slot) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); + if (wmm_info_len) //QOS + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); + + hdr->listen_interval = 0xa; //FIXME + + hdr->info_element[0].id = MFIE_TYPE_SSID; + + hdr->info_element[0].len = beacon->ssid_len; + tag = skb_put(skb, beacon->ssid_len); + memcpy(tag, beacon->ssid, beacon->ssid_len); + + tag = skb_put(skb, rate_len); + + ieee80211_MFIE_Brate(ieee, &tag); + ieee80211_MFIE_Grate(ieee, &tag); + // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. + if( beacon->bCkipSupported ) + { + static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" + u8 CcxAironetBuf[30]; + OCTET_STRING osCcxAironetIE; + + memset(CcxAironetBuf, 0,30); + osCcxAironetIE.Octet = CcxAironetBuf; + osCcxAironetIE.Length = sizeof(CcxAironetBuf); + // + // Ref. CCX test plan v3.61, 3.2.3.1 step 13. + // We want to make the device type as "4500-client". 060926, by CCW. + // + memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui)); + + // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23): + // "The CKIP negotiation is started with the associate request from the client to the access point, + // containing an Aironet element with both the MIC and KP bits set." + osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ; + tag = skb_put(skb, ckip_ie_len); + *tag++ = MFIE_TYPE_AIRONET; + *tag++ = osCcxAironetIE.Length; + memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length); + tag += osCcxAironetIE.Length; + } + + if(beacon->bCcxRmEnable) + { + static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; + OCTET_STRING osCcxRmCap; + + osCcxRmCap.Octet = CcxRmCapBuf; + osCcxRmCap.Length = sizeof(CcxRmCapBuf); + tag = skb_put(skb,ccxrm_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = osCcxRmCap.Length; + memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length); + tag += osCcxRmCap.Length; + } + + if( beacon->BssCcxVerNumber >= 2 ) + { + u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; + OCTET_STRING osCcxVerNum; + CcxVerNumBuf[4] = beacon->BssCcxVerNumber; + osCcxVerNum.Octet = CcxVerNumBuf; + osCcxVerNum.Length = sizeof(CcxVerNumBuf); + tag = skb_put(skb,cxvernum_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = osCcxVerNum.Length; + memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length); + tag += osCcxVerNum.Length; + } + //HT cap element + if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ + if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) + { + tag = skb_put(skb, ht_cap_len); + *tag++ = MFIE_TYPE_HT_CAP; + *tag++ = ht_cap_len - 2; + memcpy(tag, ht_cap_buf,ht_cap_len -2); + tag += ht_cap_len -2; + } + } + + + //choose what wpa_supplicant gives to associate. + tag = skb_put(skb, wpa_ie_len); + if (wpa_ie_len){ + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + } + + tag = skb_put(skb,wmm_info_len); + if(wmm_info_len) { + ieee80211_WMM_Info(ieee, &tag); + } +#ifdef THOMAS_TURBO + tag = skb_put(skb,turbo_info_len); + if(turbo_info_len) { + ieee80211_TURBO_Info(ieee, &tag); + } +#endif + + if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ + if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) + { + tag = skb_put(skb, ht_cap_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = ht_cap_len - 2; + memcpy(tag, ht_cap_buf,ht_cap_len - 2); + tag += ht_cap_len -2; + } + + if(ieee->pHTInfo->bCurrentRT2RTAggregation){ + tag = skb_put(skb, realtek_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = realtek_ie_len - 2; + memcpy(tag, realtek_ie_buf,realtek_ie_len -2 ); + } + } +// printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr); +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); + return skb; +} + +void ieee80211_associate_abort(struct ieee80211_device *ieee) +{ + + unsigned long flags; + spin_lock_irqsave(&ieee->lock, flags); + + ieee->associate_seq++; + + /* don't scan, and avoid to have the RX path possibily + * try again to associate. Even do not react to AUTH or + * ASSOC response. Just wait for the retry wq to be scheduled. + * Here we will check if there are good nets to associate + * with, so we retry or just get back to NO_LINK and scanning + */ + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){ + IEEE80211_DEBUG_MGMT("Authentication failed\n"); + ieee->softmac_stats.no_auth_rs++; + }else{ + IEEE80211_DEBUG_MGMT("Association failed\n"); + ieee->softmac_stats.no_ass_rs++; + } + + ieee->state = IEEE80211_ASSOCIATING_RETRY; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \ + IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); +#else + schedule_task(&ieee->associate_retry_wq); +#endif + + spin_unlock_irqrestore(&ieee->lock, flags); +} + +void ieee80211_associate_abort_cb(unsigned long dev) +{ + ieee80211_associate_abort((struct ieee80211_device *) dev); +} + + +void ieee80211_associate_step1(struct ieee80211_device *ieee) +{ + struct ieee80211_network *beacon = &ieee->current_network; + struct sk_buff *skb; + + IEEE80211_DEBUG_MGMT("Stopping scan\n"); + + ieee->softmac_stats.tx_auth_rq++; + skb=ieee80211_authentication_req(beacon, ieee, 0); + + if (!skb) + ieee80211_associate_abort(ieee); + else{ + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ; + IEEE80211_DEBUG_MGMT("Sending authentication request\n"); + //printk(KERN_WARNING "Sending authentication request\n"); + softmac_mgmt_xmit(skb, ieee); + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 + if(!timer_pending(&ieee->associate_timer)){ + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); + } + //dev_kfree_skb_any(skb);//edit by thomas + } +} + +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +{ + u8 *c; + struct sk_buff *skb; + struct ieee80211_network *beacon = &ieee->current_network; +// int hlen = sizeof(struct ieee80211_authentication); + + ieee->associate_seq++; + ieee->softmac_stats.tx_auth_rq++; + + skb = ieee80211_authentication_req(beacon, ieee, chlen+2); + if (!skb) + ieee80211_associate_abort(ieee); + else{ + c = skb_put(skb, chlen+2); + *(c++) = MFIE_TYPE_CHALLENGE; + *(c++) = chlen; + memcpy(c, challenge, chlen); + + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); + + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr )); + + softmac_mgmt_xmit(skb, ieee); + mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); +#if 0 + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); +#endif + //dev_kfree_skb_any(skb);//edit by thomas + } + kfree(challenge); +} + +void ieee80211_associate_step2(struct ieee80211_device *ieee) +{ + struct sk_buff* skb; + struct ieee80211_network *beacon = &ieee->current_network; + + del_timer_sync(&ieee->associate_timer); + + IEEE80211_DEBUG_MGMT("Sending association request\n"); + + ieee->softmac_stats.tx_ass_rq++; + skb=ieee80211_association_req(beacon, ieee); + if (!skb) + ieee80211_associate_abort(ieee); + else{ + softmac_mgmt_xmit(skb, ieee); + mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); +#if 0 + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); +#endif + //dev_kfree_skb_any(skb);//edit by thomas + } +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_complete_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); +#else +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee) +{ +#endif + printk(KERN_INFO "Associated successfully\n"); + ieee->is_roaming = false; + if(ieee80211_is_54g(ieee->current_network) && + (ieee->modulation & IEEE80211_OFDM_MODULATION)){ + + ieee->rate = 108; + printk(KERN_INFO"Using G rates:%d\n", ieee->rate); + }else{ + ieee->rate = 22; + printk(KERN_INFO"Using B rates:%d\n", ieee->rate); + } + if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) + { + printk("Successfully associated, ht enabled\n"); + HTOnAssocRsp(ieee); + } + else + { + printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); + memset(ieee->dot11HTOperationalRateSet, 0, 16); + //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + } + ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500); + // To prevent the immediately calling watch_dog after association. + if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) + { + ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; + ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; + } + ieee->link_change(ieee->dev); + if(ieee->is_silent_reset == 0){ + printk("============>normal associate\n"); + notify_wx_assoc_event(ieee); + } + else if(ieee->is_silent_reset == 1) + { + printk("==================>silent reset associate\n"); + ieee->is_silent_reset = 0; + } + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + netif_carrier_on(ieee->dev); +} + +void ieee80211_associate_complete(struct ieee80211_device *ieee) +{ +// int i; +// struct net_device* dev = ieee->dev; + del_timer_sync(&ieee->associate_timer); + +#if 0 + for(i = 0; i < 6; i++) { + ieee->seq_ctrl[i] = 0; + } +#endif + ieee->state = IEEE80211_LINKED; +#if 0 + if (ieee->pHTInfo->bCurrentHTSupport) + { + printk("Successfully associated, ht enabled\n"); + queue_work(ieee->wq, &ieee->ht_onAssRsp); + } + else + { + printk("Successfully associated, ht not enabled\n"); + memset(ieee->dot11HTOperationalRateSet, 0, 16); + HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + } +#endif + //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_complete_wq); +#else + schedule_task(&ieee->associate_complete_wq); +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_procedure_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); +#else +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee) +{ +#endif + ieee->sync_scan_hurryup = 1; + down(&ieee->wx_sem); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee80211_stop_scan(ieee); + printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); + //ieee->set_chan(ieee->dev, ieee->current_network.channel); + HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + + ieee->associate_seq = 1; + ieee80211_associate_step1(ieee); + + up(&ieee->wx_sem); +} + +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) +{ + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; + int tmp_ssid_len = 0; + + short apset,ssidset,ssidbroad,apmatch,ssidmatch; + + /* we are interested in new new only if we are not associated + * and we are not associating / authenticating + */ + if (ieee->state != IEEE80211_NOLINK) + return; + + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) + return; + + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) + return; + + + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){ + /* if the user specified the AP MAC, we need also the essid + * This could be obtained by beacons or, if the network does not + * broadcast it, it can be put manually. + */ + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 ); + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0'; + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0'); + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0); + ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\ + (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); + + + if ( /* if the user set the AP check if match. + * if the network does not broadcast essid we check the user supplyed ANY essid + * if the network does broadcast and the user does not set essid it is OK + * if the network does broadcast and the user did set essid chech if essid match + */ + ( apset && apmatch && + ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || + /* if the ap is not set, check that the user set the bssid + * and the network does bradcast and that those two bssid matches + */ + (!apset && ssidset && ssidbroad && ssidmatch) + ){ + /* if the essid is hidden replace it with the + * essid provided by the user. + */ + if (!ssidbroad){ + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); + tmp_ssid_len = ieee->current_network.ssid_len; + } + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); + + if (!ssidbroad){ + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); + ieee->current_network.ssid_len = tmp_ssid_len; + } + printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT); + + //ieee->pHTInfo->IOTAction = 0; + HTResetIOTSetting(ieee->pHTInfo); + if (ieee->iw_mode == IW_MODE_INFRA){ + /* Join the network for the first time */ + ieee->AsocRetryCount = 0; + //for HT by amy 080514 + if((ieee->current_network.qos_data.supported == 1) && + // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT)) + ieee->current_network.bssht.bdSupportHT) +/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/ + { + // ieee->pHTInfo->bCurrentHTSupport = true; + HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); + } + else + { + ieee->pHTInfo->bCurrentHTSupport = false; + } + + ieee->state = IEEE80211_ASSOCIATING; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + }else{ + if(ieee80211_is_54g(ieee->current_network) && + (ieee->modulation & IEEE80211_OFDM_MODULATION)){ + ieee->rate = 108; + ieee->SetWirelessMode(ieee->dev, IEEE_G); + printk(KERN_INFO"Using G rates\n"); + }else{ + ieee->rate = 22; + ieee->SetWirelessMode(ieee->dev, IEEE_B); + printk(KERN_INFO"Using B rates\n"); + } + memset(ieee->dot11HTOperationalRateSet, 0, 16); + //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + ieee->state = IEEE80211_LINKED; + } + + } + } + +} + +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) +{ + unsigned long flags; + struct ieee80211_network *target; + + spin_lock_irqsave(&ieee->lock, flags); + + list_for_each_entry(target, &ieee->network_list, list) { + + /* if the state become different that NOLINK means + * we had found what we are searching for + */ + + if (ieee->state != IEEE80211_NOLINK) + break; + + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) + ieee80211_softmac_new_net(ieee, target); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + +} + + +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) +{ + struct ieee80211_authentication *a; + u8 *t; + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len); + return 0xcafe; + } + *challenge = NULL; + a = (struct ieee80211_authentication*) skb->data; + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){ + t = skb->data + sizeof(struct ieee80211_authentication); + + if(*(t++) == MFIE_TYPE_CHALLENGE){ + *chlen = *(t++); + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + memcpy(*challenge, t, *chlen); + } + } + + return cpu_to_le16(a->status); + +} + + +int auth_rq_parse(struct sk_buff *skb,u8* dest) +{ + struct ieee80211_authentication *a; + + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len); + return -1; + } + a = (struct ieee80211_authentication*) skb->data; + + memcpy(dest,a->header.addr2, ETH_ALEN); + + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; + + return WLAN_STATUS_SUCCESS; +} + +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) +{ + u8 *tag; + u8 *skbend; + u8 *ssid=NULL; + u8 ssidlen = 0; + + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *) skb->data; + + if (skb->len < sizeof (struct ieee80211_hdr_3addr )) + return -1; /* corrupted */ + + memcpy(src,header->addr2, ETH_ALEN); + + skbend = (u8*)skb->data + skb->len; + + tag = skb->data + sizeof (struct ieee80211_hdr_3addr ); + + while (tag+1 < skbend){ + if (*tag == 0){ + ssid = tag+2; + ssidlen = *(tag+1); + break; + } + tag++; /* point to the len field */ + tag = tag + *(tag); /* point to the last data byte of the tag */ + tag++; /* point to the next tag */ + } + + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src)); + if (ssidlen == 0) return 1; + + if (!ssid) return 1; /* ssid not found in tagged param */ + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); + +} + +int assoc_rq_parse(struct sk_buff *skb,u8* dest) +{ + struct ieee80211_assoc_request_frame *a; + + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - + sizeof(struct ieee80211_info_element))) { + + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len); + return -1; + } + + a = (struct ieee80211_assoc_request_frame*) skb->data; + + memcpy(dest,a->header.addr2,ETH_ALEN); + + return 0; +} + +static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid) +{ + struct ieee80211_assoc_response_frame *response_head; + u16 status_code; + + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){ + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + return 0xcafe; + } + + response_head = (struct ieee80211_assoc_response_frame*) skb->data; + *aid = le16_to_cpu(response_head->aid) & 0x3fff; + + status_code = le16_to_cpu(response_head->status); + if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \ + status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&& + ((ieee->mode == IEEE_G) && + (ieee->current_network.mode == IEEE_N_24G) && + (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) { + ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE; + }else { + ieee->AsocRetryCount = 0; + } + + return le16_to_cpu(response_head->status); +} + +static inline void +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + + //IEEE80211DMESG("Rx probe"); + ieee->softmac_stats.rx_probe_rq++; + //DMESG("Dest is "MACSTR, MAC2STR(dest)); + if (probe_rq_parse(ieee, skb, dest)){ + //IEEE80211DMESG("Was for me!"); + ieee->softmac_stats.tx_probe_rs++; + ieee80211_resp_to_probe(ieee, dest); + } +} + +static inline void +ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + int status; + //IEEE80211DMESG("Rx probe"); + ieee->softmac_stats.rx_auth_rq++; + + if ((status = auth_rq_parse(skb, dest))!= -1){ + ieee80211_resp_to_auth(ieee, status, dest); + } + //DMESG("Dest is "MACSTR, MAC2STR(dest)); + +} + +static inline void +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +{ + + u8 dest[ETH_ALEN]; + //unsigned long flags; + + ieee->softmac_stats.rx_ass_rq++; + if (assoc_rq_parse(skb,dest) != -1){ + ieee80211_resp_to_assoc_rq(ieee, dest); + } + + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); + //FIXME + #if 0 + spin_lock_irqsave(&ieee->lock,flags); + add_associate(ieee,dest); + spin_unlock_irqrestore(&ieee->lock,flags); + #endif +} + + + +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) +{ + + struct sk_buff *buf = ieee80211_null_func(ieee, pwr); + + if (buf) + softmac_ps_mgmt_xmit(buf, ieee); + +} + + +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) +{ + int timeout = ieee->ps_timeout; + u8 dtim; + /*if(ieee->ps == IEEE80211_PS_DISABLED || + ieee->iw_mode != IW_MODE_INFRA || + ieee->state != IEEE80211_LINKED) + + return 0; + */ + dtim = ieee->current_network.dtim_data; + //printk("DTIM\n"); + if(!(dtim & IEEE80211_DTIM_VALID)) + return 0; + timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval + //printk("VALID\n"); + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; + + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps)) + return 2; + + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) + return 0; + + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) + return 0; + + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) + return 0; + + if(time_l){ + *time_l = ieee->current_network.last_dtim_sta_time[0] + + (ieee->current_network.beacon_interval); + // * ieee->current_network.dtim_period) * 1000; + } + + if(time_h){ + *time_h = ieee->current_network.last_dtim_sta_time[1]; + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) + *time_h += 1; + } + + return 1; + + +} + +inline void ieee80211_sta_ps(struct ieee80211_device *ieee) +{ + + u32 th,tl; + short sleep; + + unsigned long flags,flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if((ieee->ps == IEEE80211_PS_DISABLED || + ieee->iw_mode != IW_MODE_INFRA || + ieee->state != IEEE80211_LINKED)){ + + // #warning CHECK_LOCK_HERE + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + ieee80211_sta_wakeup(ieee, 1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); + /* 2 wake, 1 sleep, 0 do nothing */ + if(sleep == 0) + goto out; + + if(sleep == 1){ + + if(ieee->sta_sleep == 1) + ieee->enter_sleep_state(ieee->dev,th,tl); + + else if(ieee->sta_sleep == 0){ + // printk("send null 1\n"); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + if(ieee->ps_is_queue_empty(ieee->dev)){ + + + ieee->sta_sleep = 2; + + ieee->ack_tx_to_ieee = 1; + + ieee80211_sta_ps_send_null_frame(ieee,1); + + ieee->ps_th = th; + ieee->ps_tl = tl; + } + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + + } + + + }else if(sleep == 2){ +//#warning CHECK_LOCK_HERE + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + ieee80211_sta_wakeup(ieee,1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + +out: + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) +{ + if(ieee->sta_sleep == 0){ + if(nl){ + printk("Warning: driver is probably failing to report TX ps error\n"); + ieee->ack_tx_to_ieee = 1; + ieee80211_sta_ps_send_null_frame(ieee, 0); + } + return; + + } + + if(ieee->sta_sleep == 1) + ieee->sta_wake_up(ieee->dev); + + ieee->sta_sleep = 0; + + if(nl){ + ieee->ack_tx_to_ieee = 1; + ieee80211_sta_ps_send_null_frame(ieee, 0); + } +} + +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) +{ + unsigned long flags,flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if(ieee->sta_sleep == 2){ + /* Null frame with PS bit set */ + if(success){ + ieee->sta_sleep = 1; + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); + } + /* if the card report not success we can't be sure the AP + * has not RXed so we can't assume the AP believe us awake + */ + } + /* 21112005 - tx again null without PS bit if lost */ + else { + + if((ieee->sta_sleep == 0) && !success){ + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + ieee80211_sta_ps_send_null_frame(ieee, 0); + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + } + spin_unlock_irqrestore(&ieee->lock, flags); +} +void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb) +{ + struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; + u8* act = ieee80211_get_payload(header); + u8 tmp = 0; +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + if (act == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n"); + return; + } + tmp = *act; + act ++; + switch (tmp) + { + case ACT_CAT_BA: + if (*act == ACT_ADDBAREQ) + ieee80211_rx_ADDBAReq(ieee, skb); + else if (*act == ACT_ADDBARSP) + ieee80211_rx_ADDBARsp(ieee, skb); + else if (*act == ACT_DELBA) + ieee80211_rx_DELBA(ieee, skb); + break; + default: +// if (net_ratelimit()) +// IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp); + break; + } + return; + +} +inline int +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, u16 type, + u16 stype) +{ + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; + u16 errcode; + u8* challenge; + int chlen=0; + int aid; + struct ieee80211_assoc_response_frame *assoc_resp; +// struct ieee80211_info_element *info_element; + bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode + + if(!ieee->proto_started) + return 0; +#if 0 + printk("%d, %d, %d, %d\n", ieee->sta_sleep, ieee->ps, ieee->iw_mode, ieee->state); + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && + ieee->iw_mode == IW_MODE_INFRA && + ieee->state == IEEE80211_LINKED)) + + tasklet_schedule(&ieee->ps_task); + + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) + ieee->last_rx_ps_time = jiffies; +#endif + + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + + case IEEE80211_STYPE_ASSOC_RESP: + case IEEE80211_STYPE_REASSOC_RESP: + + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && + ieee->iw_mode == IW_MODE_INFRA){ + struct ieee80211_network network_resp; + struct ieee80211_network *network = &network_resp; + + if (0 == (errcode=assoc_parse(ieee,skb, &aid))){ + ieee->state=IEEE80211_LINKED; + ieee->assoc_id = aid; + ieee->softmac_stats.rx_ass_ok++; + /* station support qos */ + /* Let the register setting defaultly with Legacy station */ + if(ieee->qos_support) { + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data; + memset(network, 0, sizeof(*network)); + if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\ + rx_stats->len - sizeof(*assoc_resp),\ + network,rx_stats)){ + return 1; + } + else + { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network. + memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); + memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); + } + if (ieee->handle_assoc_response != NULL) + ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network); + } + ieee80211_associate_complete(ieee); + } else { + /* aid could not been allocated */ + ieee->softmac_stats.rx_ass_err++; + printk( + "Association response status code 0x%x\n", + errcode); + IEEE80211_DEBUG_MGMT( + "Association response status code 0x%x\n", + errcode); + if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + } else { + ieee80211_associate_abort(ieee); + } + } + } + break; + + case IEEE80211_STYPE_ASSOC_REQ: + case IEEE80211_STYPE_REASSOC_REQ: + + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->iw_mode == IW_MODE_MASTER) + + ieee80211_rx_assoc_rq(ieee, skb); + break; + + case IEEE80211_STYPE_AUTH: + + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){ + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && + ieee->iw_mode == IW_MODE_INFRA){ + + IEEE80211_DEBUG_MGMT("Received authentication response"); + + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){ + if(ieee->open_wep || !challenge){ + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; + ieee->softmac_stats.rx_auth_rs_ok++; + if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE)) + { + if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) + { + // WEP or TKIP encryption + if(IsHTHalfNmodeAPs(ieee)) + { + bSupportNmode = true; + bHalfSupportNmode = true; + } + else + { + bSupportNmode = false; + bHalfSupportNmode = false; + } + printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode); + } + } + /* Dummy wirless mode setting to avoid encryption issue */ + if(bSupportNmode) { + //N mode setting + ieee->SetWirelessMode(ieee->dev, \ + ieee->current_network.mode); + }else{ + //b/g mode setting + /*TODO*/ + ieee->SetWirelessMode(ieee->dev, IEEE_G); + } + + if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true) + { + printk("===============>entern half N mode\n"); + ieee->bHalfWirelessN24GMode = true; + } + else + ieee->bHalfWirelessN24GMode = false; + + ieee80211_associate_step2(ieee); + }else{ + ieee80211_auth_challenge(ieee, challenge, chlen); + } + }else{ + ieee->softmac_stats.rx_auth_rs_err++; + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + + printk("Authentication respose status code 0x%x",errcode); + ieee80211_associate_abort(ieee); + } + + }else if (ieee->iw_mode == IW_MODE_MASTER){ + ieee80211_rx_auth_rq(ieee, skb); + } + } + break; + + case IEEE80211_STYPE_PROBE_REQ: + + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && + ((ieee->iw_mode == IW_MODE_ADHOC || + ieee->iw_mode == IW_MODE_MASTER) && + ieee->state == IEEE80211_LINKED)){ + ieee80211_rx_probe_rq(ieee, skb); + } + break; + + case IEEE80211_STYPE_DISASSOC: + case IEEE80211_STYPE_DEAUTH: + /* FIXME for now repeat all the association procedure + * both for disassociation and deauthentication + */ + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == IEEE80211_LINKED && + ieee->iw_mode == IW_MODE_INFRA){ + + ieee->state = IEEE80211_ASSOCIATING; + ieee->softmac_stats.reassoc++; + ieee->is_roaming = true; + ieee80211_disassociate(ieee); + // notify_wx_assoc_event(ieee); + //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + RemovePeerTS(ieee, header->addr2); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + } + break; + case IEEE80211_STYPE_MANAGE_ACT: + ieee80211_process_action(ieee,skb); + break; + default: + return -1; + break; + } + + //dev_kfree_skb_any(skb); + return 0; +} + +/* following are for a simplier TX queue management. + * Instead of using netif_[stop/wake]_queue the driver + * will uses these two function (plus a reset one), that + * will internally uses the kernel netif_* and takes + * care of the ieee802.11 fragmentation. + * So the driver receives a fragment per time and might + * call the stop function when it want without take care + * to have enought room to TX an entire packet. + * This might be useful if each fragment need it's own + * descriptor, thus just keep a total free memory > than + * the max fragmentation treshold is not enought.. If the + * ieee802.11 stack passed a TXB struct then you needed + * to keep N free descriptors where + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD + * In this way you need just one and the 802.11 stack + * will take care of buffering fragments and pass them to + * to the driver later, when it wakes the queue. + */ +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) +{ + + unsigned int queue_index = txb->queue_index; + unsigned long flags; + int i; + cb_desc *tcb_desc = NULL; + + spin_lock_irqsave(&ieee->lock,flags); + + /* called with 2nd parm 0, no tx mgmt lock required */ + ieee80211_sta_wakeup(ieee,0); + + /* update the tx status */ +// ieee->stats.tx_bytes += txb->payload_size; +// ieee->stats.tx_packets++; + tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); + if(tcb_desc->bMulticast) { + ieee->stats.multicast++; + } +#if 1 + /* if xmit available, just xmit it immediately, else just insert it to the wait queue */ + for(i = 0; i < txb->nr_frags; i++) { +#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE + if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) || +#else + if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) || +#endif + (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\ + (ieee->queue_stop)) { + /* insert the skb packet to the wait queue */ + /* as for the completion function, it does not need + * to check it any more. + * */ + //printk("error:no descriptor left@queue_index %d\n", queue_index); + //ieee80211_stop_queue(ieee); +#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE + skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); +#else + skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); +#endif + }else{ + ieee->softmac_data_hard_start_xmit( + txb->fragments[i], + ieee->dev,ieee->rate); + //ieee->stats.tx_packets++; + //ieee->stats.tx_bytes += txb->fragments[i]->len; + //ieee->dev->trans_start = jiffies; + } + } +#endif + ieee80211_txb_free(txb); + +//exit: + spin_unlock_irqrestore(&ieee->lock,flags); + +} + +/* called with ieee->lock acquired */ +void ieee80211_resume_tx(struct ieee80211_device *ieee) +{ + int i; + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { + + if (ieee->queue_stop){ + ieee->tx_pending.frag = i; + return; + }else{ + + ieee->softmac_data_hard_start_xmit( + ieee->tx_pending.txb->fragments[i], + ieee->dev,ieee->rate); + //(i+1)tx_pending.txb->nr_frags); + ieee->stats.tx_packets++; + // ieee->dev->trans_start = jiffies; + } + } + + + ieee80211_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; +} + + +void ieee80211_reset_queue(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->lock,flags); + init_mgmt_queue(ieee); + if (ieee->tx_pending.txb){ + ieee80211_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; + } + ieee->queue_stop = 0; + spin_unlock_irqrestore(&ieee->lock,flags); + +} + +void ieee80211_wake_queue(struct ieee80211_device *ieee) +{ + + unsigned long flags; + struct sk_buff *skb; + struct ieee80211_hdr_3addr *header; + + spin_lock_irqsave(&ieee->lock,flags); + if (! ieee->queue_stop) goto exit; + + ieee->queue_stop = 0; + + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){ + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){ + + header = (struct ieee80211_hdr_3addr *) skb->data; + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + //dev_kfree_skb_any(skb);//edit by thomas + } + } + if (!ieee->queue_stop && ieee->tx_pending.txb) + ieee80211_resume_tx(ieee); + + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){ + ieee->softmac_stats.swtxawake++; + netif_wake_queue(ieee->dev); + } + +exit : + spin_unlock_irqrestore(&ieee->lock,flags); +} + + +void ieee80211_stop_queue(struct ieee80211_device *ieee) +{ + //unsigned long flags; + //spin_lock_irqsave(&ieee->lock,flags); + + if (! netif_queue_stopped(ieee->dev)){ + netif_stop_queue(ieee->dev); + ieee->softmac_stats.swtxstop++; + } + ieee->queue_stop = 1; + //spin_unlock_irqrestore(&ieee->lock,flags); + +} + + +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) +{ + + get_random_bytes(ieee->current_network.bssid, ETH_ALEN); + + /* an IBSS cell address must have the two less significant + * bits of the first byte = 2 + */ + ieee->current_network.bssid[0] &= ~0x01; + ieee->current_network.bssid[0] |= 0x02; +} + +/* called in user context only */ +void ieee80211_start_master_bss(struct ieee80211_device *ieee) +{ + ieee->assoc_id = 1; + + if (ieee->current_network.ssid_len == 0){ + strncpy(ieee->current_network.ssid, + IEEE80211_DEFAULT_TX_ESSID, + IW_ESSID_MAX_SIZE); + + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->state = IEEE80211_LINKED; + ieee->link_change(ieee->dev); + notify_wx_assoc_event(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); +} + +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) +{ + if(ieee->raw_tx){ + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + } +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_start_ibss_wq(struct work_struct *work) +{ + + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); +#else +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee) +{ +#endif + /* iwconfig mode ad-hoc will schedule this and return + * on the other hand this will block further iwconfig SET + * operations because of the wx_sem hold. + * Anyway some most set operations set a flag to speed-up + * (abort) this wq (when syncro scanning) before sleeping + * on the semaphore + */ + if(!ieee->proto_started){ + printk("==========oh driver down return\n"); + return; + } + down(&ieee->wx_sem); + + if (ieee->current_network.ssid_len == 0){ + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID); + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + + /* check if we have this cell in our network list */ + ieee80211_softmac_check_all_nets(ieee); + + +#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d. +// if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) + if (ieee->state == IEEE80211_NOLINK) + ieee->current_network.channel = 6; +#endif + /* if not then the state is not linked. Maybe the user swithced to + * ad-hoc mode just after being in monitor mode, or just after + * being very few time in managed mode (so the card have had no + * time to scan all the chans..) or we have just run up the iface + * after setting ad-hoc mode. So we have to give another try.. + * Here, in ibss mode, should be safe to do this without extra care + * (in bss mode we had to make sure no-one tryed to associate when + * we had just checked the ieee->state and we was going to start the + * scan) beacause in ibss mode the ieee80211_new_net function, when + * finds a good net, just set the ieee->state to IEEE80211_LINKED, + * so, at worst, we waste a bit of time to initiate an unneeded syncro + * scan, that will stop at the first round because it sees the state + * associated. + */ + if (ieee->state == IEEE80211_NOLINK) + ieee80211_start_scan_syncro(ieee); + + /* the network definitively is not here.. create a new cell */ + if (ieee->state == IEEE80211_NOLINK){ + printk("creating new IBSS cell\n"); + if(!ieee->wap_set) + ieee80211_randomize_cell(ieee); + + if(ieee->modulation & IEEE80211_CCK_MODULATION){ + + ieee->current_network.rates_len = 4; + + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; + + }else + ieee->current_network.rates_len = 0; + + if(ieee->modulation & IEEE80211_OFDM_MODULATION){ + ieee->current_network.rates_ex_len = 8; + + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; + + ieee->rate = 108; + }else{ + ieee->current_network.rates_ex_len = 0; + ieee->rate = 22; + } + + // By default, WMM function will be disabled in IBSS mode + ieee->current_network.QoS_Enable = 0; + ieee->SetWirelessMode(ieee->dev, IEEE_G); + ieee->current_network.atim_window = 0; + ieee->current_network.capability = WLAN_CAPABILITY_IBSS; + if(ieee->short_slot) + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; + + } + + ieee->state = IEEE80211_LINKED; + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->link_change(ieee->dev); + + notify_wx_assoc_event(ieee); + + ieee80211_start_send_beacons(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + netif_carrier_on(ieee->dev); + + up(&ieee->wx_sem); +} + +inline void ieee80211_start_ibss(struct ieee80211_device *ieee) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); +#else + schedule_task(&ieee->start_ibss_wq); +#endif +} + +/* this is called only in user context, with wx_sem held */ +void ieee80211_start_bss(struct ieee80211_device *ieee) +{ + unsigned long flags; +#ifdef ENABLE_DOT11D + // + // Ref: 802.11d 11.1.3.3 + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. + // + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) + { + if(! ieee->bGlobalDomain) + { + return; + } + } +#endif + /* check if we have already found the net we + * are interested in (if any). + * if not (we are disassociated and we are not + * in associating / authenticating phase) start the background scanning. + */ + ieee80211_softmac_check_all_nets(ieee); + + /* ensure no-one start an associating process (thus setting + * the ieee->state to ieee80211_ASSOCIATING) while we + * have just cheked it and we are going to enable scan. + * The ieee80211_new_net function is always called with + * lock held (from both ieee80211_softmac_check_all_nets and + * the rx path), so we cannot be in the middle of such function + */ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->state == IEEE80211_NOLINK){ + ieee->actscanning = true; + ieee80211_start_scan(ieee); + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +/* called only in userspace context */ +void ieee80211_disassociate(struct ieee80211_device *ieee) +{ + + + netif_carrier_off(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) + ieee80211_reset_queue(ieee); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); +#ifdef ENABLE_DOT11D + if(IS_DOT11D_ENABLE(ieee)) + Dot11d_Reset(ieee); +#endif + ieee->state = IEEE80211_NOLINK; + ieee->is_set_key = false; + ieee->link_change(ieee->dev); + //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + notify_wx_assoc_event(ieee); + +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void ieee80211_associate_retry_wq(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); +#else +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee) +{ +#endif + unsigned long flags; + + down(&ieee->wx_sem); + if(!ieee->proto_started) + goto exit; + + if(ieee->state != IEEE80211_ASSOCIATING_RETRY) + goto exit; + + /* until we do not set the state to IEEE80211_NOLINK + * there are no possibility to have someone else trying + * to start an association procdure (we get here with + * ieee->state = IEEE80211_ASSOCIATING). + * When we set the state to IEEE80211_NOLINK it is possible + * that the RX path run an attempt to associate, but + * both ieee80211_softmac_check_all_nets and the + * RX path works with ieee->lock held so there are no + * problems. If we are still disassociated then start a scan. + * the lock here is necessary to ensure no one try to start + * an association procedure when we have just checked the + * state and we are going to start the scan. + */ + ieee->beinretry = true; + ieee->state = IEEE80211_NOLINK; + + ieee80211_softmac_check_all_nets(ieee); + + spin_lock_irqsave(&ieee->lock, flags); + + if(ieee->state == IEEE80211_NOLINK) + { + ieee->is_roaming= false; + ieee->actscanning = true; + ieee80211_start_scan(ieee); + } + spin_unlock_irqrestore(&ieee->lock, flags); + + ieee->beinretry = false; +exit: + up(&ieee->wx_sem); +} + +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) +{ + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + struct sk_buff *skb; + struct ieee80211_probe_response *b; + + skb = ieee80211_probe_resp(ieee, broadcast_addr); + + if (!skb) + return NULL; + + b = (struct ieee80211_probe_response *) skb->data; + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); + + return skb; + +} + +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) +{ + struct sk_buff *skb; + struct ieee80211_probe_response *b; + + skb = ieee80211_get_beacon_(ieee); + if(!skb) + return NULL; + + b = (struct ieee80211_probe_response *) skb->data; + b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + return skb; +} + +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) +{ + ieee->sync_scan_hurryup = 1; + down(&ieee->wx_sem); + ieee80211_stop_protocol(ieee); + up(&ieee->wx_sem); +} + + +void ieee80211_stop_protocol(struct ieee80211_device *ieee) +{ + if (!ieee->proto_started) + return; + + ieee->proto_started = 0; + + ieee80211_stop_send_beacons(ieee); + del_timer_sync(&ieee->associate_timer); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->associate_retry_wq); + cancel_delayed_work(&ieee->start_ibss_wq); +#endif + ieee80211_stop_scan(ieee); + + ieee80211_disassociate(ieee); + RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS +} + +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) +{ + ieee->sync_scan_hurryup = 0; + down(&ieee->wx_sem); + ieee80211_start_protocol(ieee); + up(&ieee->wx_sem); +} + +void ieee80211_start_protocol(struct ieee80211_device *ieee) +{ + short ch = 0; + int i = 0; + if (ieee->proto_started) + return; + + ieee->proto_started = 1; + + if (ieee->current_network.channel == 0){ + do{ + ch++; + if (ch > MAX_CHANNEL_NUMBER) + return; /* no channel found */ +#ifdef ENABLE_DOT11D + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]); +#else + }while(!ieee->channel_map[ch]); +#endif + ieee->current_network.channel = ch; + } + + if (ieee->current_network.beacon_interval == 0) + ieee->current_network.beacon_interval = 100; +// printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); +// ieee->set_chan(ieee->dev,ieee->current_network.channel); + + for(i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } + + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. + + + /* if the user set the MAC of the ad-hoc cell and then + * switch to managed mode, shall we make sure that association + * attempts does not fail just because the user provide the essid + * and the nic is still checking for the AP MAC ?? + */ + if (ieee->iw_mode == IW_MODE_INFRA) + ieee80211_start_bss(ieee); + + else if (ieee->iw_mode == IW_MODE_ADHOC) + ieee80211_start_ibss(ieee); + + else if (ieee->iw_mode == IW_MODE_MASTER) + ieee80211_start_master_bss(ieee); + + else if(ieee->iw_mode == IW_MODE_MONITOR) + ieee80211_start_monitor_mode(ieee); +} + + +#define DRV_NAME "Ieee80211" +void ieee80211_softmac_init(struct ieee80211_device *ieee) +{ + int i; + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); + + ieee->state = IEEE80211_NOLINK; + ieee->sync_scan_hurryup = 0; + for(i = 0; i < 5; i++) { + ieee->seq_ctrl[i] = 0; + } +#ifdef ENABLE_DOT11D + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); + if (!ieee->pDot11dInfo) + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); + memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO)); +#endif + //added for AP roaming + ieee->LinkDetectInfo.SlotNum = 2; + ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; + ieee->LinkDetectInfo.NumRecvDataInPeriod=0; + + ieee->assoc_id = 0; + ieee->queue_stop = 0; + ieee->scanning = 0; + ieee->softmac_features = 0; //so IEEE2100-like driver are happy + ieee->wap_set = 0; + ieee->ssid_set = 0; + ieee->proto_started = 0; + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; + ieee->rate = 22; + ieee->ps = IEEE80211_PS_DISABLED; + ieee->sta_sleep = 0; + ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7 + ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15 + ieee->Regdot11HTOperationalRateSet[4]= 0x01; + //added by amy + ieee->actscanning = false; + ieee->beinretry = false; + ieee->is_set_key = false; + init_mgmt_queue(ieee); + + ieee->sta_edca_param[0] = 0x0000A403; + ieee->sta_edca_param[1] = 0x0000A427; + ieee->sta_edca_param[2] = 0x005E4342; + ieee->sta_edca_param[3] = 0x002F3262; + ieee->aggregation = true; + ieee->enable_rx_imm_BA = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + init_timer(&ieee->scan_timer); + ieee->scan_timer.data = (unsigned long)ieee; + ieee->scan_timer.function = ieee80211_softmac_scan_cb; +#endif + ieee->tx_pending.txb = NULL; + + init_timer(&ieee->associate_timer); + ieee->associate_timer.data = (unsigned long)ieee; + ieee->associate_timer.function = ieee80211_associate_abort_cb; + + init_timer(&ieee->beacon_timer); + ieee->beacon_timer.data = (unsigned long) ieee; + ieee->beacon_timer.function = ieee80211_send_beacon_cb; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#ifdef PF_SYNCTHREAD + ieee->wq = create_workqueue(DRV_NAME,0); +#else + ieee->wq = create_workqueue(DRV_NAME); +#endif +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq); + INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); + INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq); + INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq); + INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq); + INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq); + +#else + INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee); + INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee); + INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee); + INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee); + INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee); + INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee); +#endif + +#else + tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee); + tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee); + tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee); + tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee); + tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee); + tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee); +#endif + sema_init(&ieee->wx_sem, 1); + sema_init(&ieee->scan_sem, 1); + + spin_lock_init(&ieee->mgmt_tx_lock); + spin_lock_init(&ieee->beacon_lock); + + tasklet_init(&ieee->ps_task, + (void(*)(unsigned long)) ieee80211_sta_ps, + (unsigned long)ieee); + +} + +void ieee80211_softmac_free(struct ieee80211_device *ieee) +{ + down(&ieee->wx_sem); +#ifdef ENABLE_DOT11D + if(NULL != ieee->pDot11dInfo) + { + kfree(ieee->pDot11dInfo); + ieee->pDot11dInfo = NULL; + } +#endif + del_timer_sync(&ieee->associate_timer); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->associate_retry_wq); + destroy_workqueue(ieee->wq); +#endif + + up(&ieee->wx_sem); +} + +/******************************************************** + * Start of WPA code. * + * this is stolen from the ipw2200 driver * + ********************************************************/ + + +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) +{ + /* This is called when wpa_supplicant loads and closes the driver + * interface. */ + printk("%s WPA\n",value ? "enabling" : "disabling"); + ieee->wpa_enabled = value; + return 0; +} + + +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len) +{ + /* make sure WPA is enabled */ + ieee80211_wpa_enable(ieee, 1); + + ieee80211_disassociate(ieee); +} + + +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) +{ + + int ret = 0; + + switch (command) { + case IEEE_MLME_STA_DEAUTH: + // silently ignore + break; + + case IEEE_MLME_STA_DISASSOC: + ieee80211_disassociate(ieee); + break; + + default: + printk("Unknown MLME request: %d\n", command); + ret = -EOPNOTSUPP; + } + + return ret; +} + + +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, + struct ieee_param *param, int plen) +{ + u8 *buf; + + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) + return -EINVAL; + + if (param->u.wpa_ie.len) { + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = param->u.wpa_ie.len; + } else { + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } + + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); + return 0; +} + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 + +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) +{ + + struct ieee80211_security sec = { + .flags = SEC_AUTH_MODE, + }; + int ret = 0; + + if (value & AUTH_ALG_SHARED_KEY) { + sec.auth_mode = WLAN_AUTH_SHARED_KEY; + ieee->open_wep = 0; + ieee->auth_mode = 1; + } else if (value & AUTH_ALG_OPEN_SYSTEM){ + sec.auth_mode = WLAN_AUTH_OPEN; + ieee->open_wep = 1; + ieee->auth_mode = 0; + } + else if (value & IW_AUTH_ALG_LEAP){ + sec.auth_mode = WLAN_AUTH_LEAP; + ieee->open_wep = 1; + ieee->auth_mode = 2; + } + + + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + //else + // ret = -EOPNOTSUPP; + + return ret; +} + +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) +{ + int ret=0; + unsigned long flags; + + switch (name) { + case IEEE_PARAM_WPA_ENABLED: + ret = ieee80211_wpa_enable(ieee, value); + break; + + case IEEE_PARAM_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures=value; + break; + + case IEEE_PARAM_DROP_UNENCRYPTED: { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + struct ieee80211_security sec = { + .flags = SEC_ENABLED, + .enabled = value, + }; + ieee->drop_unencrypted = value; + /* We only change SEC_LEVEL for open mode. Others + * are set by ipw_wpa_set_encryption. + */ + if (!value) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_0; + } + else { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + break; + } + + case IEEE_PARAM_PRIVACY_INVOKED: + ieee->privacy_invoked=value; + break; + + case IEEE_PARAM_AUTH_ALGS: + ret = ieee80211_wpa_set_auth_algs(ieee, value); + break; + + case IEEE_PARAM_IEEE_802_1X: + ieee->ieee802_1x=value; + break; + case IEEE_PARAM_WPAX_SELECT: + // added for WPA2 mixed mode + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); + ieee->wpax_type_set = 1; + ieee->wpax_type_notify = value; + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); + break; + + default: + printk("Unknown WPA param: %d\n",name); + ret = -EOPNOTSUPP; + } + + return ret; +} + +/* implementation borrowed from hostap driver */ + +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, + struct ieee_param *param, int param_len) +{ + int ret = 0; + + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; + + struct ieee80211_security sec = { + .flags = 0, + }; + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len != + (int) ((char *) param->u.crypt.key - (char *) param) + + param->u.crypt.key_len) { + printk("Len mismatch %d, %d\n", param_len, + param->u.crypt.key_len); + return -EINVAL; + } + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (param->u.crypt.idx >= WEP_KEYS) + return -EINVAL; + crypt = &ieee->crypt[param->u.crypt.idx]; + } else { + return -EINVAL; + } + + if (strcmp(param->u.crypt.alg, "none") == 0) { + if (crypt) { + sec.enabled = 0; + // FIXME FIXME + //sec.encrypt = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + ieee80211_crypt_delayed_deinit(ieee, crypt); + } + goto done; + } + sec.enabled = 1; +// FIXME FIXME +// sec.encrypt = 1; + sec.flags |= SEC_ENABLED; + + /* IPW HW cannot build TKIP MIC, host decryption still needed. */ + if (!(ieee->host_encrypt || ieee->host_decrypt) && + strcmp(param->u.crypt.alg, "TKIP")) + goto skip_host_crypt; + + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("ieee80211_crypt_wep"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("ieee80211_crypt_tkip"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("ieee80211_crypt_ccmp"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); + } + if (ops == NULL) { + printk("unknown crypto alg '%s'\n", param->u.crypt.alg); + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; + ret = -EINVAL; + goto done; + } + + if (*crypt == NULL || (*crypt)->ops != ops) { + struct ieee80211_crypt_data *new_crypt; + + ieee80211_crypt_delayed_deinit(ieee, crypt); + + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(*new_crypt), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ops; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif + new_crypt->priv = + new_crypt->ops->init(param->u.crypt.idx); + + if (new_crypt->priv == NULL) { + kfree(new_crypt); + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; + ret = -EINVAL; + goto done; + } + + *crypt = new_crypt; + } + + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(param->u.crypt.key, + param->u.crypt.key_len, param->u.crypt.seq, + (*crypt)->priv) < 0) { + printk("key setting failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; + ret = -EINVAL; + goto done; + } + + skip_host_crypt: + if (param->u.crypt.set_tx) { + ieee->tx_keyidx = param->u.crypt.idx; + sec.active_key = param->u.crypt.idx; + sec.flags |= SEC_ACTIVE_KEY; + } else + sec.flags &= ~SEC_ACTIVE_KEY; + + if (param->u.crypt.alg != NULL) { + memcpy(sec.keys[param->u.crypt.idx], + param->u.crypt.key, + param->u.crypt.key_len); + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + + if (strcmp(param->u.crypt.alg, "WEP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + } + done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && + ieee->reset_port(ieee->dev)) { + printk("reset_port failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; + return -EINVAL; + } + + return ret; +} + +inline struct sk_buff *ieee80211_disassociate_skb( + struct ieee80211_network *beacon, + struct ieee80211_device *ieee, + u8 asRsn) +{ + struct sk_buff *skb; + struct ieee80211_disassoc *disass; + + skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc)); + if (!skb) + return NULL; + + disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc)); + disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); + disass->header.duration_id = 0; + + memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); + + disass->reason = asRsn; + return skb; +} + + +void +SendDisassociation( + struct ieee80211_device *ieee, + u8* asSta, + u8 asRsn +) +{ + struct ieee80211_network *beacon = &ieee->current_network; + struct sk_buff *skb; + skb = ieee80211_disassociate_skb(beacon,ieee,asRsn); + if (skb){ + softmac_mgmt_xmit(skb, ieee); + //dev_kfree_skb_any(skb);//edit by thomas + } +} + +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) +{ + struct ieee_param *param; + int ret=0; + + down(&ieee->wx_sem); + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); + + if (p->length < sizeof(struct ieee_param) || !p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + if (param == NULL){ + ret = -ENOMEM; + goto out; + } + if (copy_from_user(param, p->pointer, p->length)) { + kfree(param); + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + + case IEEE_CMD_SET_WPA_PARAM: + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, + param->u.wpa_param.value); + break; + + case IEEE_CMD_SET_WPA_IE: + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); + break; + + case IEEE_CMD_SET_ENCRYPTION: + ret = ieee80211_wpa_set_encryption(ieee, param, p->length); + break; + + case IEEE_CMD_MLME: + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, + param->u.mlme.reason_code); + break; + + default: + printk("Unknown WPA supplicant request: %d\n",param->cmd); + ret = -EOPNOTSUPP; + break; + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + kfree(param); +out: + up(&ieee->wx_sem); + + return ret; +} + +void notify_wx_assoc_event(struct ieee80211_device *ieee) +{ + union iwreq_data wrqu; + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + if (ieee->state == IEEE80211_LINKED) + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); + else + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_get_beacon); +//EXPORT_SYMBOL(ieee80211_wake_queue); +//EXPORT_SYMBOL(ieee80211_stop_queue); +//EXPORT_SYMBOL(ieee80211_reset_queue); +//EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); +//EXPORT_SYMBOL(ieee80211_softmac_start_protocol); +//EXPORT_SYMBOL(ieee80211_is_shortslot); +//EXPORT_SYMBOL(ieee80211_is_54g); +//EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl); +//EXPORT_SYMBOL(ieee80211_ps_tx_ack); +//EXPORT_SYMBOL(ieee80211_softmac_xmit); +//EXPORT_SYMBOL(ieee80211_stop_send_beacons); +//EXPORT_SYMBOL(notify_wx_assoc_event); +//EXPORT_SYMBOL(SendDisassociation); +//EXPORT_SYMBOL(ieee80211_disassociate); +//EXPORT_SYMBOL(ieee80211_start_send_beacons); +//EXPORT_SYMBOL(ieee80211_stop_scan); +//EXPORT_SYMBOL(ieee80211_send_probe_requests); +//EXPORT_SYMBOL(ieee80211_softmac_scan_syncro); +//EXPORT_SYMBOL(ieee80211_start_scan_syncro); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); +EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); +EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot); +EXPORT_SYMBOL_NOVERS(ieee80211_is_54g); +EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl); +EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_xmit); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_send_beacons); +EXPORT_SYMBOL_NOVERS(notify_wx_assoc_event); +EXPORT_SYMBOL_NOVERS(SendDisassociation); +EXPORT_SYMBOL_NOVERS(ieee80211_disassociate); +EXPORT_SYMBOL_NOVERS(ieee80211_start_send_beacons); +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests); +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro); +EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro); +#endif +//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c new file mode 100644 index 00000000000..7fcda9ba796 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -0,0 +1,692 @@ +/* IEEE 802.11 SoftMAC layer + * Copyright (c) 2005 Andrea Merello + * + * Mostly extracted from the rtl8180-sa2400 driver for the + * in-kernel generic ieee802.11 stack. + * + * Some pieces of code might be stolen from ipw2100 driver + * copyright of who own it's copyright ;-) + * + * PS wx handler mostly stolen from hostap, copyright who + * own it's copyright ;-) + * + * released under the GPL + */ + + +#include "ieee80211.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif +/* FIXME: add A freqs */ + +const long ieee80211_wlan_frequencies[] = { + 2412, 2417, 2422, 2427, + 2432, 2437, 2442, 2447, + 2452, 2457, 2462, 2467, + 2472, 2484 +}; + + +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct iw_freq *fwrq = & wrqu->freq; + + down(&ieee->wx_sem); + + if(ieee->iw_mode == IW_MODE_INFRA){ + ret = -EOPNOTSUPP; + goto out; + } + + /* if setting by freq convert to channel */ + if (fwrq->e == 1) { + if ((fwrq->m >= (int) 2.412e8 && + fwrq->m <= (int) 2.487e8)) { + int f = fwrq->m / 100000; + int c = 0; + + while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) + c++; + + /* hack to fall through */ + fwrq->e = 0; + fwrq->m = c + 1; + } + } + + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){ + ret = -EOPNOTSUPP; + goto out; + + }else { /* Set the channel */ + +#ifdef ENABLE_DOT11D + if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) { + ret = -EINVAL; + goto out; + } +#endif + ieee->current_network.channel = fwrq->m; + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) + if(ieee->state == IEEE80211_LINKED){ + + ieee80211_stop_send_beacons(ieee); + ieee80211_start_send_beacons(ieee); + } + } + + ret = 0; +out: + up(&ieee->wx_sem); + return ret; +} + + +int ieee80211_wx_get_freq(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct iw_freq *fwrq = & wrqu->freq; + + if (ieee->current_network.channel == 0) + return -1; + //NM 0.7.0 will not accept channel any more. + fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000; + fwrq->e = 1; +// fwrq->m = ieee->current_network.channel; +// fwrq->e = 0; + + return 0; +} + +int ieee80211_wx_get_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + unsigned long flags; + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + + if (ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + /* We want avoid to give to the user inconsistent infos*/ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->state != IEEE80211_LINKED && + ieee->state != IEEE80211_LINKED_SCANNING && + ieee->wap_set == 0) + + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + else + memcpy(wrqu->ap_addr.sa_data, + ieee->current_network.bssid, ETH_ALEN); + + spin_unlock_irqrestore(&ieee->lock, flags); + + return 0; +} + + +int ieee80211_wx_set_wap(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + + int ret = 0; + u8 zero[] = {0,0,0,0,0,0}; + unsigned long flags; + + short ifup = ieee->proto_started;//dev->flags & IFF_UP; + struct sockaddr *temp = (struct sockaddr *)awrq; + + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + /* use ifconfig hw ether */ + if (ieee->iw_mode == IW_MODE_MASTER){ + ret = -1; + goto out; + } + + if (temp->sa_family != ARPHRD_ETHER){ + ret = -EINVAL; + goto out; + } + + if (ifup) + ieee80211_stop_protocol(ieee); + + /* just to avoid to give inconsistent infos in the + * get wx method. not really needed otherwise + */ + spin_lock_irqsave(&ieee->lock, flags); + + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0; + + spin_unlock_irqrestore(&ieee->lock, flags); + + if (ifup) + ieee80211_start_protocol(ieee); +out: + up(&ieee->wx_sem); + return ret; +} + + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b) +{ + int len,ret = 0; + unsigned long flags; + + if (ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + /* We want avoid to give to the user inconsistent infos*/ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->current_network.ssid[0] == '\0' || + ieee->current_network.ssid_len == 0){ + ret = -1; + goto out; + } + + if (ieee->state != IEEE80211_LINKED && + ieee->state != IEEE80211_LINKED_SCANNING && + ieee->ssid_set == 0){ + ret = -1; + goto out; + } + len = ieee->current_network.ssid_len; + wrqu->essid.length = len; + strncpy(b,ieee->current_network.ssid,len); + wrqu->essid.flags = 1; + +out: + spin_unlock_irqrestore(&ieee->lock, flags); + + return ret; + +} + +int ieee80211_wx_set_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + u32 target_rate = wrqu->bitrate.value; + + ieee->rate = target_rate/100000; + //FIXME: we might want to limit rate also in management protocols. + return 0; +} + + + +int ieee80211_wx_get_rate(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + u32 tmp_rate; +#if 0 + printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode); + if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G)) + tmp_rate = ieee->rate; + else if (ieee->mode & IEEE_N_5G) + tmp_rate = 580; + else if (ieee->mode & IEEE_N_24G) + { + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + tmp_rate = HTHalfMcsToDataRate(ieee, 15); + else + tmp_rate = HTMcsToDataRate(ieee, 15); + } +#else + tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); + +#endif + wrqu->bitrate.value = tmp_rate * 500000; + + return 0; +} + + +int ieee80211_wx_set_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + if (wrqu->rts.disabled || !wrqu->rts.fixed) + ieee->rts = DEFAULT_RTS_THRESHOLD; + else + { + if (wrqu->rts.value < MIN_RTS_THRESHOLD || + wrqu->rts.value > MAX_RTS_THRESHOLD) + return -EINVAL; + ieee->rts = wrqu->rts.value; + } + return 0; +} + +int ieee80211_wx_get_rts(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wrqu->rts.value = ieee->rts; + wrqu->rts.fixed = 0; /* no auto select */ + wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); + return 0; +} +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + ieee->sync_scan_hurryup = 1; + + down(&ieee->wx_sem); + + if (wrqu->mode == ieee->iw_mode) + goto out; + + if (wrqu->mode == IW_MODE_MONITOR){ + + ieee->dev->type = ARPHRD_IEEE80211; + }else{ + ieee->dev->type = ARPHRD_ETHER; + } + + if (!ieee->proto_started){ + ieee->iw_mode = wrqu->mode; + }else{ + ieee80211_stop_protocol(ieee); + ieee->iw_mode = wrqu->mode; + ieee80211_start_protocol(ieee); + } + +out: + up(&ieee->wx_sem); + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void ieee80211_wx_sync_scan_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); +#else +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee) +{ +#endif + short chan; + HT_EXTCHNL_OFFSET chan_offset=0; + HT_CHANNEL_WIDTH bandwidth=0; + int b40M = 0; + static int count = 0; + chan = ieee->current_network.channel; + netif_carrier_off(ieee->dev); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + ieee80211_stop_send_beacons(ieee); + + ieee->state = IEEE80211_LINKED_SCANNING; + ieee->link_change(ieee->dev); + ieee->InitialGainHandler(ieee->dev,IG_Backup); + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { + b40M = 1; + chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; + bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz; + printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + } + ieee80211_start_scan_syncro(ieee); + if (b40M) { + printk("Scan in 20M, back to 40M\n"); + if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) + ieee->set_chan(ieee->dev, chan + 2); + else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) + ieee->set_chan(ieee->dev, chan - 2); + else + ieee->set_chan(ieee->dev, chan); + ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); + } else { + ieee->set_chan(ieee->dev, chan); + } + + ieee->InitialGainHandler(ieee->dev,IG_Restore); + ieee->state = IEEE80211_LINKED; + ieee->link_change(ieee->dev); + // To prevent the immediately calling watch_dog after scan. + if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) + { + ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; + ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; + } + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) + ieee80211_start_send_beacons(ieee); + + netif_carrier_on(ieee->dev); + count = 0; + up(&ieee->wx_sem); + +} + +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret = 0; + + down(&ieee->wx_sem); + + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ + ret = -1; + goto out; + } + + if ( ieee->state == IEEE80211_LINKED){ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->wx_sync_scan_wq); +#else + schedule_task(&ieee->wx_sync_scan_wq); +#endif + /* intentionally forget to up sem */ + return 0; + } + +out: + up(&ieee->wx_sem); + return ret; +} + +int ieee80211_wx_set_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + + int ret=0,len; + short proto_started; + unsigned long flags; + + ieee->sync_scan_hurryup = 1; + down(&ieee->wx_sem); + + proto_started = ieee->proto_started; + + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ + ret= -E2BIG; + goto out; + } + + if (ieee->iw_mode == IW_MODE_MONITOR){ + ret= -1; + goto out; + } + + if(proto_started) + ieee80211_stop_protocol(ieee); + + + /* this is just to be sure that the GET wx callback + * has consisten infos. not needed otherwise + */ + spin_lock_irqsave(&ieee->lock, flags); + + if (wrqu->essid.flags && wrqu->essid.length) { + //first flush current network.ssid + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + strncpy(ieee->current_network.ssid, extra, len); + ieee->current_network.ssid_len = len; +#if 0 + { + int i; + for (i=0; icurrent_network.ssid, extra, len+1); + ieee->current_network.ssid_len = len+1; +#if 0 + { + int i; + for (i=0; issid_set = 1; + } + else{ + ieee->ssid_set = 0; + ieee->current_network.ssid[0] = '\0'; + ieee->current_network.ssid_len = 0; + } + spin_unlock_irqrestore(&ieee->lock, flags); + + if (proto_started) + ieee80211_start_protocol(ieee); +out: + up(&ieee->wx_sem); + return ret; +} + + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + wrqu->mode = ieee->iw_mode; + return 0; +} + + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int *parms = (int *)extra; + int enable = (parms[0] > 0); + short prev = ieee->raw_tx; + + down(&ieee->wx_sem); + + if(enable) + ieee->raw_tx = 1; + else + ieee->raw_tx = 0; + + printk(KERN_INFO"raw TX is %s\n", + ieee->raw_tx ? "enabled" : "disabled"); + + if(ieee->iw_mode == IW_MODE_MONITOR) + { + if(prev == 0 && ieee->raw_tx){ + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + } + + if(prev && ieee->raw_tx == 1) + netif_carrier_off(ieee->dev); + } + + up(&ieee->wx_sem); + + return 0; +} + +int ieee80211_wx_get_name(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + strcpy(wrqu->name, "802.11"); + if(ieee->modulation & IEEE80211_CCK_MODULATION){ + strcat(wrqu->name, "b"); + if(ieee->modulation & IEEE80211_OFDM_MODULATION) + strcat(wrqu->name, "/g"); + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) + strcat(wrqu->name, "g"); + if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) + strcat(wrqu->name, "/n"); + + if((ieee->state == IEEE80211_LINKED) || + (ieee->state == IEEE80211_LINKED_SCANNING)) + strcat(wrqu->name," linked"); + else if(ieee->state != IEEE80211_NOLINK) + strcat(wrqu->name," link.."); + + + return 0; +} + + +/* this is mostly stolen from hostap */ +int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; +#if 1 + if( + (!ieee->sta_wake_up) || + // (!ieee->ps_request_tx_ack) || + (!ieee->enter_sleep_state) || + (!ieee->ps_is_queue_empty)){ + + // printk("ERROR. PS mode is tryied to be use but driver missed a callback\n\n"); + + return -1; + } +#endif + down(&ieee->wx_sem); + + if (wrqu->power.disabled){ + ieee->ps = IEEE80211_PS_DISABLED; + goto exit; + } + if (wrqu->power.flags & IW_POWER_TIMEOUT) { + //ieee->ps_period = wrqu->power.value / 1000; + ieee->ps_timeout = wrqu->power.value / 1000; + } + + if (wrqu->power.flags & IW_POWER_PERIOD) { + + //ieee->ps_timeout = wrqu->power.value / 1000; + ieee->ps_period = wrqu->power.value / 1000; + //wrq->value / 1024; + + } + switch (wrqu->power.flags & IW_POWER_MODE) { + case IW_POWER_UNICAST_R: + ieee->ps = IEEE80211_PS_UNICAST; + break; + case IW_POWER_MULTICAST_R: + ieee->ps = IEEE80211_PS_MBCAST; + break; + case IW_POWER_ALL_R: + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; + break; + + case IW_POWER_ON: + // ieee->ps = IEEE80211_PS_DISABLED; + break; + + default: + ret = -EINVAL; + goto exit; + + } +exit: + up(&ieee->wx_sem); + return ret; + +} + +/* this is stolen from hostap */ +int ieee80211_wx_get_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret =0; + + down(&ieee->wx_sem); + + if(ieee->ps == IEEE80211_PS_DISABLED){ + wrqu->power.disabled = 1; + goto exit; + } + + wrqu->power.disabled = 0; + + if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + wrqu->power.flags = IW_POWER_TIMEOUT; + wrqu->power.value = ieee->ps_timeout * 1000; + } else { +// ret = -EOPNOTSUPP; +// goto exit; + wrqu->power.flags = IW_POWER_PERIOD; + wrqu->power.value = ieee->ps_period * 1000; +//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; + } + + if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) + wrqu->power.flags |= IW_POWER_ALL_R; + else if (ieee->ps & IEEE80211_PS_MBCAST) + wrqu->power.flags |= IW_POWER_MULTICAST_R; + else + wrqu->power.flags |= IW_POWER_UNICAST_R; + +exit: + up(&ieee->wx_sem); + return ret; + +} +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_wx_get_essid); +//EXPORT_SYMBOL(ieee80211_wx_set_essid); +//EXPORT_SYMBOL(ieee80211_wx_set_rate); +//EXPORT_SYMBOL(ieee80211_wx_get_rate); +//EXPORT_SYMBOL(ieee80211_wx_set_wap); +//EXPORT_SYMBOL(ieee80211_wx_get_wap); +//EXPORT_SYMBOL(ieee80211_wx_set_mode); +//EXPORT_SYMBOL(ieee80211_wx_get_mode); +//EXPORT_SYMBOL(ieee80211_wx_set_scan); +//EXPORT_SYMBOL(ieee80211_wx_get_freq); +//EXPORT_SYMBOL(ieee80211_wx_set_freq); +//EXPORT_SYMBOL(ieee80211_wx_set_rawtx); +//EXPORT_SYMBOL(ieee80211_wx_get_name); +//EXPORT_SYMBOL(ieee80211_wx_set_power); +//EXPORT_SYMBOL(ieee80211_wx_get_power); +//EXPORT_SYMBOL(ieee80211_wlan_frequencies); +//EXPORT_SYMBOL(ieee80211_wx_set_rts); +//EXPORT_SYMBOL(ieee80211_wx_get_rts); +#else +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power); +EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rts); +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rts); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c new file mode 100644 index 00000000000..103b33c093f --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -0,0 +1,933 @@ +/****************************************************************************** + + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211.h" + + +/* + + +802.11 Data Frame + + +802.11 frame_contorl for data frames - 2 bytes + ,-----------------------------------------------------------------------------------------. +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | + '-----------------------------------------------------------------------------------------' + /\ + | +802.11 Data Frame | + ,--------- 'ctrl' expands to >-----------' + | + ,--'---,-------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `--------------------------------------------------| |------' +Total: 28 non-data bytes `----.----' + | + .- 'Frame data' expands to <---------------------------' + | + V + ,---------------------------------------------------. +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | + |------|------|---------|----------|------|---------| +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | + | DSAP | SSAP | | | | Packet | + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | + `-----------------------------------------| | +Total: 8 non-data bytes `----.----' + | + .- 'IP Packet' expands, if WEP enabled, to <--' + | + V + ,-----------------------. +Bytes | 4 | 0-2296 | 4 | + |-----|-----------|-----| +Desc. | IV | Encrypted | ICV | + | | IP Packet | | + `-----------------------' +Total: 8 non-data bytes + + +802.3 Ethernet Data Frame + + ,-----------------------------------------. +Bytes | 6 | 6 | 2 | Variable | 4 | + |-------|-------|------|-----------|------| +Desc. | Dest. | Source| Type | IP Packet | fcs | + | MAC | MAC | | | | + `-----------------------------------------' +Total: 18 non-data bytes + +In the event that fragmentation is required, the incoming payload is split into +N parts of size ieee->fts. The first fragment contains the SNAP header and the +remaining packets are just data. + +If encryption is enabled, each fragment payload size is reduced by enough space +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) +So if you have 1500 bytes of payload with ieee->fts set to 500 without +encryption it will take 3 frames. With WEP it will take 4 frames as the +payload of each frame is reduced to 492 bytes. + +* SKB visualization +* +* ,- skb->data +* | +* | ETHERNET HEADER ,-<-- PAYLOAD +* | | 14 bytes from skb->data +* | 2 bytes for Type --> ,T. | (sizeof ethhdr) +* | | | | +* |,-Dest.--. ,--Src.---. | | | +* | 6 bytes| | 6 bytes | | | | +* v | | | | | | +* 0 | v 1 | v | v 2 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +* ^ | ^ | ^ | +* | | | | | | +* | | | | `T' <---- 2 bytes for Type +* | | | | +* | | '---SNAP--' <-------- 6 bytes for SNAP +* | | +* `-IV--' <-------------------- 4 bytes for IV (WEP) +* +* SNAP HEADER +* +*/ + +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; + +static inline int ieee80211_put_snap(u8 *data, u16 h_proto) +{ + struct ieee80211_snap_hdr *snap; + u8 *oui; + + snap = (struct ieee80211_snap_hdr *)data; + snap->dsap = 0xaa; + snap->ssap = 0xaa; + snap->ctrl = 0x03; + + if (h_proto == 0x8137 || h_proto == 0x80f3) + oui = P802_1H_OUI; + else + oui = RFC1042_OUI; + snap->oui[0] = oui[0]; + snap->oui[1] = oui[1]; + snap->oui[2] = oui[2]; + + *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + + return SNAP_SIZE + sizeof(u16); +} + +int ieee80211_encrypt_fragment( + struct ieee80211_device *ieee, + struct sk_buff *frag, + int hdr_len) +{ + struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx]; + int res; + + if (!(crypt && crypt->ops)) + { + printk("=========>%s(), crypt is null\n", __FUNCTION__); + return -1; + } +#ifdef CONFIG_IEEE80211_CRYPT_TKIP + struct ieee80211_hdr *header; + + if (ieee->tkip_countermeasures && + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { + header = (struct ieee80211_hdr *) frag->data; + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " + "TX packet to " MAC_FMT "\n", + ieee->dev->name, MAC_ARG(header->addr1)); + } + return -1; + } +#endif + /* To encrypt, frame format is: + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ + + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so + * call both MSDU and MPDU encryption functions from here. */ + atomic_inc(&crypt->refcnt); + res = 0; + if (crypt->ops->encrypt_msdu) + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); + if (res == 0 && crypt->ops->encrypt_mpdu) + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); + + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_INFO "%s: Encryption failed: len=%d.\n", + ieee->dev->name, frag->len); + ieee->ieee_stats.tx_discards++; + return -1; + } + + return 0; +} + + +void ieee80211_txb_free(struct ieee80211_txb *txb) { + //int i; + if (unlikely(!txb)) + return; +#if 0 + for (i = 0; i < txb->nr_frags; i++) + if (txb->fragments[i]) + dev_kfree_skb_any(txb->fragments[i]); +#endif + kfree(txb); +} + +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, + int gfp_mask) +{ + struct ieee80211_txb *txb; + int i; + txb = kmalloc( + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags), + gfp_mask); + if (!txb) + return NULL; + + memset(txb, 0, sizeof(struct ieee80211_txb)); + txb->nr_frags = nr_frags; + txb->frag_size = txb_size; + + for (i = 0; i < nr_frags; i++) { + txb->fragments[i] = dev_alloc_skb(txb_size); + if (unlikely(!txb->fragments[i])) { + i--; + break; + } + memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); + } + if (unlikely(i != nr_frags)) { + while (i >= 0) + dev_kfree_skb_any(txb->fragments[i--]); + kfree(txb); + return NULL; + } + return txb; +} + +// Classify the to-be send data packet +// Need to acquire the sent queue index. +static int +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) +{ + struct ethhdr *eth; + struct iphdr *ip; + eth = (struct ethhdr *)skb->data; + if (eth->h_proto != htons(ETH_P_IP)) + return 0; + +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) + ip = ip_hdr(skb); +#else + ip = (struct iphdr*)(skb->data + sizeof(struct ether_header)); +#endif + switch (ip->tos & 0xfc) { + case 0x20: + return 2; + case 0x40: + return 1; + case 0x60: + return 3; + case 0x80: + return 4; + case 0xa0: + return 5; + case 0xc0: + return 6; + case 0xe0: + return 7; + default: + return 0; + } +} + +#define SN_LESS(a, b) (((a-b)&0x800)!=0) +void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + PTX_TS_RECORD pTxTs = NULL; + struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data; + + if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + return; + if (!IsQoSDataFrame(skb->data)) + return; + + if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1)) + return; + //check packet and mode later +#ifdef TO_DO_LIST + if(pTcb->PacketLength >= 4096) + return; + // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation. + if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter)) + return; +#endif +#if 1 + if(!ieee->GetNmodeSupportBySecCfg(ieee->dev)) + { + return; + } +#endif + if(pHTInfo->bCurrentAMPDUEnable) + { + if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) + { + printk("===>can't get TS\n"); + return; + } + if (pTxTs->TxAdmittedBARecord.bValid == false) + { + //as some AP will refuse our action frame until key handshake has been finished. WB + if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA)) + ; + else + TsStartAddBaProcess(ieee, pTxTs); + goto FORCED_AGG_SETTING; + } + else if (pTxTs->bUsingBa == false) + { + if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096)) + pTxTs->bUsingBa = true; + else + goto FORCED_AGG_SETTING; + } + + if (ieee->iw_mode == IW_MODE_INFRA) + { + tcb_desc->bAMPDUEnable = true; + tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor; + tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity; + } + } +FORCED_AGG_SETTING: + switch(pHTInfo->ForcedAMPDUMode ) + { + case HT_AGG_AUTO: + break; + + case HT_AGG_FORCE_ENABLE: + tcb_desc->bAMPDUEnable = true; + tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity; + tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor; + break; + + case HT_AGG_FORCE_DISABLE: + tcb_desc->bAMPDUEnable = false; + tcb_desc->ampdu_density = 0; + tcb_desc->ampdu_factor = 0; + break; + + } + return; +} + +extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc) +{ + tcb_desc->bUseShortPreamble = false; + if (tcb_desc->data_rate == 2) + {//// 1M can only use Long Preamble. 11B spec + return; + } + else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + { + tcb_desc->bUseShortPreamble = true; + } + return; +} +extern void +ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + tcb_desc->bUseShortGI = false; + + if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + return; + + if(pHTInfo->bForcedShortGI) + { + tcb_desc->bUseShortGI = true; + return; + } + + if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz) + tcb_desc->bUseShortGI = true; + else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz) + tcb_desc->bUseShortGI = true; +} + +void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + tcb_desc->bPacketBW = false; + + if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) + return; + + if(tcb_desc->bMulticast || tcb_desc->bBroadcast) + return; + + if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel. + return; + //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance + if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) + tcb_desc->bPacketBW = true; + return; +} + +void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb) +{ + // Common Settings + tcb_desc->bRTSSTBC = false; + tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used. + tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS + tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate. + tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz + + if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts + return; + + if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA. + return; + + if (ieee->mode < IEEE_N_24G) //b, g mode + { + // (1) RTS_Threshold is compared to the MPDU, not MSDU. + // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. + // Other fragments are protected by previous fragment. + // So we only need to check the length of first fragment. + if (skb->len > ieee->rts) + { + tcb_desc->bRTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + } + else if (ieee->current_network.buseprotection) + { + // Use CTS-to-SELF in protection mode. + tcb_desc->bRTSEnable = true; + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + } + //otherwise return; + return; + } + else + {// 11n High throughput case. + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + while (true) + { + //check ERP protection + if (ieee->current_network.buseprotection) + {// CTS-to-SELF + tcb_desc->bRTSEnable = true; + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + break; + } + //check HT op mode + if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) + { + u8 HTOpMode = pHTInfo->CurrentOpMode; + if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || + (!pHTInfo->bCurBW40MHz && HTOpMode == 3) ) + { + tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. + tcb_desc->bRTSEnable = true; + break; + } + } + //check rts + if (skb->len > ieee->rts) + { + tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. + tcb_desc->bRTSEnable = true; + break; + } + //to do list: check MIMO power save condition. + //check AMPDU aggregation for TXOP + if(tcb_desc->bAMPDUEnable) + { + tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. + // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads + // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily + tcb_desc->bRTSEnable = false; + break; + } + //check IOT action + if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) + { + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } + // Totally no protection case!! + goto NO_PROTECTION; + } + } + // For test , CTS replace with RTS + if( 0 ) + { + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + } + if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + tcb_desc->bUseShortPreamble = true; + if (ieee->mode == IW_MODE_MASTER) + goto NO_PROTECTION; + return; +NO_PROTECTION: + tcb_desc->bRTSEnable = false; + tcb_desc->bCTSEnable = false; + tcb_desc->rts_rate = 0; + tcb_desc->RTSSC = 0; + tcb_desc->bRTSBW = false; +} + + +void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc) +{ +#ifdef TO_DO_LIST + if(!IsDataFrame(pFrame)) + { + pTcb->bTxDisableRateFallBack = TRUE; + pTcb->bTxUseDriverAssingedRate = TRUE; + pTcb->RATRIndex = 7; + return; + } + + if(pMgntInfo->ForcedDataRate!= 0) + { + pTcb->bTxDisableRateFallBack = TRUE; + pTcb->bTxUseDriverAssingedRate = TRUE; + return; + } +#endif + if(ieee->bTxDisableRateFallBack) + tcb_desc->bTxDisableRateFallBack = true; + + if(ieee->bTxUseDriverAssingedRate) + tcb_desc->bTxUseDriverAssingedRate = true; + if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) + { + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) + tcb_desc->RATRIndex = 0; + } +} + +void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst) +{ + if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + return; + if (IsQoSDataFrame(skb->data)) //we deal qos data only + { + PTX_TS_RECORD pTS = NULL; + if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true)) + { + return; + } + pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096; + } +} + +int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + struct ieee80211_device *ieee = netdev_priv(dev); +#else + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv; +#endif + struct ieee80211_txb *txb = NULL; + struct ieee80211_hdr_3addrqos *frag_hdr; + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; + unsigned long flags; + struct net_device_stats *stats = &ieee->stats; + int ether_type = 0, encrypt; + int bytes, fc, qos_ctl = 0, hdr_len; + struct sk_buff *skb_frag; + struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */ + .duration_id = 0, + .seq_ctl = 0, + .qos_ctl = 0 + }; + u8 dest[ETH_ALEN], src[ETH_ALEN]; + int qos_actived = ieee->current_network.qos_data.active; + + struct ieee80211_crypt_data* crypt; + + cb_desc *tcb_desc; + + spin_lock_irqsave(&ieee->lock, flags); + + /* If there is no driver handler to take the TXB, dont' bother + * creating it... */ + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { + printk(KERN_WARNING "%s: No xmit handler.\n", + ieee->dev->name); + goto success; + } + + + if(likely(ieee->raw_tx == 0)){ + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + + memset(skb->cb, 0, sizeof(skb->cb)); + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); + + crypt = ieee->crypt[ieee->tx_keyidx]; + + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && + ieee->host_encrypt && crypt && crypt->ops; + + if (!encrypt && ieee->ieee802_1x && + ieee->drop_unencrypted && ether_type != ETH_P_PAE) { + stats->tx_dropped++; + goto success; + } + #ifdef CONFIG_IEEE80211_DEBUG + if (crypt && !encrypt && ether_type == ETH_P_PAE) { + struct eapol *eap = (struct eapol *)(skb->data + + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", + eap_get_type(eap->type)); + } + #endif + + /* Save source and destination addresses */ + memcpy(&dest, skb->data, ETH_ALEN); + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + if (encrypt) + fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP; + else + + fc = IEEE80211_FTYPE_DATA; + + //if(ieee->current_network.QoS_Enable) + if(qos_actived) + fc |= IEEE80211_STYPE_QOS_DATA; + else + fc |= IEEE80211_STYPE_DATA; + + if (ieee->iw_mode == IW_MODE_INFRA) { + fc |= IEEE80211_FCTL_TODS; + /* To DS: Addr1 = BSSID, Addr2 = SA, + Addr3 = DA */ + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); + memcpy(&header.addr2, &src, ETH_ALEN); + memcpy(&header.addr3, &dest, ETH_ALEN); + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + /* not From/To DS: Addr1 = DA, Addr2 = SA, + Addr3 = BSSID */ + memcpy(&header.addr1, dest, ETH_ALEN); + memcpy(&header.addr2, src, ETH_ALEN); + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); + } + + header.frame_ctl = cpu_to_le16(fc); + + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) */ + if (is_multicast_ether_addr(header.addr1) || + is_broadcast_ether_addr(header.addr1)) { + frag_size = MAX_FRAG_THRESHOLD; + qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; + } + else { + frag_size = ieee->fts;//default:392 + qos_ctl = 0; + } + + //if (ieee->current_network.QoS_Enable) + if(qos_actived) + { + hdr_len = IEEE80211_3ADDR_LEN + 2; + + skb->priority = ieee80211_classify(skb, &ieee->current_network); + qos_ctl |= skb->priority; //set in the ieee80211_classify + header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID); + } else { + hdr_len = IEEE80211_3ADDR_LEN; + } + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account for + * it when determining the amount of payload space. */ + bytes_per_frag = frag_size - hdr_len; + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + bytes_per_frag -= IEEE80211_FCS_LEN; + + /* Each fragment may need to have room for encryptiong pre/postfix */ + if (encrypt) + bytes_per_frag -= crypt->ops->extra_prefix_len + + crypt->ops->extra_postfix_len; + + /* Number of fragments is the total bytes_per_frag / + * payload_per_fragment */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + + /* When we allocate the TXB we allocate enough space for the reserve + * and full fragment bytes (bytes_per_frag doesn't include prefix, + * postfix, header, FCS, etc.) */ + txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + txb->encrypted = encrypt; + txb->payload_size = bytes; + + //if (ieee->current_network.QoS_Enable) + if(qos_actived) + { + txb->queue_index = UP2AC(skb->priority); + } else { + txb->queue_index = WME_AC_BK;; + } + + + + for (i = 0; i < nr_frags; i++) { + skb_frag = txb->fragments[i]; + tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); + if(qos_actived){ + skb_frag->priority = skb->priority;//UP2AC(skb->priority); + tcb_desc->queue_index = UP2AC(skb->priority); + } else { + skb_frag->priority = WME_AC_BK; + tcb_desc->queue_index = WME_AC_BK; + } + skb_reserve(skb_frag, ieee->tx_headroom); + + if (encrypt){ + if (ieee->hwsec_active) + tcb_desc->bHwSec = 1; + else + tcb_desc->bHwSec = 0; + skb_reserve(skb_frag, crypt->ops->extra_prefix_len); + } + else + { + tcb_desc->bHwSec = 0; + } + frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len); + memcpy(frag_hdr, &header, hdr_len); + + /* If this is not the last fragment, then add the MOREFRAGS + * bit to the frame control */ + if (i != nr_frags - 1) { + frag_hdr->frame_ctl = cpu_to_le16( + fc | IEEE80211_FCTL_MOREFRAGS); + bytes = bytes_per_frag; + + } else { + /* The last fragment takes the remaining length */ + bytes = bytes_last_frag; + } + //if(ieee->current_network.QoS_Enable) + if(qos_actived) + { + // add 1 only indicate to corresponding seq number control 2006/7/12 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i); + } else { + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + } + + /* Put a SNAP header on the first fragment */ + if (i == 0) { + ieee80211_put_snap( + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), + ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } + + memcpy(skb_put(skb_frag, bytes), skb->data, bytes); + + /* Advance the SKB... */ + skb_pull(skb, bytes); + + /* Encryption routine will move the header forward in order + * to insert the IV between the header and the payload */ + if (encrypt) + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + skb_put(skb_frag, 4); + } + + if(qos_actived) + { + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; + else + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; + } else { + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + } + }else{ + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); + if(!txb){ + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + + txb->encrypted = 0; + txb->payload_size = skb->len; + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len); + } + + success: +//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. + if (txb) + { +#if 1 + cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->bTxEnableFwCalcDur = 1; + if (is_multicast_ether_addr(header.addr1)) + tcb_desc->bMulticast = 1; + if (is_broadcast_ether_addr(header.addr1)) + tcb_desc->bBroadcast = 1; + ieee80211_txrate_selectmode(ieee, tcb_desc); + if ( tcb_desc->bMulticast || tcb_desc->bBroadcast) + tcb_desc->data_rate = ieee->basic_rate; + else + //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate); + tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); + ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc); + ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); + ieee80211_query_HTCapShortGI(ieee, tcb_desc); + ieee80211_query_BandwidthMode(ieee, tcb_desc); + ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]); + ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1); +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len); + //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc)); +#endif + } + spin_unlock_irqrestore(&ieee->lock, flags); + dev_kfree_skb_any(skb); + if (txb) { + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){ + ieee80211_softmac_xmit(txb, ieee); + }else{ + if ((*ieee->hard_start_xmit)(txb, dev) == 0) { + stats->tx_packets++; + stats->tx_bytes += txb->payload_size; + return 0; + } + ieee80211_txb_free(txb); + } + } + + return 0; + + failed: + spin_unlock_irqrestore(&ieee->lock, flags); + netif_stop_queue(dev); + stats->tx_errors++; + return 1; + +} + +//EXPORT_SYMBOL(ieee80211_txb_free); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c new file mode 100644 index 00000000000..7162f61edfa --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -0,0 +1,1032 @@ +/****************************************************************************** + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + + Copyright (c) 2002-2003, Jouni Malinen + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +******************************************************************************/ +#include +#include +#include +#include + +#include "ieee80211.h" +#if 0 +static const char *ieee80211_modes[] = { + "?", "a", "b", "ab", "g", "ag", "bg", "abg" +}; +#endif +struct modes_unit { + char *mode_string; + int mode_size; +}; +struct modes_unit ieee80211_modes[] = { + {"a",1}, + {"b",1}, + {"g",1}, + {"?",1}, + {"N-24G",5}, + {"N-5G",4}, +}; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static inline char * +iwe_stream_add_event_rsl(char * stream, /* Stream of events */ + char * ends, /* End of stream */ + struct iw_event *iwe, /* Payload */ + int event_len) /* Real size of payload */ +{ + /* Check if it's possible */ + if((stream + event_len) < ends) { + iwe->len = event_len; + ndelay(1); //new + memcpy(stream, (char *) iwe, event_len); + stream += event_len; + } + return stream; +} +#else +#define iwe_stream_add_event_rsl iwe_stream_add_event +#endif + +#define MAX_CUSTOM_LEN 64 +static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, + char *start, char *stop, + struct ieee80211_network *network, + struct iw_request_info *info) +{ + char custom[MAX_CUSTOM_LEN]; + char proto_name[IFNAMSIZ]; + char *pname = proto_name; + char *p; + struct iw_event iwe; + int i, j; + u16 max_rate, rate; + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + + /* First entry *MUST* be the AP MAC address */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_ADDR_LEN); +#endif + /* Remaining entries will be displayed in the order we provide them */ + + /* Add the ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; +// if (network->flags & NETWORK_EMPTY_ESSID) { + if (network->ssid_len == 0) { + iwe.u.data.length = sizeof(""); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, ""); +#else + start = iwe_stream_add_point(start, stop, &iwe, ""); +#endif + } else { + iwe.u.data.length = min(network->ssid_len, (u8)32); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); +#else + start = iwe_stream_add_point(start, stop, &iwe, network->ssid); +#endif + } + /* Add the protocol name */ + iwe.cmd = SIOCGIWNAME; + for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) { + if(network->mode&(1<= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_CHAR_LEN); +#endif + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + if (network->capability & + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) { + if (network->capability & WLAN_CAPABILITY_BSS) + iwe.u.mode = IW_MODE_MASTER; + else + iwe.u.mode = IW_MODE_ADHOC; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_UINT_LEN); +#endif + } + + /* Add frequency/channel */ + iwe.cmd = SIOCGIWFREQ; +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode); + iwe.u.freq.e = 3; */ + iwe.u.freq.m = network->channel; + iwe.u.freq.e = 0; + iwe.u.freq.i = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_FREQ_LEN); +#endif + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (network->capability & WLAN_CAPABILITY_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); +#else + start = iwe_stream_add_point(start, stop, &iwe, network->ssid); +#endif + /* Add basic and extended rates */ + max_rate = 0; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); + for (i = 0, j = 0; i < network->rates_len; ) { + if (j < network->rates_ex_len && + ((network->rates_ex[j] & 0x7F) < + (network->rates[i] & 0x7F))) + rate = network->rates_ex[j++] & 0x7F; + else + rate = network->rates[i++] & 0x7F; + if (rate > max_rate) + max_rate = rate; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + } + for (; j < network->rates_ex_len; j++) { + rate = network->rates_ex[j] & 0x7F; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + if (rate > max_rate) + max_rate = rate; + } + + if (network->mode >= IEEE_N_24G)//add N rate here; + { + PHT_CAPABILITY_ELE ht_cap = NULL; + bool is40M = false, isShortGI = false; + u8 max_mcs = 0; + if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4)) + ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4]; + else + ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0]; + is40M = (ht_cap->ChlWidth)?1:0; + isShortGI = (ht_cap->ChlWidth)? + ((ht_cap->ShortGI40Mhz)?1:0): + ((ht_cap->ShortGI20Mhz)?1:0); + + max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL); + rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f]; + if (rate > max_rate) + max_rate = rate; + } +#if 0 + printk("max rate:%d ===basic rate:\n", max_rate); + for (i=0;irates_len;i++) + printk(" %x", network->rates[i]); + printk("\n=======extend rate\n"); + for (i=0; irates_ex_len; i++) + printk(" %x", network->rates_ex[i]); + printk("\n"); +#endif + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + iwe.u.bitrate.value = max_rate * 500000; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, + IW_EV_PARAM_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, + IW_EV_PARAM_LEN); +#endif + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif + /* Add quality statistics */ + /* TODO: Fix these values... */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.qual = network->stats.signal; + iwe.u.qual.level = network->stats.rssi; + iwe.u.qual.noise = network->stats.noise; + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; + iwe.u.qual.updated = 7; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN); +#else + start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_QUAL_LEN); +#endif + iwe.cmd = IWEVCUSTOM; + p = custom; + + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif +#if (WIRELESS_EXT < 18) + if (ieee->wpa_enabled && network->wpa_ie_len){ + char buf[MAX_WPA_IE_LEN * 2 + 30]; + // printk("WPA IE\n"); + u8 *p = buf; + p += sprintf(p, "wpa_ie="); + for (i = 0; i < network->wpa_ie_len; i++) { + p += sprintf(p, "%02x", network->wpa_ie[i]); + } + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = strlen(buf); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } + + if (ieee->wpa_enabled && network->rsn_ie_len){ + char buf[MAX_WPA_IE_LEN * 2 + 30]; + + u8 *p = buf; + p += sprintf(p, "rsn_ie="); + for (i = 0; i < network->rsn_ie_len; i++) { + p += sprintf(p, "%02x", network->rsn_ie[i]); + } + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = strlen(buf); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } +#else + memset(&iwe, 0, sizeof(iwe)); + if (network->wpa_ie_len) + { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->wpa_ie, network->wpa_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->wpa_ie_len; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } + memset(&iwe, 0, sizeof(iwe)); + if (network->rsn_ie_len) + { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->rsn_ie, network->rsn_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->rsn_ie_len; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, buf); +#else + start = iwe_stream_add_point(start, stop, &iwe, buf); +#endif + } +#endif + + + /* Add EXTRA: Age to display seconds since last beacon/probe response + * for given network. */ + iwe.cmd = IWEVCUSTOM; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); + iwe.u.data.length = p - custom; + if (iwe.u.data.length) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + start = iwe_stream_add_point(info, start, stop, &iwe, custom); +#else + start = iwe_stream_add_point(start, stop, &iwe, custom); +#endif + + return start; +} + +int ieee80211_wx_get_scan(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ieee80211_network *network; + unsigned long flags; + + char *ev = extra; +// char *stop = ev + IW_SCAN_MAX_DATA; + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA; + //char *stop = ev + IW_SCAN_MAX_DATA; + int i = 0; + int err = 0; + IEEE80211_DEBUG_WX("Getting scan\n"); + down(&ieee->wx_sem); + spin_lock_irqsave(&ieee->lock, flags); + + list_for_each_entry(network, &ieee->network_list, list) { + i++; + if((stop-ev)<200) + { + err = -E2BIG; + break; + } + if (ieee->scan_age == 0 || + time_after(network->last_scanned + ieee->scan_age, jiffies)) + ev = rtl819x_translate_scan(ieee, ev, stop, network, info); + else + IEEE80211_DEBUG_SCAN( + "Not showing network '%s (" + MAC_FMT ")' due to age (%lums).\n", + escape_essid(network->ssid, + network->ssid_len), + MAC_ARG(network->bssid), + (jiffies - network->last_scanned) / (HZ / 100)); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + up(&ieee->wx_sem); + wrqu->data.length = ev - extra; + wrqu->data.flags = 0; + + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i); + + return err; +} + +int ieee80211_wx_set_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + struct net_device *dev = ieee->dev; + struct ieee80211_security sec = { + .flags = 0 + }; + int i, key, key_provided, len; + struct ieee80211_crypt_data **crypt; + + IEEE80211_DEBUG_WX("SET_ENCODE\n"); + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + key_provided = 1; + } else { + key_provided = 0; + key = ieee->tx_keyidx; + } + + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? + "provided" : "default"); + crypt = &ieee->crypt[key]; + + if (erq->flags & IW_ENCODE_DISABLED) { + if (key_provided && *crypt) { + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", + key); + ieee80211_crypt_delayed_deinit(ieee, crypt); + } else + IEEE80211_DEBUG_WX("Disabling encryption.\n"); + + /* Check all the keys to see if any are still configured, + * and if no key index was provided, de-init them all */ + for (i = 0; i < WEP_KEYS; i++) { + if (ieee->crypt[i] != NULL) { + if (key_provided) + break; + ieee80211_crypt_delayed_deinit( + ieee, &ieee->crypt[i]); + } + } + + if (i == WEP_KEYS) { + sec.enabled = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + } + + goto done; + } + + + + sec.enabled = 1; + sec.flags |= SEC_ENABLED; + + if (*crypt != NULL && (*crypt)->ops != NULL && + strcmp((*crypt)->ops->name, "WEP") != 0) { + /* changing to use WEP; deinit previously used algorithm + * on this key */ + ieee80211_crypt_delayed_deinit(ieee, crypt); + } + + if (*crypt == NULL) { + struct ieee80211_crypt_data *new_crypt; + + /* take WEP into use */ + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); + if (new_crypt == NULL) + return -ENOMEM; + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); + if (!new_crypt->ops) { + request_module("ieee80211_crypt_wep"); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) +#else + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner)) +#endif + new_crypt->priv = new_crypt->ops->init(key); + + if (!new_crypt->ops || !new_crypt->priv) { + kfree(new_crypt); + new_crypt = NULL; + + printk(KERN_WARNING "%s: could not initialize WEP: " + "load module ieee80211_crypt_wep\n", + dev->name); + return -EOPNOTSUPP; + } + *crypt = new_crypt; + } + + /* If a new key was provided, set it up */ + if (erq->length > 0) { + len = erq->length <= 5 ? 5 : 13; + memcpy(sec.keys[key], keybuf, erq->length); + if (len > erq->length) + memset(sec.keys[key] + erq->length, 0, + len - erq->length); + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", + key, escape_essid(sec.keys[key], len), + erq->length, len); + sec.key_sizes[key] = len; + (*crypt)->ops->set_key(sec.keys[key], len, NULL, + (*crypt)->priv); + sec.flags |= (1 << key); + /* This ensures a key will be activated if no key is + * explicitely set */ + if (key == sec.active_key) + sec.flags |= SEC_ACTIVE_KEY; + ieee->tx_keyidx = key; + + } else { + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, + NULL, (*crypt)->priv); + if (len == 0) { + /* Set a default key of all 0 */ + printk("Setting key %d to all zero.\n", + key); + + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", + key); + memset(sec.keys[key], 0, 13); + (*crypt)->ops->set_key(sec.keys[key], 13, NULL, + (*crypt)->priv); + sec.key_sizes[key] = 13; + sec.flags |= (1 << key); + } + + /* No key data - just set the default TX key index */ + if (key_provided) { + IEEE80211_DEBUG_WX( + "Setting key %d to default Tx key.\n", key); + ieee->tx_keyidx = key; + sec.active_key = key; + sec.flags |= SEC_ACTIVE_KEY; + } + } + + done: + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); + ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + sec.flags |= SEC_AUTH_MODE; + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? + "OPEN" : "SHARED KEY"); + + /* For now we just support WEP, so only set that security level... + * TODO: When WPA is added this is one place that needs to change */ + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ + + if (ieee->set_security) + ieee->set_security(dev, &sec); + + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); + return -EINVAL; + } + return 0; +} + +int ieee80211_wx_get_encode(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + int len, key; + struct ieee80211_crypt_data *crypt; + + IEEE80211_DEBUG_WX("GET_ENCODE\n"); + + if(ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + } else + key = ieee->tx_keyidx; + + crypt = ieee->crypt[key]; + erq->flags = key + 1; + + if (crypt == NULL || crypt->ops == NULL) { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + return 0; + } +#if 0 + if (strcmp(crypt->ops->name, "WEP") != 0) { + /* only WEP is supported with wireless extensions, so just + * report that encryption is used */ + erq->length = 0; + erq->flags |= IW_ENCODE_ENABLED; + return 0; + } +#endif + len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); + erq->length = (len >= 0 ? len : 0); + + erq->flags |= IW_ENCODE_ENABLED; + + if (ieee->open_wep) + erq->flags |= IW_ENCODE_OPEN; + else + erq->flags |= IW_ENCODE_RESTRICTED; + + return 0; +} +#if (WIRELESS_EXT >= 18) +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct net_device *dev = ieee->dev; + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int i, idx; + int group_key = 0; + const char *alg, *module; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; + + struct ieee80211_security sec = { + .flags = 0, + }; + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg); + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) { + if (idx < 1 || idx > WEP_KEYS) + return -EINVAL; + idx--; + } else + idx = ieee->tx_keyidx; + + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + + crypt = &ieee->crypt[idx]; + + group_key = 1; + } else { + /* some Cisco APs use idx>0 for unicast in dynamic WEP */ + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg); + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) + return -EINVAL; + if (ieee->iw_mode == IW_MODE_INFRA) + + crypt = &ieee->crypt[idx]; + + else + return -EINVAL; + } + + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT; + if ((encoding->flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE) { + if (*crypt) + ieee80211_crypt_delayed_deinit(ieee, crypt); + + for (i = 0; i < WEP_KEYS; i++) + + if (ieee->crypt[i] != NULL) + + break; + + if (i == WEP_KEYS) { + sec.enabled = 0; + // sec.encrypt = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_LEVEL; + } + //printk("disabled: flag:%x\n", encoding->flags); + goto done; + } + + sec.enabled = 1; + // sec.encrypt = 1; +#if 0 + if (group_key ? !ieee->host_mc_decrypt : + !(ieee->host_encrypt || ieee->host_decrypt || + ieee->host_encrypt_msdu)) + goto skip_host_crypt; +#endif + switch (ext->alg) { + case IW_ENCODE_ALG_WEP: + alg = "WEP"; + module = "ieee80211_crypt_wep"; + break; + case IW_ENCODE_ALG_TKIP: + alg = "TKIP"; + module = "ieee80211_crypt_tkip"; + break; + case IW_ENCODE_ALG_CCMP: + alg = "CCMP"; + module = "ieee80211_crypt_ccmp"; + break; + default: + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + ret = -EINVAL; + goto done; + } + printk("alg name:%s\n",alg); + + ops = ieee80211_get_crypto_ops(alg); + if (ops == NULL) { + request_module(module); + ops = ieee80211_get_crypto_ops(alg); + } + if (ops == NULL) { + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + printk("========>unknown crypto alg %d\n", ext->alg); + ret = -EINVAL; + goto done; + } + + if (*crypt == NULL || (*crypt)->ops != ops) { + struct ieee80211_crypt_data *new_crypt; + + ieee80211_crypt_delayed_deinit(ieee, crypt); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); +#else + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); + memset(new_crypt,0,sizeof(*new_crypt)); +#endif + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + new_crypt->ops = ops; + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) + new_crypt->priv = new_crypt->ops->init(idx); + if (new_crypt->priv == NULL) { + kfree(new_crypt); + ret = -EINVAL; + goto done; + } + *crypt = new_crypt; + + } + + if (ext->key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, + (*crypt)->priv) < 0) { + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name); + printk("key setting failed\n"); + ret = -EINVAL; + goto done; + } +#if 1 + //skip_host_crypt: + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + ieee->tx_keyidx = idx; + sec.active_key = idx; + sec.flags |= SEC_ACTIVE_KEY; + } + + if (ext->alg != IW_ENCODE_ALG_NONE) { + //memcpy(sec.keys[idx], ext->key, ext->key_len); + sec.key_sizes[idx] = ext->key_len; + sec.flags |= (1 << idx); + if (ext->alg == IW_ENCODE_ALG_WEP) { + // sec.encode_alg[idx] = SEC_ALG_WEP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (ext->alg == IW_ENCODE_ALG_TKIP) { + // sec.encode_alg[idx] = SEC_ALG_TKIP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (ext->alg == IW_ENCODE_ALG_CCMP) { + // sec.encode_alg[idx] = SEC_ALG_CCMP; + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + /* Don't set sec level for group keys. */ + if (group_key) + sec.flags &= ~SEC_LEVEL; + } +#endif +done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); + return -EINVAL; + } +#endif + return ret; +} + +int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct ieee80211_crypt_data *crypt; + int idx, max_key_len; + + max_key_len = encoding->length - sizeof(*ext); + if (max_key_len < 0) + return -EINVAL; + + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) { + if (idx < 1 || idx > WEP_KEYS) + return -EINVAL; + idx--; + } else + idx = ieee->tx_keyidx; + + if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && + ext->alg != IW_ENCODE_ALG_WEP) + if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) + return -EINVAL; + + crypt = ieee->crypt[idx]; + encoding->flags = idx + 1; + memset(ext, 0, sizeof(*ext)); + + if (crypt == NULL || crypt->ops == NULL ) { + ext->alg = IW_ENCODE_ALG_NONE; + ext->key_len = 0; + encoding->flags |= IW_ENCODE_DISABLED; + } else { + if (strcmp(crypt->ops->name, "WEP") == 0 ) + ext->alg = IW_ENCODE_ALG_WEP; + else if (strcmp(crypt->ops->name, "TKIP")) + ext->alg = IW_ENCODE_ALG_TKIP; + else if (strcmp(crypt->ops->name, "CCMP")) + ext->alg = IW_ENCODE_ALG_CCMP; + else + return -EINVAL; + ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv); + encoding->flags |= IW_ENCODE_ENABLED; + if (ext->key_len && + (ext->alg == IW_ENCODE_ALG_TKIP || + ext->alg == IW_ENCODE_ALG_CCMP)) + ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; + + } + + return 0; +} + +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct iw_mlme *mlme = (struct iw_mlme *) extra; + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + case IW_MLME_DISASSOC: + ieee80211_disassociate(ieee); + break; + default: + return -EOPNOTSUPP; + } +#endif + return 0; +} + +int ieee80211_wx_set_auth(struct ieee80211_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + switch (data->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + /*need to support wpa2 here*/ + //printk("wpa version:%x\n", data->value); + break; + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + case IW_AUTH_KEY_MGMT: + /* + * * Host AP driver does not use these parameters and allows + * * wpa_supplicant to control them internally. + * */ + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures = data->value; + break; + case IW_AUTH_DROP_UNENCRYPTED: + ieee->drop_unencrypted = data->value; + break; + + case IW_AUTH_80211_AUTH_ALG: + //printk("======>%s():data->value is %d\n",__FUNCTION__,data->value); + // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0; + if(data->value & IW_AUTH_ALG_SHARED_KEY){ + ieee->open_wep = 0; + ieee->auth_mode = 1; + } + else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){ + ieee->open_wep = 1; + ieee->auth_mode = 0; + } + else if(data->value & IW_AUTH_ALG_LEAP){ + ieee->open_wep = 1; + ieee->auth_mode = 2; + //printk("hahahaa:LEAP\n"); + } + else + return -EINVAL; + //printk("open_wep:%d\n", ieee->open_wep); + break; + +#if 1 + case IW_AUTH_WPA_ENABLED: + ieee->wpa_enabled = (data->value)?1:0; + //printk("enalbe wpa:%d\n", ieee->wpa_enabled); + break; + +#endif + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + ieee->ieee802_1x = data->value; + break; + case IW_AUTH_PRIVACY_INVOKED: + ieee->privacy_invoked = data->value; + break; + default: + return -EOPNOTSUPP; + } +#endif + return 0; +} +#endif +#if 1 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#if 0 + printk("====>%s()\n", __FUNCTION__); + { + int i; + for (i=0; iMAX_WPA_IE_LEN || (len && ie == NULL)) + { + // printk("return error out, len:%d\n", len); + return -EINVAL; + } + + + if (len) + { + if (len != ie[1]+2) + { + printk("len:%d, ie:%d\n", len, ie[1]); + return -EINVAL; + } + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memcpy(buf, ie, len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = len; + } + else{ + if (ieee->wpa_ie) + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } +#endif + return 0; + +} +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +//EXPORT_SYMBOL(ieee80211_wx_set_gen_ie); +#if (WIRELESS_EXT >= 18) +//EXPORT_SYMBOL(ieee80211_wx_set_mlme); +//EXPORT_SYMBOL(ieee80211_wx_set_auth); +//EXPORT_SYMBOL(ieee80211_wx_set_encode_ext); +//EXPORT_SYMBOL(ieee80211_wx_get_encode_ext); +#endif +//EXPORT_SYMBOL(ieee80211_wx_get_scan); +//EXPORT_SYMBOL(ieee80211_wx_set_encode); +//EXPORT_SYMBOL(ieee80211_wx_get_encode); +#else +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_gen_ie); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mlme); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_auth); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode_ext); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode); +//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/internal.h b/drivers/staging/rtl8192e/ieee80211/internal.h new file mode 100644 index 00000000000..ddc22350d00 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/internal.h @@ -0,0 +1,115 @@ +/* + * Cryptographic API. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#ifndef _CRYPTO_INTERNAL_H +#define _CRYPTO_INTERNAL_H + + +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) + +static inline void cond_resched(void) +{ + if (need_resched()) { + set_current_state(TASK_RUNNING); + schedule(); + } +} +#endif + +extern enum km_type crypto_km_types[]; + +static inline enum km_type crypto_kmap_type(int out) +{ + return crypto_km_types[(in_softirq() ? 2 : 0) + out]; +} + +static inline void *crypto_kmap(struct page *page, int out) +{ + return kmap_atomic(page, crypto_kmap_type(out)); +} + +static inline void crypto_kunmap(void *vaddr, int out) +{ + kunmap_atomic(vaddr, crypto_kmap_type(out)); +} + +static inline void crypto_yield(struct crypto_tfm *tfm) +{ + if (!in_softirq()) + cond_resched(); +} + +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) +{ + return (void *)&tfm[1]; +} + +struct crypto_alg *crypto_alg_lookup(const char *name); + +#ifdef CONFIG_KMOD +void crypto_alg_autoload(const char *name); +struct crypto_alg *crypto_alg_mod_lookup(const char *name); +#else +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + return crypto_alg_lookup(name); +} +#endif + +#ifdef CONFIG_CRYPTO_HMAC +int crypto_alloc_hmac_block(struct crypto_tfm *tfm); +void crypto_free_hmac_block(struct crypto_tfm *tfm); +#else +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm) +{ + return 0; +} + +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm) +{ } +#endif + +#ifdef CONFIG_PROC_FS +void __init crypto_init_proc(void); +#else +static inline void crypto_init_proc(void) +{ } +#endif + +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); + +int crypto_init_digest_ops(struct crypto_tfm *tfm); +int crypto_init_cipher_ops(struct crypto_tfm *tfm); +int crypto_init_compress_ops(struct crypto_tfm *tfm); + +void crypto_exit_digest_ops(struct crypto_tfm *tfm); +void crypto_exit_cipher_ops(struct crypto_tfm *tfm); +void crypto_exit_compress_ops(struct crypto_tfm *tfm); + +#endif /* _CRYPTO_INTERNAL_H */ + diff --git a/drivers/staging/rtl8192e/ieee80211/kmap_types.h b/drivers/staging/rtl8192e/ieee80211/kmap_types.h new file mode 100644 index 00000000000..de67bb01b5f --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/kmap_types.h @@ -0,0 +1,20 @@ +#ifndef __KMAP_TYPES_H + +#define __KMAP_TYPES_H + + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BH_IRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#define _ASM_KMAP_TYPES_H + +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/michael_mic.c b/drivers/staging/rtl8192e/ieee80211/michael_mic.c new file mode 100644 index 00000000000..df256e487c2 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/michael_mic.c @@ -0,0 +1,194 @@ +/* + * Cryptographic API + * + * Michael MIC (IEEE 802.11i/TKIP) keyed digest + * + * Copyright (c) 2004 Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +//#include +#include "rtl_crypto.h" + + +struct michael_mic_ctx { + u8 pending[4]; + size_t pending_len; + + u32 l, r; +}; + + +static inline u32 rotl(u32 val, int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + + +static inline u32 xswap(u32 val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + + +#define michael_block(l, r) \ +do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ +} while (0) + + +static inline u32 get_le32(const u8 *p) +{ + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + + +static inline void put_le32(u8 *p, u32 v) +{ + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +} + + +static void michael_init(void *ctx) +{ + struct michael_mic_ctx *mctx = ctx; + mctx->pending_len = 0; +} + + +static void michael_update(void *ctx, const u8 *data, unsigned int len) +{ + struct michael_mic_ctx *mctx = ctx; + + if (mctx->pending_len) { + int flen = 4 - mctx->pending_len; + if (flen > len) + flen = len; + memcpy(&mctx->pending[mctx->pending_len], data, flen); + mctx->pending_len += flen; + data += flen; + len -= flen; + + if (mctx->pending_len < 4) + return; + + mctx->l ^= get_le32(mctx->pending); + michael_block(mctx->l, mctx->r); + mctx->pending_len = 0; + } + + while (len >= 4) { + mctx->l ^= get_le32(data); + michael_block(mctx->l, mctx->r); + data += 4; + len -= 4; + } + + if (len > 0) { + mctx->pending_len = len; + memcpy(mctx->pending, data, len); + } +} + + +static void michael_final(void *ctx, u8 *out) +{ + struct michael_mic_ctx *mctx = ctx; + u8 *data = mctx->pending; + + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (mctx->pending_len) { + case 0: + mctx->l ^= 0x5a; + break; + case 1: + mctx->l ^= data[0] | 0x5a00; + break; + case 2: + mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000; + break; + case 3: + mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | + 0x5a000000; + break; + } + michael_block(mctx->l, mctx->r); + /* l ^= 0; */ + michael_block(mctx->l, mctx->r); + + put_le32(out, mctx->l); + put_le32(out + 4, mctx->r); +} + + +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) +{ + struct michael_mic_ctx *mctx = ctx; + if (keylen != 8) { + if (flags) + *flags = CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + mctx->l = get_le32(key); + mctx->r = get_le32(key + 4); + return 0; +} + + +static struct crypto_alg michael_mic_alg = { + .cra_name = "michael_mic", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct michael_mic_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = 8, + .dia_init = michael_init, + .dia_update = michael_update, + .dia_final = michael_final, + .dia_setkey = michael_setkey } } +}; + + +static int __init michael_mic_init(void) +{ + return crypto_register_alg(&michael_mic_alg); +} + + +static void __exit michael_mic_exit(void) +{ + crypto_unregister_alg(&michael_mic_alg); +} + + +module_init(michael_mic_init); +module_exit(michael_mic_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Michael MIC"); +MODULE_AUTHOR("Jouni Malinen "); diff --git a/drivers/staging/rtl8192e/ieee80211/proc.c b/drivers/staging/rtl8192e/ieee80211/proc.c new file mode 100644 index 00000000000..4f3f9ed7751 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/proc.c @@ -0,0 +1,116 @@ +/* + * Scatterlist Cryptographic API. + * + * Procfs information. + * + * Copyright (c) 2002 James Morris + * + * 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. + * + */ +#include +//#include +#include "rtl_crypto.h" +#include +#include +#include +#include "internal.h" + +extern struct list_head crypto_alg_list; +extern struct rw_semaphore crypto_alg_sem; + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + struct list_head *v; + loff_t n = *pos; + + down_read(&crypto_alg_sem); + list_for_each(v, &crypto_alg_list) + if (!n--) + return list_entry(v, struct crypto_alg, cra_list); + return NULL; +} + +static void *c_next(struct seq_file *m, void *p, loff_t *pos) +{ + struct list_head *v = p; + + (*pos)++; + v = v->next; + return (v == &crypto_alg_list) ? + NULL : list_entry(v, struct crypto_alg, cra_list); +} + +static void c_stop(struct seq_file *m, void *p) +{ + up_read(&crypto_alg_sem); +} + +static int c_show(struct seq_file *m, void *p) +{ + struct crypto_alg *alg = (struct crypto_alg *)p; + + seq_printf(m, "name : %s\n", alg->cra_name); + seq_printf(m, "module : %s\n", + (alg->cra_module ? + alg->cra_module->name : + "kernel")); + + switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { + case CRYPTO_ALG_TYPE_CIPHER: + seq_printf(m, "type : cipher\n"); + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); + seq_printf(m, "min keysize : %u\n", + alg->cra_cipher.cia_min_keysize); + seq_printf(m, "max keysize : %u\n", + alg->cra_cipher.cia_max_keysize); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + seq_printf(m, "type : digest\n"); + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); + seq_printf(m, "digestsize : %u\n", + alg->cra_digest.dia_digestsize); + break; + case CRYPTO_ALG_TYPE_COMPRESS: + seq_printf(m, "type : compression\n"); + break; + default: + seq_printf(m, "type : unknown\n"); + break; + } + + seq_putc(m, '\n'); + return 0; +} + +static struct seq_operations crypto_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show +}; + +static int crypto_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &crypto_seq_ops); +} + +static struct file_operations proc_crypto_ops = { + .open = crypto_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +void __init crypto_init_proc(void) +{ + struct proc_dir_entry *proc; + + proc = create_proc_entry("crypto", 0, NULL); + if (proc) + proc->proc_fops = &proc_crypto_ops; +} diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h new file mode 100644 index 00000000000..8ddc8bf9dc2 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h @@ -0,0 +1,69 @@ +#ifndef _BATYPE_H_ +#define _BATYPE_H_ + +#define TOTAL_TXBA_NUM 16 +#define TOTAL_RXBA_NUM 16 + +#define BA_SETUP_TIMEOUT 200 +#define BA_INACT_TIMEOUT 60000 + +#define BA_POLICY_DELAYED 0 +#define BA_POLICY_IMMEDIATE 1 + +#define ADDBA_STATUS_SUCCESS 0 +#define ADDBA_STATUS_REFUSED 37 +#define ADDBA_STATUS_INVALID_PARAM 38 + +#define DELBA_REASON_QSTA_LEAVING 36 +#define DELBA_REASON_END_BA 37 +#define DELBA_REASON_UNKNOWN_BA 38 +#define DELBA_REASON_TIMEOUT 39 +/* whether need define BA Action frames here? +struct ieee80211_ADDBA_Req{ + struct ieee80211_header_data header; + u8 category; + u8 +} __attribute__ ((packed)); +*/ +//Is this need?I put here just to make it easier to define structure BA_RECORD //WB +typedef union _SEQUENCE_CONTROL{ + u16 ShortData; + struct + { + u16 FragNum:4; + u16 SeqNum:12; + }field; +}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL; + +typedef union _BA_PARAM_SET { + u8 charData[2]; + u16 shortData; + struct { + u16 AMSDU_Support:1; + u16 BAPolicy:1; + u16 TID:4; + u16 BufferSize:10; + } field; +} BA_PARAM_SET, *PBA_PARAM_SET; + +typedef union _DELBA_PARAM_SET { + u8 charData[2]; + u16 shortData; + struct { + u16 Reserved:11; + u16 Initiator:1; + u16 TID:4; + } field; +} DELBA_PARAM_SET, *PDELBA_PARAM_SET; + +typedef struct _BA_RECORD { + struct timer_list Timer; + u8 bValid; + u8 DialogToken; + BA_PARAM_SET BaParamSet; + u16 BaTimeoutValue; + SEQUENCE_CONTROL BaStartSeqCtrl; +} BA_RECORD, *PBA_RECORD; + +#endif //end _BATYPE_H_ + diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c new file mode 100644 index 00000000000..98b3bb6b6d6 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -0,0 +1,779 @@ +/******************************************************************************************************************************** + * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is + * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send + * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. + * WB 2008-05-27 + * *****************************************************************************************************************************/ +#include "ieee80211.h" +#include "rtl819x_BA.h" + +/******************************************************************************************************************** + *function: Activate BA entry. And if Time is nozero, start timer. + * input: PBA_RECORD pBA //BA entry to be enabled + * u16 Time //indicate time delay. + * output: none +********************************************************************************************************************/ +void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time) +{ + pBA->bValid = true; + if(Time != 0) + mod_timer(&pBA->Timer, jiffies + MSECS(Time)); +} + +/******************************************************************************************************************** + *function: deactivate BA entry, including its timer. + * input: PBA_RECORD pBA //BA entry to be disabled + * output: none +********************************************************************************************************************/ +void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA) +{ + pBA->bValid = false; + del_timer_sync(&pBA->Timer); +} +/******************************************************************************************************************** + *function: deactivete BA entry in Tx Ts, and send DELBA. + * input: + * PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry. + * output: none + * notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME +********************************************************************************************************************/ +u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs) +{ + PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure + PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord; + u8 bSendDELBA = false; + + // Delete pending BA + if(pPendingBa->bValid) + { + DeActivateBAEntry(ieee, pPendingBa); + bSendDELBA = true; + } + + // Delete admitted BA + if(pAdmittedBa->bValid) + { + DeActivateBAEntry(ieee, pAdmittedBa); + bSendDELBA = true; + } + + return bSendDELBA; +} + +/******************************************************************************************************************** + *function: deactivete BA entry in Tx Ts, and send DELBA. + * input: + * PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry. + * output: none + * notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above +********************************************************************************************************************/ +u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs) +{ + PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord; + u8 bSendDELBA = false; + + if(pBa->bValid) + { + DeActivateBAEntry(ieee, pBa); + bSendDELBA = true; + } + + return bSendDELBA; +} + +/******************************************************************************************************************** + *function: reset BA entry + * input: + * PBA_RECORD pBA //entry to be reset + * output: none +********************************************************************************************************************/ +void ResetBaEntry( PBA_RECORD pBA) +{ + pBA->bValid = false; + pBA->BaParamSet.shortData = 0; + pBA->BaTimeoutValue = 0; + pBA->DialogToken = 0; + pBA->BaStartSeqCtrl.ShortData = 0; +} +//These functions need porting here or not? +/******************************************************************************************************************************* + *function: construct ADDBAREQ and ADDBARSP frame here together. + * input: u8* Dst //ADDBA frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA. + * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?) + * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ) + * output: none + * return: sk_buff* skb //return constructed skb to xmit +*******************************************************************************************************************************/ +static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type) +{ + struct sk_buff *skb = NULL; + struct ieee80211_hdr_3addr* BAReq = NULL; + u8* tag = NULL; + u16 tmp = 0; + u16 len = ieee->tx_headroom + 9; + //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); + if (pBA == NULL||ieee == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); + return NULL; + } + skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME + if (skb == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + return NULL; + } + + memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb. + skb_reserve(skb, ieee->tx_headroom); + + BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr)); + + memcpy(BAReq->addr1, Dst, ETH_ALEN); + memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); + + memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); + + BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame + + //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field + tag = (u8*)skb_put(skb, 9); + *tag ++= ACT_CAT_BA; + *tag ++= type; + // Dialog Token + *tag ++= pBA->DialogToken; + + if (ACT_ADDBARSP == type) + { + // Status Code + printk("=====>to send ADDBARSP\n"); + tmp = cpu_to_le16(StatusCode); + memcpy(tag, (u8*)&tmp, 2); + tag += 2; + } + // BA Parameter Set + tmp = cpu_to_le16(pBA->BaParamSet.shortData); + memcpy(tag, (u8*)&tmp, 2); + tag += 2; + // BA Timeout Value + tmp = cpu_to_le16(pBA->BaTimeoutValue); + memcpy(tag, (u8*)&tmp, 2); + tag += 2; + + if (ACT_ADDBAREQ == type) + { + // BA Start SeqCtrl + memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2); + tag += 2; + } + + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + return skb; + //return NULL; +} + +#if 0 //I try to merge ADDBA_REQ and ADDBA_RSP frames together.. +/******************************************************************************************************************** + *function: construct ADDBAREQ frame + * input: u8* dst //ADDBARsp frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA_RSP. + * u16 StatusCode //status code. + * output: none + * return: sk_buff* skb //return constructed skb to xmit +********************************************************************************************************************/ +static struct sk_buff* ieee80211_ADDBA_Rsp( IN struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) +{ + OCTET_STRING osADDBAFrame, tmp; + + FillOctetString(osADDBAFrame, Buffer, 0); + *pLength = 0; + + ConstructMaFrameHdr( + Adapter, + Addr, + ACT_CAT_BA, + ACT_ADDBARSP, + &osADDBAFrame ); + + // Dialog Token + FillOctetString(tmp, &pBA->DialogToken, 1); + PacketAppendData(&osADDBAFrame, tmp); + + // Status Code + FillOctetString(tmp, &StatusCode, 2); + PacketAppendData(&osADDBAFrame, tmp); + + // BA Parameter Set + FillOctetString(tmp, &pBA->BaParamSet, 2); + PacketAppendData(&osADDBAFrame, tmp); + + // BA Timeout Value + FillOctetString(tmp, &pBA->BaTimeoutValue, 2); + PacketAppendData(&osADDBAFrame, tmp); + + *pLength = osADDBAFrame.Length; +} +#endif + +/******************************************************************************************************************** + *function: construct DELBA frame + * input: u8* dst //DELBA frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA + * TR_SELECT TxRxSelect //TX RX direction + * u16 ReasonCode //status code. + * output: none + * return: sk_buff* skb //return constructed skb to xmit +********************************************************************************************************************/ +static struct sk_buff* ieee80211_DELBA( + struct ieee80211_device* ieee, + u8* dst, + PBA_RECORD pBA, + TR_SELECT TxRxSelect, + u16 ReasonCode + ) +{ + DELBA_PARAM_SET DelbaParamSet; + struct sk_buff *skb = NULL; + struct ieee80211_hdr_3addr* Delba = NULL; + u8* tag = NULL; + u16 tmp = 0; + //len = head len + DELBA Parameter Set(2) + Reason Code(2) + u16 len = 6 + ieee->tx_headroom; + + if (net_ratelimit()) + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); + + memset(&DelbaParamSet, 0, 2); + + DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0; + DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; + + skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME + if (skb == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + return NULL; + } +// memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr)); + skb_reserve(skb, ieee->tx_headroom); + + Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr)); + + memcpy(Delba->addr1, dst, ETH_ALEN); + memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); + Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame + + tag = (u8*)skb_put(skb, 6); + + *tag ++= ACT_CAT_BA; + *tag ++= ACT_DELBA; + + // DELBA Parameter Set + tmp = cpu_to_le16(DelbaParamSet.shortData); + memcpy(tag, (u8*)&tmp, 2); + tag += 2; + // Reason Code + tmp = cpu_to_le16(ReasonCode); + memcpy(tag, (u8*)&tmp, 2); + tag += 2; + + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + if (net_ratelimit()) + IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__); + return skb; +} + +/******************************************************************************************************************** + *function: send ADDBAReq frame out + * input: u8* dst //ADDBAReq frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA + * output: none + * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does +********************************************************************************************************************/ +void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA) +{ + struct sk_buff *skb = NULL; + skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero. + + if (skb) + { + softmac_mgmt_xmit(skb, ieee); + //add statistic needed here. + //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit() + //WB + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); + } + return; +} + +/******************************************************************************************************************** + *function: send ADDBARSP frame out + * input: u8* dst //DELBA frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA + * u16 StatusCode //RSP StatusCode + * output: none + * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does +********************************************************************************************************************/ +void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) +{ + struct sk_buff *skb = NULL; + skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames + if (skb) + { + softmac_mgmt_xmit(skb, ieee); + //same above + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); + } + + return; + +} +/******************************************************************************************************************** + *function: send ADDBARSP frame out + * input: u8* dst //DELBA frame's destination + * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA + * TR_SELECT TxRxSelect //TX or RX + * u16 ReasonCode //DEL ReasonCode + * output: none + * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does +********************************************************************************************************************/ + +void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode) +{ + struct sk_buff *skb = NULL; + skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames + if (skb) + { + softmac_mgmt_xmit(skb, ieee); + //same above + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); + } + return ; +} + +/******************************************************************************************************************** + *function: RX ADDBAReq + * input: struct sk_buff * skb //incoming ADDBAReq skb. + * return: 0(pass), other(fail) + * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. +********************************************************************************************************************/ +int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) +{ + struct ieee80211_hdr_3addr* req = NULL; + u16 rc = 0; + u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL; + PBA_RECORD pBA = NULL; + PBA_PARAM_SET pBaParamSet = NULL; + u16* pBaTimeoutVal = NULL; + PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL; + PRX_TS_RECORD pTS = NULL; + + if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + return -1; + } + + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + + req = ( struct ieee80211_hdr_3addr*) skb->data; + tag = (u8*)req; + dst = (u8*)(&req->addr2[0]); + tag += sizeof( struct ieee80211_hdr_3addr); + pDialogToken = tag + 2; //category+action + pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken + pBaTimeoutVal = (u16*)(tag + 5); + pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); + + printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); +//some other capability is not ready now. + if( (ieee->current_network.qos_data.active == 0) || + (ieee->pHTInfo->bCurrentHTSupport == false)) //|| + // (ieee->pStaQos->bEnableRxImmBA == false) ) + { + rc = ADDBA_STATUS_REFUSED; + IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); + goto OnADDBAReq_Fail; + } + // Search for related traffic stream. + // If there is no matched TS, reject the ADDBA request. + if( !GetTs( + ieee, + (PTS_COMMON_INFO*)(&pTS), + dst, + (u8)(pBaParamSet->field.TID), + RX_DIR, + true) ) + { + rc = ADDBA_STATUS_REFUSED; + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__); + goto OnADDBAReq_Fail; + } + pBA = &pTS->RxAdmittedBARecord; + // To Determine the ADDBA Req content + // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl... + // I want to check StartSeqCtrl to make sure when we start aggregation!!! + // + if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) + { + rc = ADDBA_STATUS_INVALID_PARAM; + IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__); + goto OnADDBAReq_Fail; + } + // Admit the ADDBA Request + // + DeActivateBAEntry(ieee, pBA); + pBA->DialogToken = *pDialogToken; + pBA->BaParamSet = *pBaParamSet; + pBA->BaTimeoutValue = *pBaTimeoutVal; + pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; + //for half N mode we only aggregate 1 frame + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + pBA->BaParamSet.field.BufferSize = 1; + else + pBA->BaParamSet.field.BufferSize = 32; + ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue); + ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); + + // End of procedure. + return 0; + +OnADDBAReq_Fail: + { + BA_RECORD BA; + BA.BaParamSet = *pBaParamSet; + BA.BaTimeoutValue = *pBaTimeoutVal; + BA.DialogToken = *pDialogToken; + BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; + ieee80211_send_ADDBARsp(ieee, dst, &BA, rc); + return 0; //we send RSP out. + } + +} + +/******************************************************************************************************************** + *function: RX ADDBARSP + * input: struct sk_buff * skb //incoming ADDBAReq skb. + * return: 0(pass), other(fail) + * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. +********************************************************************************************************************/ +int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) +{ + struct ieee80211_hdr_3addr* rsp = NULL; + PBA_RECORD pPendingBA, pAdmittedBA; + PTX_TS_RECORD pTS = NULL; + u8* dst = NULL, *pDialogToken = NULL, *tag = NULL; + u16* pStatusCode = NULL, *pBaTimeoutVal = NULL; + PBA_PARAM_SET pBaParamSet = NULL; + u16 ReasonCode; + + if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); + return -1; + } + rsp = ( struct ieee80211_hdr_3addr*)skb->data; + tag = (u8*)rsp; + dst = (u8*)(&rsp->addr2[0]); + tag += sizeof( struct ieee80211_hdr_3addr); + pDialogToken = tag + 2; + pStatusCode = (u16*)(tag + 3); + pBaParamSet = (PBA_PARAM_SET)(tag + 5); + pBaTimeoutVal = (u16*)(tag + 7); + + // Check the capability + // Since we can always receive A-MPDU, we just check if it is under HT mode. + if( ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false || + ieee->pHTInfo->bCurrentAMPDUEnable == false ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } + + + // + // Search for related TS. + // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame. + // + if (!GetTs( + ieee, + (PTS_COMMON_INFO*)(&pTS), + dst, + (u8)(pBaParamSet->field.TID), + TX_DIR, + false) ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } + + pTS->bAddBaReqInProgress = false; + pPendingBA = &pTS->TxPendingBARecord; + pAdmittedBA = &pTS->TxAdmittedBARecord; + + + // + // Check if related BA is waiting for setup. + // If not, reject by sending DELBA frame. + // + if((pAdmittedBA->bValid==true)) + { + // Since BA is already setup, we ignore all other ADDBA Response. + IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n"); + return -1; + } + else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken)) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n"); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode); + DeActivateBAEntry(ieee, pPendingBA); + } + + + if(*pStatusCode == ADDBA_STATUS_SUCCESS) + { + // + // Determine ADDBA Rsp content here. + // We can compare the value of BA parameter set that Peer returned and Self sent. + // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism. + // + if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) + { + // Since this is a kind of ADDBA failed, we delay next ADDBA process. + pTS->bAddBaReqDelayed = true; + DeActivateBAEntry(ieee, pAdmittedBA); + ReasonCode = DELBA_REASON_END_BA; + goto OnADDBARsp_Reject; + } + + + // + // Admitted condition + // + pAdmittedBA->DialogToken = *pDialogToken; + pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; + pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; + pAdmittedBA->BaParamSet = *pBaParamSet; + DeActivateBAEntry(ieee, pAdmittedBA); + ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); + } + else + { + // Delay next ADDBA process. + pTS->bAddBaReqDelayed = true; + } + + // End of procedure + return 0; + +OnADDBARsp_Reject: + { + BA_RECORD BA; + BA.BaParamSet = *pBaParamSet; + ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); + return 0; + } + +} + +/******************************************************************************************************************** + *function: RX DELBA + * input: struct sk_buff * skb //incoming ADDBAReq skb. + * return: 0(pass), other(fail) + * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. +********************************************************************************************************************/ +int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) +{ + struct ieee80211_hdr_3addr* delba = NULL; + PDELBA_PARAM_SET pDelBaParamSet = NULL; + u16* pReasonCode = NULL; + u8* dst = NULL; + + if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); + return -1; + } + + if(ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); + return -1; + } + + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + delba = ( struct ieee80211_hdr_3addr*)skb->data; + dst = (u8*)(&delba->addr2[0]); + delba += sizeof( struct ieee80211_hdr_3addr); + pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2); + pReasonCode = (u16*)(delba+4); + + if(pDelBaParamSet->field.Initiator == 1) + { + PRX_TS_RECORD pRxTs; + + if( !GetTs( + ieee, + (PTS_COMMON_INFO*)&pRxTs, + dst, + (u8)pDelBaParamSet->field.TID, + RX_DIR, + false) ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __FUNCTION__); + return -1; + } + + RxTsDeleteBA(ieee, pRxTs); + } + else + { + PTX_TS_RECORD pTxTs; + + if(!GetTs( + ieee, + (PTS_COMMON_INFO*)&pTxTs, + dst, + (u8)pDelBaParamSet->field.TID, + TX_DIR, + false) ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__); + return -1; + } + + pTxTs->bUsingBa = false; + pTxTs->bAddBaReqInProgress = false; + pTxTs->bAddBaReqDelayed = false; + del_timer_sync(&pTxTs->TsAddBaTimer); + //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer); + TxTsDeleteBA(ieee, pTxTs); + } + return 0; +} + +// +// ADDBA initiate. This can only be called by TX side. +// +void +TsInitAddBA( + struct ieee80211_device* ieee, + PTX_TS_RECORD pTS, + u8 Policy, + u8 bOverwritePending + ) +{ + PBA_RECORD pBA = &pTS->TxPendingBARecord; + + if(pBA->bValid==true && bOverwritePending==false) + return; + + // Set parameters to "Pending" variable set + DeActivateBAEntry(ieee, pBA); + + pBA->DialogToken++; // DialogToken: Only keep the latest dialog token + pBA->BaParamSet.field.AMSDU_Support = 0; // Do not support A-MSDU with A-MPDU now!! + pBA->BaParamSet.field.BAPolicy = Policy; // Policy: Delayed or Immediate + pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; // TID + // BufferSize: This need to be set according to A-MPDU vector + pBA->BaParamSet.field.BufferSize = 32; // BufferSize: This need to be set according to A-MPDU vector + pBA->BaTimeoutValue = 0; // Timeout value: Set 0 to disable Timer + pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; // Block Ack will start after 3 packets later. + + ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); + + ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); +} + +void +TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect) +{ + + if(TxRxSelect == TX_DIR) + { + PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo; + + if(TxTsDeleteBA(ieee, pTxTs)) + ieee80211_send_DELBA( + ieee, + pTsCommonInfo->Addr, + (pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord), + TxRxSelect, + DELBA_REASON_END_BA); + } + else if(TxRxSelect == RX_DIR) + { + PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo; + if(RxTsDeleteBA(ieee, pRxTs)) + ieee80211_send_DELBA( + ieee, + pTsCommonInfo->Addr, + &pRxTs->RxAdmittedBARecord, + TxRxSelect, + DELBA_REASON_END_BA ); + } +} +/******************************************************************************************************************** + *function: BA setup timer + * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer + * return: NULL + * notice: +********************************************************************************************************************/ +void BaSetupTimeOut(unsigned long data) +{ + PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; + + pTxTs->bAddBaReqInProgress = false; + pTxTs->bAddBaReqDelayed = true; + pTxTs->TxPendingBARecord.bValid = false; +} + +void TxBaInactTimeout(unsigned long data) +{ + PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; + struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]); + TxTsDeleteBA(ieee, pTxTs); + ieee80211_send_DELBA( + ieee, + pTxTs->TsCommonInfo.Addr, + &pTxTs->TxAdmittedBARecord, + TX_DIR, + DELBA_REASON_TIMEOUT); +} + +void RxBaInactTimeout(unsigned long data) +{ + PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; + struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); + + RxTsDeleteBA(ieee, pRxTs); + ieee80211_send_DELBA( + ieee, + pRxTs->TsCommonInfo.Addr, + &pRxTs->RxAdmittedBARecord, + RX_DIR, + DELBA_REASON_TIMEOUT); + return ; +} + diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h new file mode 100644 index 00000000000..992b71825a8 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h @@ -0,0 +1,481 @@ +#ifndef _RTL819XU_HTTYPE_H_ +#define _RTL819XU_HTTYPE_H_ + +//------------------------------------------------------------ +// The HT Capability element is present in beacons, association request, +// reassociation request and probe response frames +//------------------------------------------------------------ + +// +// Operation mode value +// +#define HT_OPMODE_NO_PROTECT 0 +#define HT_OPMODE_OPTIONAL 1 +#define HT_OPMODE_40MHZ_PROTECT 2 +#define HT_OPMODE_MIXED 3 + +// +// MIMO Power Save Setings +// +#define MIMO_PS_STATIC 0 +#define MIMO_PS_DYNAMIC 1 +#define MIMO_PS_NOLIMIT 3 + + +// +// There should be 128 bits to cover all of the MCS rates. However, since +// 8190 does not support too much rates, one integer is quite enough. +// + +#define sHTCLng 4 + + +#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff +#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00 +#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP + + +typedef enum _HT_MCS_RATE{ + HT_MCS0 = 0x00000001, + HT_MCS1 = 0x00000002, + HT_MCS2 = 0x00000004, + HT_MCS3 = 0x00000008, + HT_MCS4 = 0x00000010, + HT_MCS5 = 0x00000020, + HT_MCS6 = 0x00000040, + HT_MCS7 = 0x00000080, + HT_MCS8 = 0x00000100, + HT_MCS9 = 0x00000200, + HT_MCS10 = 0x00000400, + HT_MCS11 = 0x00000800, + HT_MCS12 = 0x00001000, + HT_MCS13 = 0x00002000, + HT_MCS14 = 0x00004000, + HT_MCS15 = 0x00008000, + // Do not define MCS32 here although 8190 support MCS32 +}HT_MCS_RATE,*PHT_MCS_RATE; + +// +// Represent Channel Width in HT Capabilities +// +typedef enum _HT_CHANNEL_WIDTH{ + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, +}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; + +// +// Represent Extention Channel Offset in HT Capabilities +// This is available only in 40Mhz mode. +// +typedef enum _HT_EXTCHNL_OFFSET{ + HT_EXTCHNL_OFFSET_NO_EXT = 0, + HT_EXTCHNL_OFFSET_UPPER = 1, + HT_EXTCHNL_OFFSET_NO_DEF = 2, + HT_EXTCHNL_OFFSET_LOWER = 3, +}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET; + +typedef enum _CHNLOP{ + CHNLOP_NONE = 0, // No Action now + CHNLOP_SCAN = 1, // Scan in progress + CHNLOP_SWBW = 2, // Bandwidth switching in progress + CHNLOP_SWCHNL = 3, // Software Channel switching in progress +} CHNLOP, *PCHNLOP; + +// Determine if the Channel Operation is in progress +#define CHHLOP_IN_PROGRESS(_pHTInfo) \ + ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE + +/* +typedef union _HT_CAPABILITY{ + u16 ShortData; + u8 CharData[2]; + struct + { + u16 AdvCoding:1; + u16 ChlWidth:1; + u16 MimoPwrSave:2; + u16 GreenField:1; + u16 ShortGI20Mhz:1; + u16 ShortGI40Mhz:1; + u16 STBC:1; + u16 BeamForm:1; + u16 DelayBA:1; + u16 MaxAMSDUSize:1; + u16 DssCCk:1; + u16 PSMP:1; + u16 Rsvd:3; + }Field; +}HT_CAPABILITY, *PHT_CAPABILITY; + +typedef union _HT_CAPABILITY_MACPARA{ + u8 ShortData; + u8 CharData[1]; + struct + { + u8 MaxRxAMPDU:2; + u8 MPDUDensity:2; + u8 Rsvd:4; + }Field; +}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA; +*/ + +typedef enum _HT_ACTION{ + ACT_RECOMMAND_WIDTH = 0, + ACT_MIMO_PWR_SAVE = 1, + ACT_PSMP = 2, + ACT_SET_PCO_PHASE = 3, + ACT_MIMO_CHL_MEASURE = 4, + ACT_RECIPROCITY_CORRECT = 5, + ACT_MIMO_CSI_MATRICS = 6, + ACT_MIMO_NOCOMPR_STEER = 7, + ACT_MIMO_COMPR_STEER = 8, + ACT_ANTENNA_SELECT = 9, +} HT_ACTION, *PHT_ACTION; + + +/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */ +typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{ + SC_MODE_DUPLICATE = 0, + SC_MODE_LOWER = 1, + SC_MODE_UPPER = 2, + SC_MODE_FULL40MHZ = 3, +}HT_BW40_SC_E; + +typedef struct _HT_CAPABILITY_ELE{ + + //HT capability info + u8 AdvCoding:1; + u8 ChlWidth:1; + u8 MimoPwrSave:2; + u8 GreenField:1; + u8 ShortGI20Mhz:1; + u8 ShortGI40Mhz:1; + u8 TxSTBC:1; + u8 RxSTBC:2; + u8 DelayBA:1; + u8 MaxAMSDUSize:1; + u8 DssCCk:1; + u8 PSMP:1; + u8 Rsvd1:1; + u8 LSigTxopProtect:1; + + //MAC HT parameters info + u8 MaxRxAMPDUFactor:2; + u8 MPDUDensity:3; + u8 Rsvd2:3; + + //Supported MCS set + u8 MCS[16]; + + + //Extended HT Capability Info + u16 ExtHTCapInfo; + + //TXBF Capabilities + u8 TxBFCap[4]; + + //Antenna Selection Capabilities + u8 ASCap; + +} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE; + +//------------------------------------------------------------ +// The HT Information element is present in beacons +// Only AP is required to include this element +//------------------------------------------------------------ + +typedef struct _HT_INFORMATION_ELE{ + u8 ControlChl; + + u8 ExtChlOffset:2; + u8 RecommemdedTxWidth:1; + u8 RIFS:1; + u8 PSMPAccessOnly:1; + u8 SrvIntGranularity:3; + + u8 OptMode:2; + u8 NonGFDevPresent:1; + u8 Revd1:5; + u8 Revd2:8; + + u8 Rsvd3:6; + u8 DualBeacon:1; + u8 DualCTSProtect:1; + + u8 SecondaryBeacon:1; + u8 LSigTxopProtectFull:1; + u8 PcoActive:1; + u8 PcoPhase:1; + u8 Rsvd4:4; + + u8 BasicMSC[16]; +} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE; + +// +// MIMO Power Save control field. +// This is appear in MIMO Power Save Action Frame +// +typedef struct _MIMOPS_CTRL{ + u8 MimoPsEnable:1; + u8 MimoPsMode:1; + u8 Reserved:6; +} MIMOPS_CTRL, *PMIMOPS_CTRL; + +typedef enum _HT_SPEC_VER{ + HT_SPEC_VER_IEEE = 0, + HT_SPEC_VER_EWC = 1, +}HT_SPEC_VER, *PHT_SPEC_VER; + +typedef enum _HT_AGGRE_MODE_E{ + HT_AGG_AUTO = 0, + HT_AGG_FORCE_ENABLE = 1, + HT_AGG_FORCE_DISABLE = 2, +}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E; + +//------------------------------------------------------------ +// The Data structure is used to keep HT related variables when card is +// configured as non-AP STA mode. **Note** Current_xxx should be set +// to default value in HTInitializeHTInfo() +//------------------------------------------------------------ + +typedef struct _RT_HIGH_THROUGHPUT{ + u8 bEnableHT; + u8 bCurrentHTSupport; + + u8 bRegBW40MHz; // Tx 40MHz channel capablity + u8 bCurBW40MHz; // Tx 40MHz channel capability + + u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz + u8 bCurShortGI40MHz; // Tx Short GI for 40MHz + + u8 bRegShortGI20MHz; // Tx Short GI for 20MHz + u8 bCurShortGI20MHz; // Tx Short GI for 20MHz + + u8 bRegSuppCCK; // Tx CCK rate capability + u8 bCurSuppCCK; // Tx CCK rate capability + + // 802.11n spec version for "peer" + HT_SPEC_VER ePeerHTSpecVer; + + + // HT related information for "Self" + HT_CAPABILITY_ELE SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities. + HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities. + + // HT related information for "Peer" + u8 PeerHTCapBuf[32]; + u8 PeerHTInfoBuf[32]; + + + // A-MSDU related + u8 bAMSDU_Support; // This indicates Tx A-MSDU capability + u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability + u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability + u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability + + + // AMPDU related <2006.08.10 Emily> + u8 bAMPDUEnable; // This indicate Tx A-MPDU capability + u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability + u8 AMPDU_Factor; // This indicate Tx A-MPDU capability + u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability + u8 MPDU_Density; // This indicate Tx A-MPDU capability + u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability + + // Forced A-MPDU enable + HT_AGGRE_MODE_E ForcedAMPDUMode; + u8 ForcedAMPDUFactor; + u8 ForcedMPDUDensity; + + // Forced A-MSDU enable + HT_AGGRE_MODE_E ForcedAMSDUMode; + u16 ForcedAMSDUMaxSize; + + u8 bForcedShortGI; + + u8 CurrentOpMode; + + // MIMO PS related + u8 SelfMimoPs; + u8 PeerMimoPs; + + // 40MHz Channel Offset settings. + HT_EXTCHNL_OFFSET CurSTAExtChnlOffset; + u8 bCurTxBW40MHz; // If we use 40 MHz to Tx + u8 PeerBandwidth; + + // For Bandwidth Switching + u8 bSwBwInProgress; + CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15. + u8 SwBwStep; + //struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here. + + // For Realtek proprietary A-MPDU factor for aggregation + u8 bRegRT2RTAggregation; + u8 bCurrentRT2RTAggregation; + u8 bCurrentRT2RTLongSlotTime; + u8 szRT2RTAggBuffer[10]; + + // Rx Reorder control + u8 bRegRxReorderEnable; + u8 bCurRxReorderEnable; + u8 RxReorderWinSize; + u8 RxReorderPendingTime; + u16 RxReorderDropCounter; + +#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE + u8 UsbTxAggrNum; +#endif +#ifdef USB_RX_AGGREGATION_SUPPORT + u8 UsbRxFwAggrEn; + u8 UsbRxFwAggrPageNum; + u8 UsbRxFwAggrPacketNum; + u8 UsbRxFwAggrTimeout; +#endif + + // Add for Broadcom(Linksys) IOT. Joseph + u8 bIsPeerBcm; + + // For IOT issue. + u8 IOTPeer; + u32 IOTAction; +} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT; + + +//------------------------------------------------------------ +// The Data structure is used to keep HT related variable for "each Sta" +// when card is configured as "AP mode" +//------------------------------------------------------------ + +typedef struct _RT_HTINFO_STA_ENTRY{ + u8 bEnableHT; + + u8 bSupportCck; + + u16 AMSDU_MaxSize; + + u8 AMPDU_Factor; + u8 MPDU_Density; + + u8 HTHighestOperaRate; + + u8 bBw40MHz; + + u8 MimoPs; + + u8 McsRateSet[16]; + + +}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY; + + + + + +//------------------------------------------------------------ +// The Data structure is used to keep HT related variable for "each AP" +// when card is configured as "STA mode" +//------------------------------------------------------------ + +typedef struct _BSS_HT{ + + u8 bdSupportHT; + + // HT related elements + u8 bdHTCapBuf[32]; + u16 bdHTCapLen; + u8 bdHTInfoBuf[32]; + u16 bdHTInfoLen; + + HT_SPEC_VER bdHTSpecVer; + //HT_CAPABILITY_ELE bdHTCapEle; + //HT_INFORMATION_ELE bdHTInfoEle; + + u8 bdRT2RTAggregation; + u8 bdRT2RTLongSlotTime; +} __attribute__ ((packed)) BSS_HT, *PBSS_HT; + +typedef struct _MIMO_RSSI{ + u32 EnableAntenna; + u32 AntennaA; + u32 AntennaB; + u32 AntennaC; + u32 AntennaD; + u32 Average; +}MIMO_RSSI, *PMIMO_RSSI; + +typedef struct _MIMO_EVM{ + u32 EVM1; + u32 EVM2; +}MIMO_EVM, *PMIMO_EVM; + +typedef struct _FALSE_ALARM_STATISTICS{ + u32 Cnt_Parity_Fail; + u32 Cnt_Rate_Illegal; + u32 Cnt_Crc8_fail; + u32 Cnt_all; +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; + + +extern u8 MCS_FILTER_ALL[16]; +extern u8 MCS_FILTER_1SS[16]; + +/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set + STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have + to add a macro to judge wireless mode. */ +#define PICK_RATE(_nLegacyRate, _nMcsRate) \ + (_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate) +/* 2007/07/12 MH We only define legacy and HT wireless mode now. */ +#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK + +#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ + ((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\ + (LegacyRate):\ + (PICK_RATE(LegacyRate, HTRate)) + + + +// MCS Bw 40 {1~7, 12~15,32} +#define RATE_ADPT_1SS_MASK 0xFF +#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily +#define RATE_ADPT_MCS32_MASK 0x01 + +#define IS_11N_MCS_RATE(rate) (rate&0x80) + +typedef enum _HT_AGGRE_SIZE{ + HT_AGG_SIZE_8K = 0, + HT_AGG_SIZE_16K = 1, + HT_AGG_SIZE_32K = 2, + HT_AGG_SIZE_64K = 3, +}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E; + +/* Indicate different AP vendor for IOT issue */ +typedef enum _HT_IOT_PEER +{ + HT_IOT_PEER_UNKNOWN = 0, + HT_IOT_PEER_REALTEK = 1, + HT_IOT_PEER_BROADCOM = 2, + HT_IOT_PEER_RALINK = 3, + HT_IOT_PEER_ATHEROS = 4, + HT_IOT_PEER_CISCO= 5, + HT_IOT_PEER_MAX = 6 +}HT_IOT_PEER_E, *PHTIOT_PEER_E; + +// +// IOT Action for different AP +// +typedef enum _HT_IOT_ACTION{ + HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, + HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, + HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, + HT_IOT_ACT_DISABLE_MCS15 = 0x00000008, + HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010, + HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020, + HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040, + HT_IOT_ACT_CDD_FSYNC = 0x00000080, + HT_IOT_ACT_PURE_N_MODE = 0x00000100, + HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, +}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; + +#endif //_RTL819XU_HTTYPE_H_ + diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c new file mode 100644 index 00000000000..1e392141779 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -0,0 +1,1719 @@ + +//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08 +#include "ieee80211.h" +#include "rtl819x_HT.h" +u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +u16 MCS_DATA_RATE[2][2][77] = + { { {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260, + 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520, + 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195, + 195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260, + 286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429}, // Long GI, 20MHz + {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, + 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578, + 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217, + 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289, + 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477} }, // Short GI, 20MHz + { {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, + 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080, + 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405, + 405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540, + 594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, // Long GI, 40MHz + {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, + 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200, + 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450, + 450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600, + 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} } // Short GI, 40MHz + }; + +static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; +static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; +static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; +static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; +static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 +static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; +static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; +static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; +static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; +static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; +static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; + +// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the +// code in other place?? +//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; +/******************************************************************************************************************** + *function: This function update default settings in pHTInfo structure + * input: PRT_HIGH_THROUGHPUT pHTInfo + * output: none + * return: none + * notice: These value need be modified if any changes. + * *****************************************************************************************************************/ +void HTUpdateDefaultSetting(struct ieee80211_device* ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + //const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo; + + //printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p, offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo)); + //printk("===>ieee:%p,\n", ieee); + // ShortGI support + pHTInfo->bRegShortGI20MHz= 1; + pHTInfo->bRegShortGI40MHz= 1; + + // 40MHz channel support + pHTInfo->bRegBW40MHz = 1; + + // CCK rate support in 40MHz channel + if(pHTInfo->bRegBW40MHz) + pHTInfo->bRegSuppCCK = 1; + else + pHTInfo->bRegSuppCCK = true; + + // AMSDU related + pHTInfo->nAMSDU_MaxSize = 7935UL; + pHTInfo->bAMSDU_Support = 0; + + // AMPDU related + pHTInfo->bAMPDUEnable = 1; + pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k) + pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec + + // MIMO Power Save + pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.) + if(pHTInfo->SelfMimoPs == 2) + pHTInfo->SelfMimoPs = 3; + // 8190 only. Assign rate operation mode to firmware + ieee->bTxDisableRateFallBack = 0; + ieee->bTxUseDriverAssingedRate = 0; + +#ifdef TO_DO_LIST + // 8190 only. Assign duration operation mode to firmware + pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur; +#endif + // 8190 only, Realtek proprietary aggregation mode + // Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others + pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others + + // For Rx Reorder Control + pHTInfo->bRegRxReorderEnable = 1; + pHTInfo->RxReorderWinSize = 64; + pHTInfo->RxReorderPendingTime = 30; + +#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE + pHTInfo->UsbTxAggrNum = 4; +#endif +#ifdef USB_RX_AGGREGATION_SUPPORT + pHTInfo->UsbRxFwAggrEn = 1; + pHTInfo->UsbRxFwAggrPageNum = 24; + pHTInfo->UsbRxFwAggrPacketNum = 8; + pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us +#endif + + +} +/******************************************************************************************************************** + *function: This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq) + * input: u8* CapIE //Capability IE to be printed out + * u8* TitleString //mainly print out caller function + * output: none + * return: none + * notice: Driver should not print out this message by default. + * *****************************************************************************************************************/ +void HTDebugHTCapability(u8* CapIE, u8* TitleString ) +{ + + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + PHT_CAPABILITY_ELE pCapELE; + + if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) + { + //EWC IE + IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__); + pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]); + }else + pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]); + + IEEE80211_DEBUG(IEEE80211_DL_HT, ". Called by %s\n", TitleString ); + + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO"); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\ + pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]); + return; + +} +/******************************************************************************************************************** + *function: This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp) + * input: u8* InfoIE //Capability IE to be printed out + * u8* TitleString //mainly print out caller function + * output: none + * return: none + * notice: Driver should not print out this message by default. + * *****************************************************************************************************************/ +void HTDebugHTInfo(u8* InfoIE, u8* TitleString) +{ + + static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily + PHT_INFORMATION_ELE pHTInfoEle; + + if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + { + // Not EWC IE + IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__); + pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]); + }else + pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]); + + + IEEE80211_DEBUG(IEEE80211_DL_HT, ". Called by %s\n", TitleString); + + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl); + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel ="); + switch(pHTInfoEle->ExtChlOffset) + { + case 0: + IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n"); + break; + case 1: + IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n"); + break; + case 2: + IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n"); + break; + case 3: + IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n"); + break; + } + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz"); + + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = "); + switch(pHTInfoEle->OptMode) + { + case 0: + IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n"); + break; + case 1: + IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n"); + break; + case 2: + IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n"); + break; + case 3: + IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n"); + break; + } + + IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\ + pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]); + return; +} + +/* +* Return: true if station in half n mode and AP supports 40 bw +*/ +bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee) +{ + bool retValue = false; + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode + retValue = false; + else if(pHTInfo->bRegBW40MHz == false) // station supports 40 bw + retValue = false; + else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode + retValue = false; + else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw + retValue = true; + else + retValue = false; + + return retValue; +} + +bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz) +{ + bool retValue = false; + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode + retValue = false; + else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode + retValue = false; + else if(is40MHz) // ap support 40 bw + { + if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI + retValue = true; + else + retValue = false; + } + else + { + if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI + retValue = true; + else + retValue = false; + } + + return retValue; +} + +u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate) +{ + + u8 is40MHz; + u8 isShortGI; + + is40MHz = (IsHTHalfNmode40Bandwidth(ieee))?1:0; + isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0; + + return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)]; +} + + +u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + u8 is40MHz = (pHTInfo->bCurBW40MHz)?1:0; + u8 isShortGI = (pHTInfo->bCurBW40MHz)? + ((pHTInfo->bCurShortGI40MHz)?1:0): + ((pHTInfo->bCurShortGI20MHz)?1:0); + return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)]; +} + +/******************************************************************************************************************** + *function: This function returns current datarate. + * input: struct ieee80211_device* ieee + * u8 nDataRate + * output: none + * return: tx rate + * notice: quite unsure about how to use this function //wb + * *****************************************************************************************************************/ +u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate) +{ + //PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + u16 CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c}; + u8 is40MHz = 0; + u8 isShortGI = 0; + + if(nDataRate < 12) + { + return CCKOFDMRate[nDataRate]; + } + else + { + if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 ) + { + is40MHz = 0; + isShortGI = 0; + + // nDataRate = nDataRate - 12; + } + else if(nDataRate >=0x20 && nDataRate <= 0x2f ) //(27, 44) + { + is40MHz = 1; + isShortGI = 0; + + //nDataRate = nDataRate - 28; + } + else if(nDataRate >= 0x30 && nDataRate <= 0x3f ) //(43, 60) + { + is40MHz = 0; + isShortGI = 1; + + //nDataRate = nDataRate - 44; + } + else if(nDataRate >= 0x40 && nDataRate <= 0x4f ) //(59, 76) + { + is40MHz = 1; + isShortGI = 1; + + //nDataRate = nDataRate - 60; + } + return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf]; + } +} + + + +bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee) +{ + bool retValue = false; + struct ieee80211_network* net = &ieee->current_network; +#if 0 + if(pMgntInfo->bHalfNMode == false) + retValue = false; + else +#endif + if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || + (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || + (memcmp(net->bssid, PCI_RALINK, 3)==0) || + (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || + (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || + (net->ralink_cap_exist)) + retValue = true; + else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || + (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| + (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| + (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) || + (net->broadcom_cap_exist)) + retValue = true; + else if(net->bssht.bdRT2RTAggregation) + retValue = true; + else + retValue = false; + + return retValue; +} + +/******************************************************************************************************************** + *function: This function returns peer IOT. + * input: struct ieee80211_device* ieee + * output: none + * return: + * notice: + * *****************************************************************************************************************/ +void HTIOTPeerDetermine(struct ieee80211_device* ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + struct ieee80211_network* net = &ieee->current_network; + if(net->bssht.bdRT2RTAggregation) + pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; + else if(net->broadcom_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || + (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| + (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| + (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ) + pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || + (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || + (memcmp(net->bssid, PCI_RALINK, 3)==0) || + (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || + (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || + net->ralink_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; + else if((net->atheros_cap_exist )|| (memcmp(net->bssid, DLINK_ATHEROS, 3) == 0)) + pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; + else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0) + pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; + else + pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; + + IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer); +} +/******************************************************************************************************************** + *function: Check whether driver should declare received rate up to MCS13 only since some chipset is not good + * at receiving MCS14~15 frame from some AP. + * input: struct ieee80211_device* ieee + * u8 * PeerMacAddr + * output: none + * return: return 1 if driver should declare MCS13 only(otherwise return 0) + * *****************************************************************************************************************/ +u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr) +{ + u8 ret = 0; +#if 0 + // Apply for 819u only +#if (HAL_CODE_BASE==RTL8192 && DEV_BUS_TYPE==USB_INTERFACE) + if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) || + (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) + ) + { + ret = 1; + } + + + if(pHTInfo->bCurrentRT2RTAggregation) + { + // The parameter of pHTInfo->bCurrentRT2RTAggregation must be decided previously + ret = 1; + } +#endif +#endif + return ret; + } + + +/** +* Function: HTIOTActIsDisableMCS15 +* +* Overview: Check whether driver should declare capability of receving MCS15 +* +* Input: +* PADAPTER Adapter, +* +* Output: None +* Return: true if driver should disable MCS15 +* 2008.04.15 Emily +*/ +bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee) +{ + bool retValue = false; + +#ifdef TODO + // Apply for 819u only +#if (HAL_CODE_BASE==RTL8192) + +#if (DEV_BUS_TYPE == USB_INTERFACE) + // Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15 + retValue = true; +#elif (DEV_BUS_TYPE == PCI_INTERFACE) + // Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12 +// if(pBssDesc->bCiscoCapExist) +// retValue = false; +// else + retValue = false; +#endif +#endif +#endif + // Jerry Chang suggest that 8190 1x2 does not need to disable MCS15 + + return retValue; +} + +/** +* Function: HTIOTActIsDisableMCSTwoSpatialStream +* +* Overview: Check whether driver should declare capability of receving All 2 ss packets +* +* Input: +* PADAPTER Adapter, +* +* Output: None +* Return: true if driver should disable all two spatial stream packet +* 2008.04.21 Emily +*/ +bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee, u8 *PeerMacAddr) +{ + bool retValue = false; + +#ifdef TODO + // Apply for 819u only +//#if (HAL_CODE_BASE==RTL8192) + + //This rule only apply to Belkin(Ralink) AP + if(IS_UNDER_11N_AES_MODE(Adapter)) + { + if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) || + (PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) || + (PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0)) + { + //Set True to disable this function. Disable by default, Emily, 2008.04.23 + retValue = false; + } + } + +//#endif +#endif + return retValue; +} + +/******************************************************************************************************************** + *function: Check whether driver should disable EDCA turbo mode + * input: struct ieee80211_device* ieee + * u8* PeerMacAddr + * output: none + * return: return 1 if driver should disable EDCA turbo mode(otherwise return 0) + * *****************************************************************************************************************/ +u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* ieee, u8* PeerMacAddr) +{ + u8 retValue = false; // default enable EDCA Turbo mode. + // Set specific EDCA parameter for different AP in DM handler. + + return retValue; +#if 0 + if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0)|| + (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| + (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| + (memcmp(PeerMacAddr, NETGEAR834Bv2_BROADCOM, 3)==0)) + + { + retValue = 1; //Linksys disable EDCA turbo mode + } + + return retValue; +#endif +} + +/******************************************************************************************************************** + *function: Check whether we need to use OFDM to sned MGNT frame for broadcom AP + * input: struct ieee80211_network *network //current network we live + * output: none + * return: return 1 if true + * *****************************************************************************************************************/ +u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network) +{ + u8 retValue = 0; + + // 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP. + // 2008/01/28 MH We must prevent that we select null bssid to link. + + if(network->broadcom_cap_exist) + { + retValue = 1; + } + + return retValue; +} + +u8 HTIOTActIsCCDFsync(u8* PeerMacAddr) +{ + u8 retValue = 0; + if( (memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) || + (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) || + (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0)) + { + retValue = 1; + } + + return retValue; +} + +void HTResetIOTSetting( + PRT_HIGH_THROUGHPUT pHTInfo +) +{ + pHTInfo->IOTAction = 0; + pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; +} + + +/******************************************************************************************************************** + *function: Construct Capablility Element in Beacon... if HTEnable is turned on + * input: struct ieee80211_device* ieee + * u8* posHTCap //pointer to store Capability Ele + * u8* len //store length of CE + * u8 IsEncrypt //whether encrypt, needed further + * output: none + * return: none + * notice: posHTCap can't be null and should be initialized before. + * *****************************************************************************************************************/ +void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt) +{ + PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; + PHT_CAPABILITY_ELE pCapELE = NULL; + //u8 bIsDeclareMCS13; + + if ((posHTCap == NULL) || (pHT == NULL)) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n"); + return; + } + memset(posHTCap, 0, *len); + if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) + { + u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); + pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]); + }else + { + pCapELE = (PHT_CAPABILITY_ELE)posHTCap; + } + + + //HT capability info + pCapELE->AdvCoding = 0; // This feature is not supported now!! + if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + { + pCapELE->ChlWidth = 0; + } + else + { + pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0); + } + +// pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0); + pCapELE->MimoPwrSave = pHT->SelfMimoPs; + pCapELE->GreenField = 0; // This feature is not supported now!! + pCapELE->ShortGI20Mhz = 1; // We can receive Short GI!! + pCapELE->ShortGI40Mhz = 1; // We can receive Short GI!! + //DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r", + //pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz); + pCapELE->TxSTBC = 1; + pCapELE->RxSTBC = 0; + pCapELE->DelayBA = 0; // Do not support now!! + pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0; + pCapELE->DssCCk = ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0); + pCapELE->PSMP = 0; // Do not support now!! + pCapELE->LSigTxopProtect = 0; // Do not support now!! + + + //MAC HT parameters info + // TODO: Nedd to take care of this part + IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); + + if( IsEncrypt) + { + pCapELE->MPDUDensity = 7; // 8us + pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K + } + else + { + pCapELE->MaxRxAMPDUFactor = 3; // 2 is for 32 K and 3 is 64K + pCapELE->MPDUDensity = 0; // no density + } + + //Supported MCS set + memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); + if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) + pCapELE->MCS[1] &= 0x7f; + + if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) + pCapELE->MCS[1] &= 0xbf; + + if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) + pCapELE->MCS[1] &= 0x00; + + // 2008.06.12 + // For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7. + if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + { + int i; + for(i = 1; i< 16; i++) + pCapELE->MCS[i] = 0; + } + + //Extended HT Capability Info + memset(&pCapELE->ExtHTCapInfo, 0, 2); + + + //TXBF Capabilities + memset(pCapELE->TxBFCap, 0, 4); + + //Antenna Selection Capabilities + pCapELE->ASCap = 0; +//add 2 to give space for element ID and len when construct frames + if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) + *len = 30 + 2; + else + *len = 26 + 2; + + + +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2); + + //Print each field in detail. Driver should not print out this message by default +// HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()"); + return; + +} +/******************************************************************************************************************** + *function: Construct Information Element in Beacon... if HTEnable is turned on + * input: struct ieee80211_device* ieee + * u8* posHTCap //pointer to store Information Ele + * u8* len //store len of + * u8 IsEncrypt //whether encrypt, needed further + * output: none + * return: none + * notice: posHTCap can't be null and be initialized before. only AP and IBSS sta should do this + * *****************************************************************************************************************/ +void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt) +{ + PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; + PHT_INFORMATION_ELE pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo; + if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n"); + return; + } + + memset(posHTInfo, 0, *len); + if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported + { + pHTInfoEle->ControlChl = ieee->current_network.channel; + pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT: + (ieee->current_network.channel<=6)? + HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER); + pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; + pHTInfoEle->RIFS = 0; + pHTInfoEle->PSMPAccessOnly = 0; + pHTInfoEle->SrvIntGranularity = 0; + pHTInfoEle->OptMode = pHT->CurrentOpMode; + pHTInfoEle->NonGFDevPresent = 0; + pHTInfoEle->DualBeacon = 0; + pHTInfoEle->SecondaryBeacon = 0; + pHTInfoEle->LSigTxopProtectFull = 0; + pHTInfoEle->PcoActive = 0; + pHTInfoEle->PcoPhase = 0; + + memset(pHTInfoEle->BasicMSC, 0, 16); + + + *len = 22 + 2; //same above + + } + else + { + //STA should not generate High Throughput Information Element + *len = 0; + } + //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2); + //HTDebugHTInfo(posHTInfo, "HTConstructInforElement"); + return; +} + +/* + * According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance + * if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2 + * (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set + * limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP + * will be much less than the traffic stream from AP to STA if both of the stream runs concurrently + * at the same time. + * + * Frame Format + * Element ID Length OUI Type1 Reserved + * 1 byte 1 byte 3 bytes 1 byte 1 byte + * + * OUI = 0x00, 0xe0, 0x4c, + * Type = 0x02 + * Reserved = 0x00 + * + * 2007.8.21 by Emily +*/ +/******************************************************************************************************************** + *function: Construct Information Element in Beacon... in RT2RT condition + * input: struct ieee80211_device* ieee + * u8* posRT2RTAgg //pointer to store Information Ele + * u8* len //store len + * output: none + * return: none + * notice: + * *****************************************************************************************************************/ +void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len) +{ + if (posRT2RTAgg == NULL) { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n"); + return; + } + memset(posRT2RTAgg, 0, *len); + *posRT2RTAgg++ = 0x00; + *posRT2RTAgg++ = 0xe0; + *posRT2RTAgg++ = 0x4c; + *posRT2RTAgg++ = 0x02; + *posRT2RTAgg++ = 0x01; + *posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02; + + if(ieee->bSupportRemoteWakeUp) { + *posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW; + } + + *len = 6 + 2; + return; +#ifdef TODO +#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE) + /* + //Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this + section of code. + if(IS_UNDER_11N_AES_MODE(Adapter)) + { + posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU; + }else + { + posRT2RTAgg->Octet[5] &= 0xfb; + } + */ + +#else + // Do Nothing +#endif + + posRT2RTAgg->Length = 6; +#endif + + + + +} + + +/******************************************************************************************************************** + *function: Pick the right Rate Adaptive table to use + * input: struct ieee80211_device* ieee + * u8* pOperateMCS //A pointer to MCS rate bitmap + * return: always we return true + * notice: + * *****************************************************************************************************************/ +u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS) +{ + u8 i; + if (pOperateMCS == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n"); + return false; + } + + switch(ieee->mode) + { + case IEEE_A: + case IEEE_B: + case IEEE_G: + //legacy rate routine handled at selectedrate + + //no MCS rate + for(i=0;i<=15;i++){ + pOperateMCS[i] = 0; + } + break; + + case IEEE_N_24G: //assume CCK rate ok + case IEEE_N_5G: + // Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G. + // Legacy part shall be handled at SelectRateSet(). + + //HT part + // TODO: may be different if we have different number of antenna + pOperateMCS[0] &=RATE_ADPT_1SS_MASK; //support MCS 0~7 + pOperateMCS[1] &=RATE_ADPT_2SS_MASK; + pOperateMCS[3] &=RATE_ADPT_MCS32_MASK; + break; + + //should never reach here + default: + + break; + + } + + return true; +} + +/* +* Description: +* This function will get the highest speed rate in input MCS set. +* +* /param Adapter Pionter to Adapter entity +* pMCSRateSet Pointer to MCS rate bitmap +* pMCSFilter Pointer to MCS rate filter +* +* /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter. +* +*/ +/******************************************************************************************************************** + *function: This function will get the highest speed rate in input MCS set. + * input: struct ieee80211_device* ieee + * u8* pMCSRateSet //Pointer to MCS rate bitmap + * u8* pMCSFilter //Pointer to MCS rate filter + * return: Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter + * notice: + * *****************************************************************************************************************/ +u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter) +{ + u8 i, j; + u8 bitMap; + u8 mcsRate = 0; + u8 availableMcsRate[16]; + if (pMCSRateSet == NULL || pMCSFilter == NULL) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n"); + return false; + } + for(i=0; i<16; i++) + availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; + + for(i = 0; i < 16; i++) + { + if(availableMcsRate[i] != 0) + break; + } + if(i == 16) + return false; + + for(i = 0; i < 16; i++) + { + if(availableMcsRate[i] != 0) + { + bitMap = availableMcsRate[i]; + for(j = 0; j < 8; j++) + { + if((bitMap%2) != 0) + { + if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate)) + mcsRate = (8*i+j); + } + bitMap = bitMap>>1; + } + } + } + return (mcsRate|0x80); +} + + + +/* +** +**1.Filter our operation rate set with AP's rate set +**2.shall reference channel bandwidth, STBC, Antenna number +**3.generate rate adative table for firmware +**David 20060906 +** +** \pHTSupportedCap: the connected STA's supported rate Capability element +*/ +u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS) +{ + + u8 i=0; + + // filter out operational rate set not supported by AP, the lenth of it is 16 + for(i=0;i<=15;i++){ + pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i]; + } + + + // TODO: adjust our operational rate set according to our channel bandwidth, STBC and Antenna number + + // TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet + // we also shall suggested the first start rate set according to our singal strength + HT_PickMCSRate(ieee, pOperateMCS); + + // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. + if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + pOperateMCS[1] = 0; + + // + // For RTL819X, we support only MCS0~15. + // And also, we do not know how to use MCS32 now. + // + for(i=2; i<=15; i++) + pOperateMCS[i] = 0; + + return true; +} +void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +#if 0 +//I need move this function to other places, such as rx? +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void HTOnAssocRsp_wq(struct work_struct *work) +{ + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ht_onAssRsp); +#else +void HTOnAssocRsp_wq(struct ieee80211_device *ieee) +{ +#endif +#endif +void HTOnAssocRsp(struct ieee80211_device *ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + PHT_CAPABILITY_ELE pPeerHTCap = NULL; + PHT_INFORMATION_ELE pPeerHTInfo = NULL; + u16 nMaxAMSDUSize = 0; + u8* pMcsFilter = NULL; + + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily + + if( pHTInfo->bCurrentHTSupport == false ) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n"); + return; + } + IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE)); +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE)); + +// HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq"); +// HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq"); + // + if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap))) + pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]); + else + pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf); + + if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]); + else + pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf); + + + //////////////////////////////////////////////////////// + // Configurations: + //////////////////////////////////////////////////////// + IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE)); +// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE)); + // Config Supported Channel Width setting + // + HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset)); + +// if(pHTInfo->bCurBW40MHz == true) + pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false); + + // + // Update short GI/ long GI setting + // + // TODO: + pHTInfo->bCurShortGI20MHz= + ((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false); + pHTInfo->bCurShortGI40MHz= + ((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false); + + // + // Config TX STBC setting + // + // TODO: + + // + // Config DSSS/CCK mode in 40MHz mode + // + // TODO: + pHTInfo->bCurSuppCCK = + ((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false); + + + // + // Config and configure A-MSDU setting + // + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + + nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935; + + if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize ) + pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; + else + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + + // + // Config A-MPDU setting + // + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + + // <1> Decide AMPDU Factor + + // By Emily + if(!pHTInfo->bRegRT2RTAggregation) + { + // Decide AMPDU Factor according to protocol handshake + if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) + pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + }else + { + // Set MPDU density to 2 to Realtek AP, and set it to 0 for others + // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily +#if 0 + osTmp= PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length >= 5) //00:e0:4c:02:00 +#endif + if (ieee->current_network.bssht.bdRT2RTAggregation) + { + if( ieee->pairwise_key_type != KEY_TYPE_NA) + // Realtek may set 32k in security mode and 64k for others + pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; + }else + { + if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) + pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; + } + } + + // <2> Set AMPDU Minimum MPDU Start Spacing + // 802.11n 3.0 section 9.7d.3 +#if 1 + if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + else + pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; + if(ieee->pairwise_key_type != KEY_TYPE_NA ) + pHTInfo->CurrentMPDUDensity = 7; // 8us +#else + if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + else + pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; +#endif + // Force TX AMSDU + + // Lanhsin: mark for tmp to avoid deauth by ap from s3 + //if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0) + if(0) + { + + pHTInfo->bCurrentAMPDUEnable = false; + pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; + pHTInfo->ForcedAMSDUMaxSize = 7935; + + pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K; + } + + // Rx Reorder Setting + pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; + + // + // Filter out unsupported HT rate for this AP + // Update RATR table + // This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism. + // + + // Handle Ralink AP bad MCS rate set condition. Joseph. + // This fix the bug of Ralink AP. This may be removed in the future. + if(pPeerHTCap->MCS[0] == 0) + pPeerHTCap->MCS[0] = 0xff; + + HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); + + // + // Config MIMO Power Save setting + // + pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; + if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC) + pMcsFilter = MCS_FILTER_1SS; + else + pMcsFilter = MCS_FILTER_ALL; + //WB add for MCS8 bug +// pMcsFilter = MCS_FILTER_1SS; + ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter); + ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; + + // + // Config current operation mode. + // + pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; + + + +} + +void HTSetConnectBwModeCallback(struct ieee80211_device* ieee); +/******************************************************************************************************************** + *function: initialize HT info(struct PRT_HIGH_THROUGHPUT) + * input: struct ieee80211_device* ieee + * output: none + * return: none + * notice: This function is called when * (1) MPInitialization Phase * (2) Receiving of Deauthentication from AP +********************************************************************************************************************/ +// TODO: Should this funciton be called when receiving of Disassociation? +void HTInitializeHTInfo(struct ieee80211_device* ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + // + // These parameters will be reset when receiving deauthentication packet + // + IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__); + pHTInfo->bCurrentHTSupport = false; + + // 40MHz channel support + pHTInfo->bCurBW40MHz = false; + pHTInfo->bCurTxBW40MHz = false; + + // Short GI support + pHTInfo->bCurShortGI20MHz = false; + pHTInfo->bCurShortGI40MHz = false; + pHTInfo->bForcedShortGI = false; + + // CCK rate support + // This flag is set to true to support CCK rate by default. + // It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to + // 11N BSS. + pHTInfo->bCurSuppCCK = true; + + // AMSDU related + pHTInfo->bCurrent_AMSDU_Support = false; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + // AMPUD related + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + + + // Initialize all of the parameters related to 11n + memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap)); + memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo)); + memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf)); + memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf)); + + pHTInfo->bSwBwInProgress = false; + pHTInfo->ChnlOp = CHNLOP_NONE; + + // Set default IEEE spec for Draft N + pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; + + // Realtek proprietary aggregation mode + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + pHTInfo->IOTPeer = 0; + pHTInfo->IOTAction = 0; + + //MCS rate initialized here + { + u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); + RegHTSuppRateSets[0] = 0xFF; //support MCS 0~7 + RegHTSuppRateSets[1] = 0xFF; //support MCS 8~15 + RegHTSuppRateSets[4] = 0x01; //support MCS 32 + } +} +/******************************************************************************************************************** + *function: initialize Bss HT structure(struct PBSS_HT) + * input: PBSS_HT pBssHT //to be initialized + * output: none + * return: none + * notice: This function is called when initialize network structure +********************************************************************************************************************/ +void HTInitializeBssDesc(PBSS_HT pBssHT) +{ + + pBssHT->bdSupportHT = false; + memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); + pBssHT->bdHTCapLen = 0; + memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); + pBssHT->bdHTInfoLen = 0; + + pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE; + + pBssHT->bdRT2RTAggregation = false; + pBssHT->bdRT2RTLongSlotTime = false; +} +#if 0 +//below function has merged into ieee80211_network_init() in ieee80211_rx.c +void +HTParsingHTCapElement( + IN PADAPTER Adapter, + IN OCTET_STRING HTCapIE, + OUT PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) ) + { + RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") ); + return; + } + + // TODO: Check the correctness of HT Cap + //Print each field in detail. Driver should not print out this message by default + if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc) + HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu8)"HTParsingHTCapElement()"); + + HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\ + sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length; //prevent from overflow + + CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length); + pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length; + +} + + +void +HTParsingHTInfoElement( + PADAPTER Adapter, + OCTET_STRING HTInfoIE, + PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)) + { + RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") ); + return; + } + + // TODO: Check the correctness of HT Info + //Print each field in detail. Driver should not print out this message by default + if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc) + HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu8)"HTParsingHTInfoElement()"); + + HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\ + sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length; //prevent from overflow + + CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length); + pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length; +} + +/* + * Get HT related information from beacon and save it in BssDesc + * + * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP + * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() + * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode). + * Input: + * PADAPTER Adapter + * + * Output: + * PRT_TCB BssDesc + * +*/ +void HTGetValueFromBeaconOrProbeRsp( + PADAPTER Adapter, + POCTET_STRING pSRCmmpdu, + PRT_WLAN_BSS bssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + OCTET_STRING HTCapIE, HTInfoIE, HTRealtekAgg, mmpdu; + OCTET_STRING BroadcomElement, CiscoElement; + + mmpdu.Octet = pSRCmmpdu->Octet; + mmpdu.Length = pSRCmmpdu->Length; + + //2Note: + // Mark for IOT testing using Linksys WRT350N, This AP does not contain WMM IE when + // it is configured at pure-N mode. + // if(bssDesc->BssQos.bdQoSMode & QOS_WMM) + // + + HTInitializeBssDesc (&bssDesc->BssHT); + + //2<1> Parse HTCap, and HTInfo + // Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE + HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(HTCapIE.Length == 0) + { + HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE); + if(HTCapIE.Length != 0) + bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC; + } + if(HTCapIE.Length != 0) + HTParsingHTCapElement(Adapter, HTCapIE, bssDesc); + + // Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE + HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(HTInfoIE.Length == 0) + { + HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE); + if(HTInfoIE.Length != 0) + bssDesc->BssHT.bdHTSpecVer = HT_SPEC_VER_EWC; + } + if(HTInfoIE.Length != 0) + HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc); + + //2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() + if(HTCapIE.Length != 0) + { + bssDesc->BssHT.bdSupportHT = true; + if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE) + QosSetLegacyWMMParamWithHT(Adapter, bssDesc); + } + else + { + bssDesc->BssHT.bdSupportHT = false; + } + + //2<3>Check whether the peer is Realtek AP/STA + if(pHTInfo->bRegRT2RTAggregation) + { + if(bssDesc->BssHT.bdSupportHT) + { + HTRealtekAgg = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE); + if(HTRealtekAgg.Length >=5 ) + { + bssDesc->BssHT.bdRT2RTAggregation = true; + + if((HTRealtekAgg.Octet[4]==1) && (HTRealtekAgg.Octet[5] & 0x02)) + bssDesc->BssHT.bdRT2RTLongSlotTime = true; + } + } + } + + // + // 2008/01/25 MH Get Broadcom AP IE for manamgent frame CCK rate problem. + // AP can not receive CCK managemtn from from 92E. + // + + // Initialize every new bss broadcom cap exist as false.. + bssDesc->bBroadcomCapExist= false; + + if(HTCapIE.Length != 0 || HTInfoIE.Length != 0) + { + u4Byte Length = 0; + + FillOctetString(BroadcomElement, NULL, 0); + + BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_1, OUI_SUBTYPE_DONT_CARE); + Length += BroadcomElement.Length; + BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_2, OUI_SUBTYPE_DONT_CARE); + Length += BroadcomElement.Length; + BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_3, OUI_SUBTYPE_DONT_CARE); + Length += BroadcomElement.Length; + + if(Length > 0) + bssDesc->bBroadcomCapExist = true; + } + + + // For Cisco IOT issue + CiscoElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_CISCO_IE, OUI_SUBTYPE_DONT_CARE); + if(CiscoElement.Length != 0){ // 3: 0x00, 0x40, 0x96 .... + bssDesc->bCiscoCapExist = true; + }else{ + bssDesc->bCiscoCapExist = false; + } +} + + +#endif +/******************************************************************************************************************** + *function: initialize Bss HT structure(struct PBSS_HT) + * input: struct ieee80211_device *ieee + * struct ieee80211_network *pNetwork //usually current network we are live in + * output: none + * return: none + * notice: This function should ONLY be called before association +********************************************************************************************************************/ +void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; +// u16 nMaxAMSDUSize; +// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf; +// PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; +// u8* pMcsFilter; + u8 bIOTAction = 0; + + // + // Save Peer Setting before Association + // + IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__); + /*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/ +// if( pHTInfo->bEnableHT && pNetwork->bssht.bdSupportHT) + if (pNetwork->bssht.bdSupportHT) + { + pHTInfo->bCurrentHTSupport = true; + pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; + + // Save HTCap and HTInfo information Element + if(pNetwork->bssht.bdHTCapLen > 0 && pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) + memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen); + + if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf)) + memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen); + + // Check whether RT to RT aggregation mode is enabled + if(pHTInfo->bRegRT2RTAggregation) + { + pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation; + pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime; + } + else + { + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + } + + // Determine the IOT Peer Vendor. + HTIOTPeerDetermine(ieee); + + // Decide IOT Action + // Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided + pHTInfo->IOTAction = 0; + bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; + + bIOTAction = HTIOTActIsDisableMCS15(ieee); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; + + bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; + + + bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; + + bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; + + bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid); + if(bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; + + + } + else + { + pHTInfo->bCurrentHTSupport = false; + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + + pHTInfo->IOTAction = 0; + } + +} + +void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; +// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf; + PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; + + if(pHTInfo->bCurrentHTSupport) + { + // + // Config current operation mode. + // + if(pNetwork->bssht.bdHTInfoLen != 0) + pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; + + // + // + // + } +} + +void HTUseDefaultSetting(struct ieee80211_device* ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; +// u8 regBwOpMode; + + if(pHTInfo->bEnableHT) + { + pHTInfo->bCurrentHTSupport = true; + + pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; + + pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; + + pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz; + + pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz; + + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; + + // Set BWOpMode register + + //update RATR index0 + HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet); + //function below is not implemented at all. WB +#ifdef TODO + Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet); +#endif + ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL); + ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; + + } + else + { + pHTInfo->bCurrentHTSupport = false; + } + return; +} +/******************************************************************************************************************** + *function: check whether HT control field exists + * input: struct ieee80211_device *ieee + * u8* pFrame //coming skb->data + * output: none + * return: return true if HT control field exists(false otherwise) + * notice: +********************************************************************************************************************/ +u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame) +{ + if(ieee->pHTInfo->bCurrentHTSupport) + { + if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) + { + IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n"); + return true; + } + } + return false; +} + +// +// This function set bandwidth mode in protocol layer. +// +void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; +// u32 flags = 0; + + if(pHTInfo->bRegBW40MHz == false) + return; + + + + // To reduce dummy operation +// if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) || +// (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset)) +// return; + +// spin_lock_irqsave(&(ieee->bw_spinlock), flags); + if(pHTInfo->bSwBwInProgress) { +// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); + return; + } + //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. + if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))) + { + // Handle Illegal extention channel offset!! + if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER) + Offset = HT_EXTCHNL_OFFSET_NO_EXT; + if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) { + pHTInfo->bCurBW40MHz = true; + pHTInfo->CurSTAExtChnlOffset = Offset; + } else { + pHTInfo->bCurBW40MHz = false; + pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + } + } else { + pHTInfo->bCurBW40MHz = false; + pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + } + + pHTInfo->bSwBwInProgress = true; + + // TODO: 2007.7.13 by Emily Wait 2000ms in order to garantee that switching + // bandwidth is executed after scan is finished. It is a temporal solution + // because software should ganrantee the last operation of switching bandwidth + // is executed properlly. + HTSetConnectBwModeCallback(ieee); + +// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); +} + +void HTSetConnectBwModeCallback(struct ieee80211_device* ieee) +{ + PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; + + IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__); + + if(pHTInfo->bCurBW40MHz) + { + if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER) + ieee->set_chan(ieee->dev, ieee->current_network.channel+2); + else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER) + ieee->set_chan(ieee->dev, ieee->current_network.channel-2); + else + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); + } else { + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + } + + pHTInfo->bSwBwInProgress = false; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +//EXPORT_SYMBOL_NOVERS(HTUpdateSelfAndPeerSetting); +#else +//EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h new file mode 100644 index 00000000000..f7b882b99d1 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h @@ -0,0 +1,749 @@ +#ifndef __INC_QOS_TYPE_H +#define __INC_QOS_TYPE_H + +//#include "EndianFree.h" +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#define MAX_WMMELE_LENGTH 64 + +// +// QoS mode. +// enum 0, 1, 2, 4: since we can use the OR(|) operation. +// +// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko. +//typedef enum _QOS_MODE{ +// QOS_DISABLE = 0, +// QOS_WMM = 1, +// QOS_EDCA = 2, +// QOS_HCCA = 4, +//}QOS_MODE,*PQOS_MODE; +// +typedef u32 QOS_MODE, *PQOS_MODE; +#define QOS_DISABLE 0 +#define QOS_WMM 1 +#define QOS_WMMSA 2 +#define QOS_EDCA 4 +#define QOS_HCCA 8 +#define QOS_WMM_UAPSD 16 //WMM Power Save, 2006-06-14 Isaiah + +#define AC_PARAM_SIZE 4 +#define WMM_PARAM_ELE_BODY_LEN 18 + +// +// QoS ACK Policy Field Values +// Ref: WMM spec 2.1.6: QoS Control Field, p.10. +// +typedef enum _ACK_POLICY{ + eAckPlc0_ACK = 0x00, + eAckPlc1_NoACK = 0x01, +}ACK_POLICY,*PACK_POLICY; + +#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE)) +#if 0 +#define GET_QOS_CTRL(_pStart) ReadEF2Byte((u8 *)(_pStart) + 24) +#define SET_QOS_CTRL(_pStart, _value) WriteEF2Byte((u8 *)(_pStart) + 24, _value) + +// WMM control field. +#define GET_QOS_CTRL_WMM_UP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 3)) +#define SET_QOS_CTRL_WMM_UP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 3, (u8)(_value)) + +#define GET_QOS_CTRL_WMM_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) +#define SET_QOS_CTRL_WMM_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) + +#define GET_QOS_CTRL_WMM_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) +#define SET_QOS_CTRL_WMM_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) + +// 802.11e control field (by STA, data) +#define GET_QOS_CTRL_STA_DATA_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) +#define SET_QOS_CTRL_STA_DATA_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) + +#define GET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) +#define SET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) + +#define GET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) +#define SET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) + +#define GET_QOS_CTRL_STA_DATA_TXOP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) +#define SET_QOS_CTRL_STA_DATA_TXOP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) + +#define GET_QOS_CTRL_STA_DATA_QSIZE(_pStart) GET_QOS_CTRL_STA_DATA_TXOP(_pStart) +#define SET_QOS_CTRL_STA_DATA_QSIZE(_pStart, _value) SET_QOS_CTRL_STA_DATA_TXOP(_pStart) + +// 802.11e control field (by HC, data) +#define GET_QOS_CTRL_HC_DATA_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) +#define SET_QOS_CTRL_HC_DATA_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) + +#define GET_QOS_CTRL_HC_DATA_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) +#define SET_QOS_CTRL_HC_DATA_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) + +#define GET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) +#define SET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) + +#define GET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) +#define SET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) + +// 802.11e control field (by HC, CFP) +#define GET_QOS_CTRL_HC_CFP_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) +#define SET_QOS_CTRL_HC_CFP_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) + +#define GET_QOS_CTRL_HC_CFP_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) +#define SET_QOS_CTRL_HC_CFP_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) + +#define GET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) +#define SET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) + +#define GET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) +#define SET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) + +#define SET_WMM_QOS_INFO_FIELD(_pStart, _val) WriteEF1Byte(_pStart, _val) + +#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 4) +#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val) + +#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 7, 1) +#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 1, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 2, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 3, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart) LE_BITS_TO_1BYTE(_pStart, 5, 2) +#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val) + + +#define WMM_INFO_ELEMENT_SIZE 7 + +#define GET_WMM_INFO_ELE_OUI(_pStart) ((u8 *)(_pStart)) +#define SET_WMM_INFO_ELE_OUI(_pStart, _pVal) PlatformMoveMemory(_pStart, _pVal, 3); + +#define GET_WMM_INFO_ELE_OUI_TYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+3) ) ) +#define SET_WMM_INFO_ELE_OUI_TYPE(_pStart, _val) ( *((u8 *)(_pStart)+3) = EF1Byte(_val) ) + +#define GET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+4) ) ) +#define SET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart, _val) ( *((u8 *)(_pStart)+4) = EF1Byte(_val) ) + +#define GET_WMM_INFO_ELE_VERSION(_pStart) ( EF1Byte( *((u8 *)(_pStart)+5) ) ) +#define SET_WMM_INFO_ELE_VERSION(_pStart, _val) ( *((u8 *)(_pStart)+5) = EF1Byte(_val) ) + +#define GET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart) ( EF1Byte( *((u8 *)(_pStart)+6) ) ) +#define SET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart, _val) ( *((u8 *)(_pStart)+6) = EF1Byte(_val) ) + + + +#define GET_WMM_AC_PARAM_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) ) +#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val) + +#define GET_WMM_AC_PARAM_ACM(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) ) +#define SET_WMM_AC_PARAM_ACM(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val) + +#define GET_WMM_AC_PARAM_ACI(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) ) +#define SET_WMM_AC_PARAM_ACI(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val) + +#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) ) +#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val) SET_BTIS_TO_LE_4BYTE(_pStart, 0, 8, _val) + +#define GET_WMM_AC_PARAM_ECWMIN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) ) +#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val) + +#define GET_WMM_AC_PARAM_ECWMAX(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) ) +#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val) + +#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart) ( (u16)LE_BITS_TO_4BYTE(_pStart, 16, 16) ) +#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val) + + + + +#define GET_WMM_PARAM_ELE_OUI(_pStart) ((u8 *)(_pStart)) +#define SET_WMM_PARAM_ELE_OUI(_pStart, _pVal) PlatformMoveMemory(_pStart, _pVal, 3) + +#define GET_WMM_PARAM_ELE_OUI_TYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+3) ) ) +#define SET_WMM_PARAM_ELE_OUI_TYPE(_pStart, _val) ( *((u8 *)(_pStart)+3) = EF1Byte(_val) ) + +#define GET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+4) ) ) +#define SET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart, _val) ( *((u8 *)(_pStart)+4) = EF1Byte(_val) ) + +#define GET_WMM_PARAM_ELE_VERSION(_pStart) ( EF1Byte( *((u8 *)(_pStart)+5) ) ) +#define SET_WMM_PARAM_ELE_VERSION(_pStart, _val) ( *((u8 *)(_pStart)+5) = EF1Byte(_val) ) + +#define GET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart) ( EF1Byte( *((u8 *)(_pStart)+6) ) ) +#define SET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart, _val) ( *((u8 *)(_pStart)+6) = EF1Byte(_val) ) + +#define GET_WMM_PARAM_ELE_AC_PARAM(_pStart) ( (u8 *)(_pStart)+8 ) +#define SET_WMM_PARAM_ELE_AC_PARAM(_pStart, _pVal) PlatformMoveMemory((_pStart)+8, _pVal, 16) +#endif + +// +// QoS Control Field +// Ref: +// 1. WMM spec 2.1.6: QoS Control Field, p.9. +// 2. 802.11e/D13.0 7.1.3.5, p.26. +// +typedef union _QOS_CTRL_FIELD{ + u8 charData[2]; + u16 shortData; + + // WMM spec + struct + { + u8 UP:3; + u8 usRsvd1:1; + u8 EOSP:1; + u8 AckPolicy:2; + u8 usRsvd2:1; + u8 ucRsvdByte; + }WMM; + + // 802.11e: QoS data type frame sent by non-AP QSTAs. + struct + { + u8 TID:4; + u8 bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size. + u8 AckPolicy:2; + u8 usRsvd:1; + u8 TxopOrQsize; // (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size. + }BySta; + + // 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC. + struct + { + u8 TID:4; + u8 EOSP:1; + u8 AckPolicy:2; + u8 usRsvd:1; + u8 PSBufState; // QAP PS Buffer State. + }ByHc_Data; + + // 802.11e: QoS (+) CF-Poll frames sent by HC. + struct + { + u8 TID:4; + u8 EOSP:1; + u8 AckPolicy:2; + u8 usRsvd:1; + u8 TxopLimit; // TXOP Limit. + }ByHc_CFP; + +}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD; + + +// +// QoS Info Field +// Ref: +// 1. WMM spec 2.2.1: WME Information Element, p.11. +// 2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h] +// +typedef union _QOS_INFO_FIELD{ + u8 charData; + + struct + { + u8 ucParameterSetCount:4; + u8 ucReserved:4; + }WMM; + + struct + { + //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah + u8 ucAC_VO_UAPSD:1; + u8 ucAC_VI_UAPSD:1; + u8 ucAC_BE_UAPSD:1; + u8 ucAC_BK_UAPSD:1; + u8 ucReserved1:1; + u8 ucMaxSPLen:2; + u8 ucReserved2:1; + + }ByWmmPsSta; + + struct + { + //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah + u8 ucParameterSetCount:4; + u8 ucReserved:3; + u8 ucApUapsd:1; + }ByWmmPsAp; + + struct + { + u8 ucAC3_UAPSD:1; + u8 ucAC2_UAPSD:1; + u8 ucAC1_UAPSD:1; + u8 ucAC0_UAPSD:1; + u8 ucQAck:1; + u8 ucMaxSPLen:2; + u8 ucMoreDataAck:1; + } By11eSta; + + struct + { + u8 ucParameterSetCount:4; + u8 ucQAck:1; + u8 ucQueueReq:1; + u8 ucTXOPReq:1; + u8 ucReserved:1; + } By11eAp; + + struct + { + u8 ucReserved1:4; + u8 ucQAck:1; + u8 ucReserved2:2; + u8 ucMoreDataAck:1; + } ByWmmsaSta; + + struct + { + u8 ucReserved1:4; + u8 ucQAck:1; + u8 ucQueueReq:1; + u8 ucTXOPReq:1; + u8 ucReserved2:1; + } ByWmmsaAp; + + struct + { + u8 ucAC3_UAPSD:1; + u8 ucAC2_UAPSD:1; + u8 ucAC1_UAPSD:1; + u8 ucAC0_UAPSD:1; + u8 ucQAck:1; + u8 ucMaxSPLen:2; + u8 ucMoreDataAck:1; + } ByAllSta; + + struct + { + u8 ucParameterSetCount:4; + u8 ucQAck:1; + u8 ucQueueReq:1; + u8 ucTXOPReq:1; + u8 ucApUapsd:1; + } ByAllAp; + +}QOS_INFO_FIELD, *PQOS_INFO_FIELD; + +#if 0 +// +// WMM Information Element +// Ref: WMM spec 2.2.1: WME Information Element, p.10. +// +typedef struct _WMM_INFO_ELEMENT{ +// u8 ElementID; +// u8 Length; + u8 OUI[3]; + u8 OUI_Type; + u8 OUI_SubType; + u8 Version; + QOS_INFO_FIELD QosInfo; +}WMM_INFO_ELEMENT, *PWMM_INFO_ELEMENT; +#endif + +// +// ACI to AC coding. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. +// +// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko. +//typedef enum _AC_CODING{ +// AC0_BE = 0, // ACI: 0x00 // Best Effort +// AC1_BK = 1, // ACI: 0x01 // Background +// AC2_VI = 2, // ACI: 0x10 // Video +// AC3_VO = 3, // ACI: 0x11 // Voice +// AC_MAX = 4, // Max: define total number; Should not to be used as a real enum. +//}AC_CODING,*PAC_CODING; +// +typedef u32 AC_CODING; +#define AC0_BE 0 // ACI: 0x00 // Best Effort +#define AC1_BK 1 // ACI: 0x01 // Background +#define AC2_VI 2 // ACI: 0x10 // Video +#define AC3_VO 3 // ACI: 0x11 // Voice +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum. + +// +// ACI/AIFSN Field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _ACI_AIFSN{ + u8 charData; + + struct + { + u8 AIFSN:4; + u8 ACM:1; + u8 ACI:2; + u8 Reserved:1; + }f; // Field +}ACI_AIFSN, *PACI_AIFSN; + +// +// ECWmin/ECWmax field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. +// +typedef union _ECW{ + u8 charData; + struct + { + u8 ECWmin:4; + u8 ECWmax:4; + }f; // Field +}ECW, *PECW; + +// +// AC Parameters Record Format. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _AC_PARAM{ + u32 longData; + u8 charData[4]; + + struct + { + ACI_AIFSN AciAifsn; + ECW Ecw; + u16 TXOPLimit; + }f; // Field +}AC_PARAM, *PAC_PARAM; + + + +// +// QoS element subtype +// +typedef enum _QOS_ELE_SUBTYPE{ + QOSELE_TYPE_INFO = 0x00, // 0x00: Information element + QOSELE_TYPE_PARAM = 0x01, // 0x01: parameter element +}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE; + + +// +// Direction Field Values. +// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18. +// +typedef enum _DIRECTION_VALUE{ + DIR_UP = 0, // 0x00 // UpLink + DIR_DOWN = 1, // 0x01 // DownLink + DIR_DIRECT = 2, // 0x10 // DirectLink + DIR_BI_DIR = 3, // 0x11 // Bi-Direction +}DIRECTION_VALUE,*PDIRECTION_VALUE; + + +// +// TS Info field in WMM TSPEC Element. +// Ref: +// 1. WMM spec 2.2.11: WME TSPEC Element, p.18. +// 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h] +// +typedef union _QOS_TSINFO{ + u8 charData[3]; + struct { + u8 ucTrafficType:1; //WMM is reserved + u8 ucTSID:4; + u8 ucDirection:2; + u8 ucAccessPolicy:2; //WMM: bit8=0, bit7=1 + u8 ucAggregation:1; //WMM is reserved + u8 ucPSB:1; //WMMSA is APSD + u8 ucUP:3; + u8 ucTSInfoAckPolicy:2; //WMM is reserved + u8 ucSchedule:1; //WMM is reserved + u8 ucReserved:7; + }field; +}QOS_TSINFO, *PQOS_TSINFO; + +// +// WMM TSPEC Body. +// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16. +// +typedef union _TSPEC_BODY{ + u8 charData[55]; + + struct + { + QOS_TSINFO TSInfo; //u8 TSInfo[3]; + u16 NominalMSDUsize; + u16 MaxMSDUsize; + u32 MinServiceItv; + u32 MaxServiceItv; + u32 InactivityItv; + u32 SuspenItv; + u32 ServiceStartTime; + u32 MinDataRate; + u32 MeanDataRate; + u32 PeakDataRate; + u32 MaxBurstSize; + u32 DelayBound; + u32 MinPhyRate; + u16 SurplusBandwidthAllowance; + u16 MediumTime; + } f; // Field +}TSPEC_BODY, *PTSPEC_BODY; + + +// +// WMM TSPEC Element. +// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16. +// +typedef struct _WMM_TSPEC{ + u8 ID; + u8 Length; + u8 OUI[3]; + u8 OUI_Type; + u8 OUI_SubType; + u8 Version; + TSPEC_BODY Body; +} WMM_TSPEC, *PWMM_TSPEC; + +// +// ACM implementation method. +// Annie, 2005-12-13. +// +typedef enum _ACM_METHOD{ + eAcmWay0_SwAndHw = 0, // By SW and HW. + eAcmWay1_HW = 1, // By HW. + eAcmWay2_SW = 2, // By SW. +}ACM_METHOD,*PACM_METHOD; + + +typedef struct _ACM{ +// u8 RegEnableACM; + u64 UsedTime; + u64 MediumTime; + u8 HwAcmCtl; // TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B). +}ACM, *PACM; + +typedef u8 AC_UAPSD, *PAC_UAPSD; + +#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0) +#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0) + +#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1) +#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1) + +#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2) +#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2) + +#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3) +#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3) + + +//typedef struct _TCLASS{ +// TODO +//} TCLASS, *PTCLASS; +typedef union _QOS_TCLAS{ + + struct _TYPE_GENERAL{ + u8 Priority; + u8 ClassifierType; + u8 Mask; + } TYPE_GENERAL; + + struct _TYPE0_ETH{ + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 SrcAddr[6]; + u8 DstAddr[6]; + u16 Type; + } TYPE0_ETH; + + struct _TYPE1_IPV4{ + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 Version; + u8 SrcIP[4]; + u8 DstIP[4]; + u16 SrcPort; + u16 DstPort; + u8 DSCP; + u8 Protocol; + u8 Reserved; + } TYPE1_IPV4; + + struct _TYPE1_IPV6{ + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 Version; + u8 SrcIP[16]; + u8 DstIP[16]; + u16 SrcPort; + u16 DstPort; + u8 FlowLabel[3]; + } TYPE1_IPV6; + + struct _TYPE2_8021Q{ + u8 Priority; + u8 ClassifierType; + u8 Mask; + u16 TagType; + } TYPE2_8021Q; +} QOS_TCLAS, *PQOS_TCLAS; + +//typedef struct _WMM_TSTREAM{ +// +//- TSPEC +//- AC (which to mapping) +//} WMM_TSTREAM, *PWMM_TSTREAM; +typedef struct _QOS_TSTREAM{ + u8 AC; + WMM_TSPEC TSpec; + QOS_TCLAS TClass; +} QOS_TSTREAM, *PQOS_TSTREAM; + +//typedef struct _U_APSD{ +//- TriggerEnable [4] +//- MaxSPLength +//- HighestAcBuffered +//} U_APSD, *PU_APSD; + +//joseph TODO: +// UAPSD function should be implemented by 2 data structure +// "Qos control field" and "Qos info field" +//typedef struct _QOS_UAPSD{ +// u8 bTriggerEnable[4]; +// u8 MaxSPLength; +// u8 HighestBufAC; +//} QOS_UAPSD, *PQOS_APSD; + +//---------------------------------------------------------------------------- +// 802.11 Management frame Status Code field +//---------------------------------------------------------------------------- +typedef struct _OCTET_STRING{ + u8 *Octet; + u16 Length; +}OCTET_STRING, *POCTET_STRING; +#if 0 +#define FillOctetString(_os,_octet,_len) \ + (_os).Octet=(u8 *)(_octet); \ + (_os).Length=(_len); + +#define WMM_ELEM_HDR_LEN 6 +#define WMMElemSkipHdr(_osWMMElem) \ + (_osWMMElem).Octet += WMM_ELEM_HDR_LEN; \ + (_osWMMElem).Length -= WMM_ELEM_HDR_LEN; +#endif +// +// STA QoS data. +// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h] +// +typedef struct _STA_QOS{ + //DECLARE_RT_OBJECT(STA_QOS); + u8 WMMIEBuf[MAX_WMMELE_LENGTH]; + u8* WMMIE; + + // Part 1. Self QoS Mode. + QOS_MODE QosCapability; //QoS Capability, 2006-06-14 Isaiah + QOS_MODE CurrentQosMode; + + // For WMM Power Save Mode : + // ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah + AC_UAPSD b4ac_Uapsd; //VoUapsd(bit0), ViUapsd(bit1), BkUapsd(bit2), BeUapsd(bit3), + AC_UAPSD Curr4acUapsd; + u8 bInServicePeriod; + u8 MaxSPLength; + int NumBcnBeforeTrigger; + + // Part 2. EDCA Parameter (perAC) + u8 * pWMMInfoEle; + u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE]; + u8 WMMPELength; + + // + //2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element. + // By Bruce, 2008-01-30. + // Part 2. EDCA Parameter (perAC) + QOS_INFO_FIELD QosInfoField_STA; // Maintained by STA + QOS_INFO_FIELD QosInfoField_AP; // Retrieved from AP + + AC_PARAM CurAcParameters[4]; + + // Part 3. ACM + ACM acm[4]; + ACM_METHOD AcmMethod; + + // Part 4. Per TID (Part 5: TCLASS will be described by TStream) + QOS_TSTREAM TStream[16]; + WMM_TSPEC TSpec; + + u32 QBssWirelessMode; + + // No Ack Setting + u8 bNoAck; + + // Enable/Disable Rx immediate BA capability. + u8 bEnableRxImmBA; + +}STA_QOS, *PSTA_QOS; + +// +// BSS QOS data. +// Ref: BssDscr in 8185 code. [def. in BssDscr.h] +// +typedef struct _BSS_QOS{ + QOS_MODE bdQoSMode; + + u8 bdWMMIEBuf[MAX_WMMELE_LENGTH]; + u8* bdWMMIE; + + QOS_ELE_SUBTYPE EleSubType; + + u8 * pWMMInfoEle; + u8 * pWMMParamEle; + + QOS_INFO_FIELD QosInfoField; + AC_PARAM AcParameter[4]; +}BSS_QOS, *PBSS_QOS; + + +// +// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code. +//#define QoSCtl (( (Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA)) ) ?sQoSCtlLng:0) +// +#define sQoSCtlLng 2 +#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0) + + +//Added by joseph +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP +//#define UP2AC(up) ((up<3)?((up==0)?1:0):(up>>1)) +#define IsACValid(ac) ((ac<=7 )?true:false ) + +#endif // #ifndef __INC_QOS_TYPE_H diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h new file mode 100644 index 00000000000..baaac2149de --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h @@ -0,0 +1,56 @@ +#ifndef _TSTYPE_H_ +#define _TSTYPE_H_ +#include "rtl819x_Qos.h" +#define TS_SETUP_TIMEOUT 60 // In millisecond +#define TS_INACT_TIMEOUT 60 +#define TS_ADDBA_DELAY 60 + +#define TOTAL_TS_NUM 16 +#define TCLAS_NUM 4 + +// This define the Tx/Rx directions +typedef enum _TR_SELECT { + TX_DIR = 0, + RX_DIR = 1, +} TR_SELECT, *PTR_SELECT; + +typedef struct _TS_COMMON_INFO{ + struct list_head List; + struct timer_list SetupTimer; + struct timer_list InactTimer; + u8 Addr[6]; + TSPEC_BODY TSpec; + QOS_TCLAS TClass[TCLAS_NUM]; + u8 TClasProc; + u8 TClasNum; +} TS_COMMON_INFO, *PTS_COMMON_INFO; + +typedef struct _TX_TS_RECORD{ + TS_COMMON_INFO TsCommonInfo; + u16 TxCurSeq; + BA_RECORD TxPendingBARecord; // For BA Originator + BA_RECORD TxAdmittedBARecord; // For BA Originator +// QOS_DL_RECORD DLRecord; + u8 bAddBaReqInProgress; + u8 bAddBaReqDelayed; + u8 bUsingBa; + struct timer_list TsAddBaTimer; + u8 num; +} TX_TS_RECORD, *PTX_TS_RECORD; + +typedef struct _RX_TS_RECORD { + TS_COMMON_INFO TsCommonInfo; + u16 RxIndicateSeq; + u16 RxTimeoutIndicateSeq; + struct list_head RxPendingPktList; + struct timer_list RxPktPendingTimer; + BA_RECORD RxAdmittedBARecord; // For BA Recepient + u16 RxLastSeqNum; + u8 RxLastFragNum; + u8 num; +// QOS_DL_RECORD DLRecord; +} RX_TS_RECORD, *PRX_TS_RECORD; + + +#endif + diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c new file mode 100644 index 00000000000..2816b60a08a --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -0,0 +1,659 @@ +#include "ieee80211.h" +#include +#include "rtl819x_TS.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) +#endif +void TsSetupTimeOut(unsigned long data) +{ + // Not implement yet + // This is used for WMMSA and ACM , that would send ADDTSReq frame. +} + +void TsInactTimeout(unsigned long data) +{ + // Not implement yet + // This is used for WMMSA and ACM. + // This function would be call when TS is no Tx/Rx for some period of time. +} + +/******************************************************************************************************************** + *function: I still not understand this function, so wait for further implementation + * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer + * return: NULL + * notice: +********************************************************************************************************************/ +#if 1 +void RxPktPendingTimeout(unsigned long data) +{ + PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; + struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); + + PRX_REORDER_ENTRY pReorderEntry = NULL; + + //u32 flags = 0; + unsigned long flags = 0; + struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; + u8 index = 0; + bool bPktInBuf = false; + + + spin_lock_irqsave(&(ieee->reorder_spinlock), flags); + //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK); + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__); + if(pRxTs->RxTimeoutIndicateSeq != 0xffff) + { + // Indicate the pending packets sequentially according to SeqNum until meet the gap. + while(!list_empty(&pRxTs->RxPendingPktList)) + { + pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List); + if(index == 0) + pRxTs->RxIndicateSeq = pReorderEntry->SeqNum; + + if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ) + { + list_del_init(&pReorderEntry->List); + + if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)) + pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096; + + IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum); + stats_IndicateArray[index] = pReorderEntry->prxb; + index++; + + list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); + } + else + { + bPktInBuf = true; + break; + } + } + } + + if(index>0) + { + // Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now. + pRxTs->RxTimeoutIndicateSeq = 0xffff; + + // Indicate packets + if(index > REORDER_WIN_SIZE){ + IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); + return; + } + ieee80211_indicate_packets(ieee, stats_IndicateArray, index); + bPktInBuf = false; + } + + if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) + { + pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; +#if 0 + if(timer_pending(&pRxTs->RxPktPendingTimer)) + del_timer_sync(&pRxTs->RxPktPendingTimer); + pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime; + add_timer(&pRxTs->RxPktPendingTimer); +#else + mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime)); +#endif + } + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); + //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); +} +#endif + +/******************************************************************************************************************** + *function: Add BA timer function + * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer + * return: NULL + * notice: +********************************************************************************************************************/ +void TsAddBaProcess(unsigned long data) +{ + PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; + u8 num = pTxTs->num; + struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]); + + TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); + IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n"); +} + + +void ResetTsCommonInfo(PTS_COMMON_INFO pTsCommonInfo) +{ + memset(pTsCommonInfo->Addr, 0, 6); + memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY)); + memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM); + pTsCommonInfo->TClasProc = 0; + pTsCommonInfo->TClasNum = 0; +} + +void ResetTxTsEntry(PTX_TS_RECORD pTS) +{ + ResetTsCommonInfo(&pTS->TsCommonInfo); + pTS->TxCurSeq = 0; + pTS->bAddBaReqInProgress = false; + pTS->bAddBaReqDelayed = false; + pTS->bUsingBa = false; + ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator + ResetBaEntry(&pTS->TxPendingBARecord); +} + +void ResetRxTsEntry(PRX_TS_RECORD pTS) +{ + ResetTsCommonInfo(&pTS->TsCommonInfo); + pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!! + pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!! + ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recepient +} + +void TSInitialize(struct ieee80211_device *ieee) +{ + PTX_TS_RECORD pTxTS = ieee->TxTsRecord; + PRX_TS_RECORD pRxTS = ieee->RxTsRecord; + PRX_REORDER_ENTRY pRxReorderEntry = ieee->RxReorderEntry; + u8 count = 0; + IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__); + // Initialize Tx TS related info. + INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); + INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); + INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); + + for(count = 0; count < TOTAL_TS_NUM; count++) + { + // + pTxTS->num = count; + // The timers for the operation of Traffic Stream and Block Ack. + // DLS related timer will be add here in the future!! + init_timer(&pTxTS->TsCommonInfo.SetupTimer); + pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS; + pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut; + + init_timer(&pTxTS->TsCommonInfo.InactTimer); + pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS; + pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout; + + init_timer(&pTxTS->TsAddBaTimer); + pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS; + pTxTS->TsAddBaTimer.function = TsAddBaProcess; + + init_timer(&pTxTS->TxPendingBARecord.Timer); + pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS; + pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut; + + init_timer(&pTxTS->TxAdmittedBARecord.Timer); + pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS; + pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout; + + ResetTxTsEntry(pTxTS); + list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List); + pTxTS++; + } + + // Initialize Rx TS related info. + INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); + INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); + INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); + for(count = 0; count < TOTAL_TS_NUM; count++) + { + pRxTS->num = count; + INIT_LIST_HEAD(&pRxTS->RxPendingPktList); + + init_timer(&pRxTS->TsCommonInfo.SetupTimer); + pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS; + pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut; + + init_timer(&pRxTS->TsCommonInfo.InactTimer); + pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS; + pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout; + + init_timer(&pRxTS->RxAdmittedBARecord.Timer); + pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS; + pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout; + + init_timer(&pRxTS->RxPktPendingTimer); + pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS; + pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout; + + ResetRxTsEntry(pRxTS); + list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List); + pRxTS++; + } + // Initialize unused Rx Reorder List. + INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); +//#ifdef TO_DO_LIST + for(count = 0; count < REORDER_ENTRY_NUM; count++) + { + list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List); + if(count == (REORDER_ENTRY_NUM-1)) + break; + pRxReorderEntry = &ieee->RxReorderEntry[count+1]; + } +//#endif + +} + +void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime) +{ + del_timer_sync(&pTsCommonInfo->SetupTimer); + del_timer_sync(&pTsCommonInfo->InactTimer); + + if(InactTime!=0) + mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime)); +} + + +PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect) +{ + //DIRECTION_VALUE dir; + u8 dir; + bool search_dir[4] = {0, 0, 0, 0}; + struct list_head* psearch_list; //FIXME + PTS_COMMON_INFO pRet = NULL; + if(ieee->iw_mode == IW_MODE_MASTER) //ap mode + { + if(TxRxSelect == TX_DIR) + { + search_dir[DIR_DOWN] = true; + search_dir[DIR_BI_DIR]= true; + } + else + { + search_dir[DIR_UP] = true; + search_dir[DIR_BI_DIR]= true; + } + } + else if(ieee->iw_mode == IW_MODE_ADHOC) + { + if(TxRxSelect == TX_DIR) + search_dir[DIR_UP] = true; + else + search_dir[DIR_DOWN] = true; + } + else + { + if(TxRxSelect == TX_DIR) + { + search_dir[DIR_UP] = true; + search_dir[DIR_BI_DIR]= true; + search_dir[DIR_DIRECT]= true; + } + else + { + search_dir[DIR_DOWN] = true; + search_dir[DIR_BI_DIR]= true; + search_dir[DIR_DIRECT]= true; + } + } + + if(TxRxSelect == TX_DIR) + psearch_list = &ieee->Tx_TS_Admit_List; + else + psearch_list = &ieee->Rx_TS_Admit_List; + + //for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++) + for(dir = 0; dir <= DIR_BI_DIR; dir++) + { + if(search_dir[dir] ==false ) + continue; + list_for_each_entry(pRet, psearch_list, List){ + // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); + if (memcmp(pRet->Addr, Addr, 6) == 0) + if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) + if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) + { + // printk("Bingo! got it\n"); + break; + } + + } + if(&pRet->List != psearch_list) + break; + } + + if(&pRet->List != psearch_list){ + return pRet ; + } + else + return NULL; +} + +void MakeTSEntry( + PTS_COMMON_INFO pTsCommonInfo, + u8* Addr, + PTSPEC_BODY pTSPEC, + PQOS_TCLAS pTCLAS, + u8 TCLAS_Num, + u8 TCLAS_Proc + ) +{ + u8 count; + + if(pTsCommonInfo == NULL) + return; + + memcpy(pTsCommonInfo->Addr, Addr, 6); + + if(pTSPEC != NULL) + memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY)); + + for(count = 0; count < TCLAS_Num; count++) + memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS)); + + pTsCommonInfo->TClasProc = TCLAS_Proc; + pTsCommonInfo->TClasNum = TCLAS_Num; +} + + +bool GetTs( + struct ieee80211_device* ieee, + PTS_COMMON_INFO *ppTS, + u8* Addr, + u8 TID, + TR_SELECT TxRxSelect, //Rx:1, Tx:0 + bool bAddNewTs + ) +{ + u8 UP = 0; + // + // We do not build any TS for Broadcast or Multicast stream. + // So reject these kinds of search here. + // + if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); + return false; + } +#if 0 + if(ieee->pStaQos->CurrentQosMode == QOS_DISABLE) + { UP = 0; } //only use one TS + else if(ieee->pStaQos->CurrentQosMode & QOS_WMM) + { +#else + if (ieee->current_network.qos_data.supported == 0) + UP = 0; + else + { +#endif + // In WMM case: we use 4 TID only + if (!IsACValid(TID)) + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID); + return false; + } + + switch(TID) + { + case 0: + case 3: + UP = 0; + break; + + case 1: + case 2: + UP = 2; + break; + + case 4: + case 5: + UP = 5; + break; + + case 6: + case 7: + UP = 7; + break; + } + } + + *ppTS = SearchAdmitTRStream( + ieee, + Addr, + UP, + TxRxSelect); + if(*ppTS != NULL) + { + return true; + } + else + { + if(bAddNewTs == false) + { + IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP); + return false; + } + else + { + // + // Create a new Traffic stream for current Tx/Rx + // This is for EDCA and WMM to add a new TS. + // For HCCA or WMMSA, TS cannot be addmit without negotiation. + // + TSPEC_BODY TSpec; + PQOS_TSINFO pTSInfo = &TSpec.f.TSInfo; + struct list_head* pUnusedList = + (TxRxSelect == TX_DIR)? + (&ieee->Tx_TS_Unused_List): + (&ieee->Rx_TS_Unused_List); + + struct list_head* pAddmitList = + (TxRxSelect == TX_DIR)? + (&ieee->Tx_TS_Admit_List): + (&ieee->Rx_TS_Admit_List); + + DIRECTION_VALUE Dir = (ieee->iw_mode == IW_MODE_MASTER)? + ((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP): + ((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN); + IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n"); + if(!list_empty(pUnusedList)) + { + (*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List); + list_del_init(&(*ppTS)->List); + if(TxRxSelect==TX_DIR) + { + PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo); + ResetTxTsEntry(tmp); + } + else{ + PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo); + ResetRxTsEntry(tmp); + } + + IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); + // Prepare TS Info releated field + pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field + pTSInfo->field.ucTSID = UP; // TSID + pTSInfo->field.ucDirection = Dir; // Direction: if there is DirectLink, this need additional consideration. + pTSInfo->field.ucAccessPolicy = 1; // Access policy + pTSInfo->field.ucAggregation = 0; // Aggregation + pTSInfo->field.ucPSB = 0; // Aggregation + pTSInfo->field.ucUP = UP; // User priority + pTSInfo->field.ucTSInfoAckPolicy = 0; // Ack policy + pTSInfo->field.ucSchedule = 0; // Schedule + + MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); + AdmitTS(ieee, *ppTS, 0); + list_add_tail(&((*ppTS)->List), pAddmitList); + // if there is DirectLink, we need to do additional operation here!! + + return true; + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__); + return false; + } + } + } +} + +void RemoveTsEntry( + struct ieee80211_device* ieee, + PTS_COMMON_INFO pTs, + TR_SELECT TxRxSelect + ) +{ + //u32 flags = 0; + unsigned long flags = 0; + del_timer_sync(&pTs->SetupTimer); + del_timer_sync(&pTs->InactTimer); + TsInitDelBA(ieee, pTs, TxRxSelect); + + if(TxRxSelect == RX_DIR) + { +//#ifdef TO_DO_LIST + PRX_REORDER_ENTRY pRxReorderEntry; + PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs; + if(timer_pending(&pRxTS->RxPktPendingTimer)) + del_timer_sync(&pRxTS->RxPktPendingTimer); + + while(!list_empty(&pRxTS->RxPendingPktList)) + { + // PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK); + spin_lock_irqsave(&(ieee->reorder_spinlock), flags); + //pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); + pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); + list_del_init(&pRxReorderEntry->List); + { + int i = 0; + struct ieee80211_rxb * prxb = pRxReorderEntry->prxb; + if (unlikely(!prxb)) + { + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); + return; + } + for(i =0; i < prxb->nr_subframes; i++) { + dev_kfree_skb(prxb->subframes[i]); + } + kfree(prxb); + prxb = NULL; + } + list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List); + //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); + } + +//#endif + } + else + { + PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs; + del_timer_sync(&pTxTS->TsAddBaTimer); + } +} + +void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) +{ + PTS_COMMON_INFO pTS, pTmpTS; + printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); +#if 1 + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) + { + if (memcmp(pTS->Addr, Addr, 6) == 0) + { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) + { + if (memcmp(pTS->Addr, Addr, 6) == 0) + { + printk("====>remove Tx_TS_admin_list\n"); + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) + { + if (memcmp(pTS->Addr, Addr, 6) == 0) + { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) + { + if (memcmp(pTS->Addr, Addr, 6) == 0) + { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + } +#endif +} + +void RemoveAllTS(struct ieee80211_device* ieee) +{ + PTS_COMMON_INFO pTS, pTmpTS; +#if 1 + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) + { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) + { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) + { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) + { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } +#endif +} + +void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) +{ + if(pTxTS->bAddBaReqInProgress == false) + { + pTxTS->bAddBaReqInProgress = true; +#if 1 + if(pTxTS->bAddBaReqDelayed) + { + IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"); + mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY)); + } + else + { + IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"); + mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks + } +#endif + } + else + IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__); +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +EXPORT_SYMBOL_NOVERS(RemovePeerTS); +#else +//EXPORT_SYMBOL(RemovePeerTS); +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h new file mode 100644 index 00000000000..ccf6ae76357 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h @@ -0,0 +1,399 @@ +/* + * Scatterlist Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * + * Portions derived from Cryptoapi, by Alexander Kjeldaas + * and Nettle, by Niels Mé°ˆler. + * + * 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. + * + */ +#ifndef _LINUX_CRYPTO_H +#define _LINUX_CRYPTO_H + +#include +#include +#include +#include +#include +#include +#include + +#define crypto_register_alg crypto_register_alg_rsl +#define crypto_unregister_alg crypto_unregister_alg_rsl +#define crypto_alloc_tfm crypto_alloc_tfm_rsl +#define crypto_free_tfm crypto_free_tfm_rsl +#define crypto_alg_available crypto_alg_available_rsl + +/* + * Algorithm masks and types. + */ +#define CRYPTO_ALG_TYPE_MASK 0x000000ff +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001 +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004 + +/* + * Transform masks and values (for crt_flags). + */ +#define CRYPTO_TFM_MODE_MASK 0x000000ff +#define CRYPTO_TFM_REQ_MASK 0x000fff00 +#define CRYPTO_TFM_RES_MASK 0xfff00000 + +#define CRYPTO_TFM_MODE_ECB 0x00000001 +#define CRYPTO_TFM_MODE_CBC 0x00000002 +#define CRYPTO_TFM_MODE_CFB 0x00000004 +#define CRYPTO_TFM_MODE_CTR 0x00000008 + +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 + +/* + * Miscellaneous stuff. + */ +#define CRYPTO_UNSPEC 0 +#define CRYPTO_MAX_ALG_NAME 64 + +struct scatterlist; + +/* + * Algorithms: modular crypto algorithm implementations, managed + * via crypto_register_alg() and crypto_unregister_alg(). + */ +struct cipher_alg { + unsigned int cia_min_keysize; + unsigned int cia_max_keysize; + int (*cia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); +}; + +struct digest_alg { + unsigned int dia_digestsize; + void (*dia_init)(void *ctx); + void (*dia_update)(void *ctx, const u8 *data, unsigned int len); + void (*dia_final)(void *ctx, u8 *out); + int (*dia_setkey)(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags); +}; + +struct compress_alg { + int (*coa_init)(void *ctx); + void (*coa_exit)(void *ctx); + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); +}; + +#define cra_cipher cra_u.cipher +#define cra_digest cra_u.digest +#define cra_compress cra_u.compress + +struct crypto_alg { + struct list_head cra_list; + u32 cra_flags; + unsigned int cra_blocksize; + unsigned int cra_ctxsize; + const char cra_name[CRYPTO_MAX_ALG_NAME]; + + union { + struct cipher_alg cipher; + struct digest_alg digest; + struct compress_alg compress; + } cra_u; + + struct module *cra_module; +}; + +/* + * Algorithm registration interface. + */ +int crypto_register_alg(struct crypto_alg *alg); +int crypto_unregister_alg(struct crypto_alg *alg); + +/* + * Algorithm query interface. + */ +int crypto_alg_available(const char *name, u32 flags); + +/* + * Transforms: user-instantiated objects which encapsulate algorithms + * and core processing logic. Managed via crypto_alloc_tfm() and + * crypto_free_tfm(), as well as the various helpers below. + */ +struct crypto_tfm; + +struct cipher_tfm { + void *cit_iv; + unsigned int cit_ivsize; + u32 cit_mode; + int (*cit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); + int (*cit_encrypt)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + int (*cit_encrypt_iv)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv); + int (*cit_decrypt)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); + int (*cit_decrypt_iv)(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv); + void (*cit_xor_block)(u8 *dst, const u8 *src); +}; + +struct digest_tfm { + void (*dit_init)(struct crypto_tfm *tfm); + void (*dit_update)(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg); + void (*dit_final)(struct crypto_tfm *tfm, u8 *out); + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, + unsigned int nsg, u8 *out); + int (*dit_setkey)(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen); +#ifdef CONFIG_CRYPTO_HMAC + void *dit_hmac_block; +#endif +}; + +struct compress_tfm { + int (*cot_compress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); + int (*cot_decompress)(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); +}; + +#define crt_cipher crt_u.cipher +#define crt_digest crt_u.digest +#define crt_compress crt_u.compress + +struct crypto_tfm { + + u32 crt_flags; + + union { + struct cipher_tfm cipher; + struct digest_tfm digest; + struct compress_tfm compress; + } crt_u; + + struct crypto_alg *__crt_alg; +}; + +/* + * Transform user interface. + */ + +/* + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm. + * If that fails and the kernel supports dynamically loadable modules, it + * will then attempt to load a module of the same name or alias. A refcount + * is grabbed on the algorithm which is then associated with the new transform. + * + * crypto_free_tfm() frees up the transform and any associated resources, + * then drops the refcount on the associated algorithm. + */ +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); +void crypto_free_tfm(struct crypto_tfm *tfm); + +/* + * Transform helpers which query the underlying algorithm. + */ +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_name; +} + +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + + if (alg->cra_module) + return alg->cra_module->name; + else + return NULL; +} + +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; +} + +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_min_keysize; +} + +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_max_keysize; +} + +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_ivsize; +} + +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_blocksize; +} + +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + return tfm->__crt_alg->cra_digest.dia_digestsize; +} + +/* + * API wrappers. + */ +static inline void crypto_digest_init(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_init(tfm); +} + +static inline void crypto_digest_update(struct crypto_tfm *tfm, + struct scatterlist *sg, + unsigned int nsg) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_update(tfm, sg, nsg); +} + +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_final(tfm, out); +} + +static inline void crypto_digest_digest(struct crypto_tfm *tfm, + struct scatterlist *sg, + unsigned int nsg, u8 *out) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + tfm->crt_digest.dit_digest(tfm, sg, nsg, out); +} + +static inline int crypto_digest_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + if (tfm->crt_digest.dit_setkey == NULL) + return -ENOSYS; + return tfm->crt_digest.dit_setkey(tfm, key, keylen); +} + +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, + const u8 *key, unsigned int keylen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_setkey(tfm, key, keylen); +} + +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); +} + +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); +} + +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); +} + +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); +} + +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, + const u8 *src, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(tfm->crt_cipher.cit_iv, src, len); +} + +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, + u8 *dst, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(dst, tfm->crt_cipher.cit_iv, len); +} + +static inline int crypto_comp_compress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); +} + +static inline int crypto_comp_decompress(struct crypto_tfm *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); +} + +/* + * HMAC support. + */ +#ifdef CONFIG_CRYPTO_HMAC +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); +void crypto_hmac_update(struct crypto_tfm *tfm, + struct scatterlist *sg, unsigned int nsg); +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, + unsigned int *keylen, u8 *out); +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, + struct scatterlist *sg, unsigned int nsg, u8 *out); +#endif /* CONFIG_CRYPTO_HMAC */ + +#endif /* _LINUX_CRYPTO_H */ + diff --git a/drivers/staging/rtl8192e/ieee80211/scatterwalk.c b/drivers/staging/rtl8192e/ieee80211/scatterwalk.c new file mode 100644 index 00000000000..49f401fbce8 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/scatterwalk.c @@ -0,0 +1,126 @@ +/* + * Cryptographic API. + * + * Cipher operations. + * + * Copyright (c) 2002 James Morris + * 2002 Adam J. Richter + * 2004 Jean-Luc Cooke + * + * 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. + * + */ +#include "kmap_types.h" + +#include +#include +#include +#include +#include +#include "internal.h" +#include "scatterwalk.h" + +enum km_type crypto_km_types[] = { + KM_USER0, + KM_USER1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, +}; + +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch) +{ + if (nbytes <= walk->len_this_page && + (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <= + PAGE_CACHE_SIZE) + return walk->data; + else + return scratch; +} + +static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) +{ + if (out) + memcpy(sgdata, buf, nbytes); + else + memcpy(buf, sgdata, nbytes); +} + +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) +{ + unsigned int rest_of_page; + + walk->sg = sg; + + walk->page = sg->page; + walk->len_this_segment = sg->length; + + rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1)); + walk->len_this_page = min(sg->length, rest_of_page); + walk->offset = sg->offset; +} + +void scatterwalk_map(struct scatter_walk *walk, int out) +{ + walk->data = crypto_kmap(walk->page, out) + walk->offset; +} + +static void scatterwalk_pagedone(struct scatter_walk *walk, int out, + unsigned int more) +{ + /* walk->data may be pointing the first byte of the next page; + however, we know we transfered at least one byte. So, + walk->data - 1 will be a virtual address in the mapped page. */ + + if (out) + flush_dcache_page(walk->page); + + if (more) { + walk->len_this_segment -= walk->len_this_page; + + if (walk->len_this_segment) { + walk->page++; + walk->len_this_page = min(walk->len_this_segment, + (unsigned)PAGE_CACHE_SIZE); + walk->offset = 0; + } + else + scatterwalk_start(walk, sg_next(walk->sg)); + } +} + +void scatterwalk_done(struct scatter_walk *walk, int out, int more) +{ + crypto_kunmap(walk->data, out); + if (walk->len_this_page == 0 || !more) + scatterwalk_pagedone(walk, out, more); +} + +/* + * Do not call this unless the total length of all of the fragments + * has been verified as multiple of the block size. + */ +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, + size_t nbytes, int out) +{ + if (buf != walk->data) { + while (nbytes > walk->len_this_page) { + memcpy_dir(buf, walk->data, walk->len_this_page, out); + buf += walk->len_this_page; + nbytes -= walk->len_this_page; + + crypto_kunmap(walk->data, out); + scatterwalk_pagedone(walk, out, 1); + scatterwalk_map(walk, out); + } + + memcpy_dir(buf, walk->data, nbytes, out); + } + + walk->offset += nbytes; + walk->len_this_page -= nbytes; + walk->len_this_segment -= nbytes; + return 0; +} diff --git a/drivers/staging/rtl8192e/ieee80211/scatterwalk.h b/drivers/staging/rtl8192e/ieee80211/scatterwalk.h new file mode 100644 index 00000000000..b1644651901 --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211/scatterwalk.h @@ -0,0 +1,51 @@ +/* + * Cryptographic API. + * + * Copyright (c) 2002 James Morris + * Copyright (c) 2002 Adam J. Richter + * Copyright (c) 2004 Jean-Luc Cooke + * + * 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. + * + */ + +#ifndef _CRYPTO_SCATTERWALK_H +#define _CRYPTO_SCATTERWALK_H +#include +#include + +struct scatter_walk { + struct scatterlist *sg; + struct page *page; + void *data; + unsigned int len_this_page; + unsigned int len_this_segment; + unsigned int offset; +}; + +/* Define sg_next is an inline routine now in case we want to change + scatterlist to a linked list later. */ +static inline struct scatterlist *sg_next(struct scatterlist *sg) +{ + return sg + 1; +} + +static inline int scatterwalk_samebuf(struct scatter_walk *walk_in, + struct scatter_walk *walk_out, + void *src_p, void *dst_p) +{ + return walk_in->page == walk_out->page && + walk_in->offset == walk_out->offset && + walk_in->data == src_p && walk_out->data == dst_p; +} + +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch); +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out); +void scatterwalk_map(struct scatter_walk *walk, int out); +void scatterwalk_done(struct scatter_walk *walk, int out, int more); + +#endif /* _CRYPTO_SCATTERWALK_H */ diff --git a/drivers/staging/rtl8192e/ieee80211_crypt.h b/drivers/staging/rtl8192e/ieee80211_crypt.h new file mode 100644 index 00000000000..b58a3bcc0dc --- /dev/null +++ b/drivers/staging/rtl8192e/ieee80211_crypt.h @@ -0,0 +1,86 @@ +/* + * Original code based on Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * + * Copyright (c) 2002-2003, Jouni Malinen + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * + * + * Copyright (c) 2004, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ + +/* + * This file defines the interface to the ieee80211 crypto module. + */ +#ifndef IEEE80211_CRYPT_H +#define IEEE80211_CRYPT_H + +#include + +struct ieee80211_crypto_ops { + const char *name; + + /* init new crypto context (e.g., allocate private data space, + * select IV, etc.); returns NULL on failure or pointer to allocated + * private data on success */ + void * (*init)(int keyidx); + + /* deinitialize crypto context and free allocated private data */ + void (*deinit)(void *priv); + + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return + * value from decrypt_mpdu is passed as the keyidx value for + * decrypt_msdu. skb must have enough head and tail room for the + * encryption; if not, error will be returned; these functions are + * called for all MPDUs (i.e., fragments). + */ + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); + + /* These functions are called for full MSDUs, i.e. full frames. + * These can be NULL if full MSDU operations are not needed. */ + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, + void *priv); + + int (*set_key)(void *key, int len, u8 *seq, void *priv); + int (*get_key)(void *key, int len, u8 *seq, void *priv); + + /* procfs handler for printing out key information and possible + * statistics */ + char * (*print_stats)(char *p, void *priv); + + /* maximum number of bytes added by encryption; encrypt buf is + * allocated with extra_prefix_len bytes, copy of in_buf, and + * extra_postfix_len; encrypt need not use all this space, but + * the result must start at the beginning of the buffer and correct + * length must be returned */ + int extra_prefix_len, extra_postfix_len; + + struct module *owner; +}; + +struct ieee80211_crypt_data { + struct list_head list; /* delayed deletion list */ + struct ieee80211_crypto_ops *ops; + void *priv; + atomic_t refcnt; +}; + +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); +void ieee80211_crypt_deinit_handler(unsigned long); +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, + struct ieee80211_crypt_data **crypt); + +#endif diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c new file mode 100644 index 00000000000..838ee352c0e --- /dev/null +++ b/drivers/staging/rtl8192e/r8180_93cx6.c @@ -0,0 +1,146 @@ +/* + This files contains card eeprom (93c46 or 93c56) programming routines, + memory is addressed by 16 bits words. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official realtek driver. + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + +#include "r8180_93cx6.h" + +void eprom_cs(struct net_device *dev, short bit) +{ + if(bit) + write_nic_byte(dev, EPROM_CMD, + (1<epromtype==EPROM_93c56){ + addr_str[7]=addr & 1; + addr_str[6]=addr & (1<<1); + addr_str[5]=addr & (1<<2); + addr_str[4]=addr & (1<<3); + addr_str[3]=addr & (1<<4); + addr_str[2]=addr & (1<<5); + addr_str[1]=addr & (1<<6); + addr_str[0]=addr & (1<<7); + addr_len=8; + }else{ + addr_str[5]=addr & 1; + addr_str[4]=addr & (1<<1); + addr_str[3]=addr & (1<<2); + addr_str[2]=addr & (1<<3); + addr_str[1]=addr & (1<<4); + addr_str[0]=addr & (1<<5); + addr_len=6; + } + eprom_cs(dev, 1); + eprom_ck_cycle(dev); + eprom_send_bits_string(dev, read_cmd, 3); + eprom_send_bits_string(dev, addr_str, addr_len); + + //keep chip pin D to low state while reading. + //I'm unsure if it is necessary, but anyway shouldn't hurt + eprom_w(dev, 0); + + for(i=0;i<16;i++){ + //eeprom needs a clk cycle between writing opcode&adr + //and reading data. (eeprom outs a dummy 0) + eprom_ck_cycle(dev); + ret |= (eprom_r(dev)<<(15-i)); + } + + eprom_cs(dev, 0); + eprom_ck_cycle(dev); + + //disable EPROM programming + write_nic_byte(dev, EPROM_CMD, + (EPROM_CMD_NORMAL< + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the official realtek driver + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of such projects and the Ndiswrapper project Authors. +*/ + +/*This files contains card eeprom (93c46 or 93c56) programming routines*/ +/*memory is addressed by WORDS*/ + +#include "r8192E.h" +#include "r8192E_hw.h" + +#define EPROM_DELAY 10 + +#define EPROM_ANAPARAM_ADDRLWORD 0xd +#define EPROM_ANAPARAM_ADDRHWORD 0xe + +#define EPROM_RFCHIPID 0x6 +#define EPROM_TXPW_BASE 0x05 +#define EPROM_RFCHIPID_RTL8225U 5 +#define EPROM_RF_PARAM 0x4 +#define EPROM_CONFIG2 0xc + +#define EPROM_VERSION 0x1E +#define MAC_ADR 0x7 + +#define CIS 0x18 + +#define EPROM_TXPW0 0x16 +#define EPROM_TXPW2 0x1b +#define EPROM_TXPW1 0x3d + + +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c new file mode 100644 index 00000000000..da628c52040 --- /dev/null +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -0,0 +1,1161 @@ +/* + This is part of the rtl8192 driver + released under the GPL (See file COPYING for details). + + This files contains programming code for the rtl8256 + radio frontend. + + *Many* thanks to Realtek Corp. for their great support! + +*/ + +#include "r8192E.h" +#include "r8192E_hw.h" +#include "r819xE_phyreg.h" +#include "r819xE_phy.h" +#include "r8190_rtl8256.h" + +/*-------------------------------------------------------------------------- + * Overview: set RF band width (20M or 40M) + * Input: struct net_device* dev + * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M + * Output: NONE + * Return: NONE + * Note: 8226 support both 20M and 40 MHz + *---------------------------------------------------------------------------*/ +void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M +{ + u8 eRFPath; + struct r8192_priv *priv = ieee80211_priv(dev); + + //for(eRFPath = RF90_PATH_A; eRFPath NumTotalRFPath; eRFPath++) + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + { + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + continue; + + switch(Bandwidth) + { + case HT_CHANNEL_WIDTH_20: + if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! + { + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021); + + //cosa add for sd3's request 01/23/2008 + //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); + } + else + { + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); + } + + break; + case HT_CHANNEL_WIDTH_20_40: + if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! + { + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); + + //cosa add for sd3's request 01/23/2008 + #if 0 + if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b); + else + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); + #endif + } + else + { + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); + } + + + break; + default: + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ); + break; + + } + } + return; +} +/*-------------------------------------------------------------------------- + * Overview: Interface to config 8256 + * Input: struct net_device* dev + * Output: NONE + * Return: NONE + *---------------------------------------------------------------------------*/ +RT_STATUS PHY_RF8256_Config(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + // Initialize general global value + // + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + // TODO: Extend RF_PATH_C and RF_PATH_D in the future + priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; + // Config BB and RF + rtStatus = phy_RF8256_Config_ParaFile(dev); + + return rtStatus; +} +/*-------------------------------------------------------------------------- + * Overview: Interface to config 8256 + * Input: struct net_device* dev + * Output: NONE + * Return: NONE + *---------------------------------------------------------------------------*/ +RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) +{ + u32 u4RegValue = 0; + u8 eRFPath; + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + BB_REGISTER_DEFINITION_T *pPhyReg; + struct r8192_priv *priv = ieee80211_priv(dev); + u32 RegOffSetToBeCheck = 0x3; + u32 RegValueToBeCheck = 0x7f1; + u32 RF3_Final_Value = 0; + u8 ConstRetryTimes = 5, RetryTimes = 5; + u8 ret = 0; + //3//----------------------------------------------------------------- + //3// <2> Initialize RF + //3//----------------------------------------------------------------- + for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath NumTotalRFPath; eRFPath++) + { + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + continue; + + pPhyReg = &priv->PHYRegDef[eRFPath]; + + // Joseph test for shorten RF config + // pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord); + + /*----Store original RFENV control type----*/ + switch(eRFPath) + { + case RF90_PATH_A: + case RF90_PATH_C: + u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); + break; + case RF90_PATH_B : + case RF90_PATH_D: + u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16); + break; + } + + /*----Set RF_ENV enable----*/ + rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + + /*----Set RF_ENV output high----*/ + rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); + + /* Set bit number of Address and Data for RF register */ + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? + + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); + + /*----Check RF block (for FPGA platform only)----*/ + // TODO: this function should be removed on ASIC , Emily 2007.2.2 + rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath); + if(rtStatus!= RT_STATUS_SUCCESS) + { + RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath); + goto phy_RF8256_Config_ParaFile_Fail; + } + + RetryTimes = ConstRetryTimes; + RF3_Final_Value = 0; + /*----Initialize RF fom connfiguration file----*/ + switch(eRFPath) + { + case RF90_PATH_A: + while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) + { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_B: + while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) + { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_C: + while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) + { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_D: + while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) + { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + } + + /*----Restore RFENV control type----*/; + switch(eRFPath) + { + case RF90_PATH_A: + case RF90_PATH_C: + rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); + break; + case RF90_PATH_B : + case RF90_PATH_D: + rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); + break; + } + + if(ret){ + RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath); + goto phy_RF8256_Config_ParaFile_Fail; + } + + } + + RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ; + return RT_STATUS_SUCCESS; + +phy_RF8256_Config_ParaFile_Fail: + RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ; + return RT_STATUS_FAILURE; +} + + +void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) +{ + u32 TxAGC=0; + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef RTL8190P + u8 byte0, byte1; + + TxAGC |= ((powerlevel<<8)|powerlevel); + TxAGC += priv->CCKTxPowerLevelOriginalOffset; + + if(priv->bDynamicTxLowPower == true //cosa 04282008 for cck long range + /*pMgntInfo->bScanInProgress == TRUE*/ ) //cosa 05/22/2008 for scan + { + if(priv->CustomerID == RT_CID_819x_Netcore) + TxAGC = 0x2222; + else + TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl); + } + + byte0 = (u8)(TxAGC & 0xff); + byte1 = (u8)((TxAGC & 0xff00)>>8); + if(byte0 > 0x24) + byte0 = 0x24; + if(byte1 > 0x24) + byte1 = 0x24; + if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset + { // check antenna C over the max index 0x24 + if(priv->RF_C_TxPwDiff > 0) + { + if( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24) + byte0 = 0x24 - priv->RF_C_TxPwDiff; + if( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24) + byte1 = 0x24 - priv->RF_C_TxPwDiff; + } + } + TxAGC = (byte1<<8) |byte0; + write_nic_dword(dev, CCK_TXAGC, TxAGC); +#else + #ifdef RTL8192E + + TxAGC = powerlevel; + if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range + { + if(priv->CustomerID == RT_CID_819x_Netcore) + TxAGC = 0x22; + else + TxAGC += priv->CckPwEnl; + } + if(TxAGC > 0x24) + TxAGC = 0x24; + rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); + #endif +#endif +} + + +void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + //Joseph TxPower for 8192 testing +#ifdef RTL8190P + u32 TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0; + u8 i, byteVal1[4], byteVal2[4], byteVal3[4]; + + if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 + { + TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); + //for tx power track + TxAGC2_tmp = TxAGC1; + + TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; + TxAGC2 =0x03030303; + + //for tx power track + TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1]; + } + else + { + TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); + TxAGC2 = TxAGC1; + + TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; + TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1]; + + TxAGC2_tmp = TxAGC2; + + } + for(i=0; i<4; i++) + { + byteVal1[i] = (u8)( (TxAGC1 & (0xff<<(i*8))) >>(i*8) ); + if(byteVal1[i] > 0x24) + byteVal1[i] = 0x24; + byteVal2[i] = (u8)( (TxAGC2 & (0xff<<(i*8))) >>(i*8) ); + if(byteVal2[i] > 0x24) + byteVal2[i] = 0x24; + + //for tx power track + byteVal3[i] = (u8)( (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) ); + if(byteVal3[i] > 0x24) + byteVal3[i] = 0x24; + } + + if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset + { // check antenna C over the max index 0x24 + if(priv->RF_C_TxPwDiff > 0) + { + for(i=0; i<4; i++) + { + if( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) + byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff; + if( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) + byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff; + if( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) + byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff; + } + } + } + + TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0]; + TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0]; + + //for tx power track + TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0]; + priv->Pwr_Track = TxAGC2_tmp; + //DbgPrint("TxAGC2_tmp = 0x%x\n", TxAGC2_tmp); + + //DbgPrint("TxAGC1/TxAGC2 = 0x%x/0x%x\n", TxAGC1, TxAGC2); + write_nic_dword(dev, MCS_TXAGC, TxAGC1); + write_nic_dword(dev, MCS_TXAGC+4, TxAGC2); +#else +#ifdef RTL8192E + u32 writeVal, powerBase0, powerBase1, writeVal_tmp; + u8 index = 0; + u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; + u8 byte0, byte1, byte2, byte3; + + powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; //OFDM rates + powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0; + powerBase1 = powerlevel; //MCS rates + powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1; + + for(index=0; index<6; index++) + { + writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1); + byte0 = (u8)(writeVal & 0x7f); + byte1 = (u8)((writeVal & 0x7f00)>>8); + byte2 = (u8)((writeVal & 0x7f0000)>>16); + byte3 = (u8)((writeVal & 0x7f000000)>>24); + if(byte0 > 0x24) // Max power index = 0x24 + byte0 = 0x24; + if(byte1 > 0x24) + byte1 = 0x24; + if(byte2 > 0x24) + byte2 = 0x24; + if(byte3 > 0x24) + byte3 = 0x24; + + if(index == 3) + { + writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; + priv->Pwr_Track = writeVal_tmp; + } + + if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 //when DM implement, add this + { + writeVal = 0x03030303; + } + else + { + writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; + } + rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); + } + +#endif +#endif + return; +} + +#define MAX_DOZE_WAITING_TIMES_9x 64 +bool +SetRFPowerState8190( + struct net_device* dev, + RT_RF_POWER_STATE eRFPowerState + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + bool bResult = true; + //u8 eRFPath; + u8 i = 0, QueueID = 0; + ptx_ring head=NULL,tail=NULL; + + if(priv->SetRFPowerStateInProgress == true) + return false; + RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n"); + priv->SetRFPowerStateInProgress = true; + + switch(priv->rf_chip) + { + case RF_8256: + switch( eRFPowerState ) + { + case eRfOn: + RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n"); + //RXTX enable control: On + //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + // PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); + #ifdef RTL8190P + if(priv->rf_type == RF_2T4R) + { + //enable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] + //enable RF-Chip C/D + rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0xf); // 0x880[8:5] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0xf);// 0xc04[3:0] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0xf);// 0xd04[3:0] + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0xf); // 0x880[12:9] + } + else if(priv->rf_type == RF_1T2R) //RF-C, RF-D + { + //enable RF-Chip C/D + rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x180, 0x3); // 0x880[8:7] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xc, 0x3);// 0xc04[3:2] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xc, 0x3);// 0xd04[3:2] + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11] + } + #else + write_nic_byte(dev, ANAPAR, 0x37);//160MHz + write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403 + mdelay(1); + //enable clock 80/88 MHz + + priv->bHwRfOffAction = 0; + //} + + // Baseband reset 2008.09.30 add + write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); + + //2 AFE + // 2008.09.30 add + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] + //rx antenna on + //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] + //rx antenna on 2008.09.30 mark + //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] + + //2 RF + //enable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] + rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] + #endif + break; + + // + // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. + // By Bruce, 2008-01-16. + // + case eRfSleep: + case eRfOff: + RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n"); + if (pPSC->bLeisurePs) + { + for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) + { + switch(QueueID) { + case MGNT_QUEUE: + tail=priv->txmapringtail; + head=priv->txmapringhead; + break; + + case BK_QUEUE: + tail=priv->txbkpringtail; + head=priv->txbkpringhead; + break; + + case BE_QUEUE: + tail=priv->txbepringtail; + head=priv->txbepringhead; + break; + + case VI_QUEUE: + tail=priv->txvipringtail; + head=priv->txvipringhead; + break; + + case VO_QUEUE: + tail=priv->txvopringtail; + head=priv->txvopringhead; + break; + + default: + tail=head=NULL; + break; + } + if(tail == head) + { + //DbgPrint("QueueID = %d", QueueID); + QueueID++; + continue; + } + else + { + RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); + udelay(10); + i++; + } + + if(i >= MAX_DOZE_WAITING_TIMES_9x) + { + RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); + break; + } + } + } + #ifdef RTL8190P + if(priv->rf_type == RF_2T4R) + { + //disable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4] + } + //disable RF-Chip C/D + rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4] + //analog to digital off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + //digital to analog off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5] + //rx antenna off + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0] + //rx antenna off + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0] + //analog to digital part2 off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9] +#else //8192E + //2 RF + //disable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4] + rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0); // 0x864[4] + //2 AFE + //analog to digital off, for power save + //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); // 2008.09.30 Modify + //digital to analog off, for power save + //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3] + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify + //rx antenna off 2008.09.30 mark + //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0] + //rx antenna off 2008.09.30 mark + //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0] + //analog to digital part2 off, for power save + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5] + // 2008.09.30 add + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884 + + + //disable clock 80/88 MHz 2008.09.30 mark + //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2] + //2 BB + // Baseband reset 2008.09.30 add + write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101 + //MAC: off + write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403 + //slow down cpu/lbus clock from 160MHz to Lower + write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz + priv->bHwRfOffAction = 0; + //} + #endif + break; + + default: + bResult = false; + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); + break; + } + + break; + + default: + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); + break; + } + + if(bResult) + { + // Update current RF state variable. + priv->ieee80211->eRFPowerState = eRFPowerState; + + switch(priv->rf_chip ) + { + case RF_8256: + switch(priv->ieee80211->eRFPowerState) + { + case eRfOff: + // + //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015 + // + if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS ) + { + #ifdef TO_DO + Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK); + #endif + } + else + { + // Turn off LED if RF is not ON. + #ifdef TO_DO + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF); + #endif + } + break; + + case eRfOn: + // Turn on RF we are still linked, which might happen when + // we quickly turn off and on HW RF. 2006.05.12, by rcnjko. + if( priv->ieee80211->state == IEEE80211_LINKED) + { + #ifdef TO_DO + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK); + #endif + } + else + { + // Turn off LED if RF is not ON. + #ifdef TO_DO + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK); + #endif + } + break; + + default: + // do nothing. + break; + }// Switch RF state + + break; + + default: + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); + break; + }// Switch RFChipID + } + + priv->SetRFPowerStateInProgress = false; + RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); + return bResult; +} + + + +// +// Description: +// Change RF power state. +// +// Assumption: +// This function must be executed in re-schdulable context, +// ie. PASSIVE_LEVEL. +// +// 050823, by rcnjko. +// +bool +SetRFPowerState( + struct net_device* dev, + RT_RF_POWER_STATE eRFPowerState + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + bool bResult = false; + + RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); +#ifdef RTL8192E + if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0) +#else + if(eRFPowerState == priv->ieee80211->eRFPowerState) +#endif + { + RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); + return bResult; + } + + bResult = SetRFPowerState8190(dev, eRFPowerState); + + RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult); + + return bResult; +} + +void +MgntDisconnectIBSS( + struct net_device* dev +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + //RT_OP_MODE OpMode; + u8 i; + bool bFilterOutNonAssociatedBSSID = false; + + //IEEE80211_DEBUG(IEEE80211_DL_TRACE, "XXXXXXXXXX MgntDisconnect IBSS\n"); + + priv->ieee80211->state = IEEE80211_NOLINK; + +// PlatformZeroMemory( pMgntInfo->Bssid, 6 ); + for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55; + priv->OpMode = RT_OP_MODE_NO_LINK; + write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); + write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); + { + RT_OP_MODE OpMode = priv->OpMode; + //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; + u8 btMsr = read_nic_byte(dev, MSR); + + btMsr &= 0xfc; + + switch(OpMode) + { + case RT_OP_MODE_INFRASTRUCTURE: + btMsr |= MSR_LINK_MANAGED; + //LedAction = LED_CTL_LINK; + break; + + case RT_OP_MODE_IBSS: + btMsr |= MSR_LINK_ADHOC; + // led link set seperate + break; + + case RT_OP_MODE_AP: + btMsr |= MSR_LINK_MASTER; + //LedAction = LED_CTL_LINK; + break; + + default: + btMsr |= MSR_LINK_NONE; + break; + } + + write_nic_byte(dev, MSR, btMsr); + + // LED control + //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); + } + ieee80211_stop_send_beacons(priv->ieee80211); + + // If disconnect, clear RCR CBSSID bit + bFilterOutNonAssociatedBSSID = false; + { + u32 RegRCR, Type; + Type = bFilterOutNonAssociatedBSSID; + RegRCR = read_nic_dword(dev,RCR); + priv->ReceiveConfig = RegRCR; + if (Type == true) + RegRCR |= (RCR_CBSSID); + else if (Type == false) + RegRCR &= (~RCR_CBSSID); + + { + write_nic_dword(dev, RCR,RegRCR); + priv->ReceiveConfig = RegRCR; + } + + } + //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE ); + notify_wx_assoc_event(priv->ieee80211); + +} + +void +MlmeDisassociateRequest( + struct net_device* dev, + u8* asSta, + u8 asRsn + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 i; + + RemovePeerTS(priv->ieee80211, asSta); + + SendDisassociation( priv->ieee80211, asSta, asRsn ); + + if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == 0) + { + //ShuChen TODO: change media status. + //ShuChen TODO: What to do when disassociate. + priv->ieee80211->state = IEEE80211_NOLINK; + //pMgntInfo->AsocTimestamp = 0; + for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; +// pMgntInfo->mBrates.Length = 0; +// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) ); + priv->OpMode = RT_OP_MODE_NO_LINK; + { + RT_OP_MODE OpMode = priv->OpMode; + //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; + u8 btMsr = read_nic_byte(dev, MSR); + + btMsr &= 0xfc; + + switch(OpMode) + { + case RT_OP_MODE_INFRASTRUCTURE: + btMsr |= MSR_LINK_MANAGED; + //LedAction = LED_CTL_LINK; + break; + + case RT_OP_MODE_IBSS: + btMsr |= MSR_LINK_ADHOC; + // led link set seperate + break; + + case RT_OP_MODE_AP: + btMsr |= MSR_LINK_MASTER; + //LedAction = LED_CTL_LINK; + break; + + default: + btMsr |= MSR_LINK_NONE; + break; + } + + write_nic_byte(dev, MSR, btMsr); + + // LED control + //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); + } + ieee80211_disassociate(priv->ieee80211); + + write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); + write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); + + } + +} + + +void +MgntDisconnectAP( + struct net_device* dev, + u8 asRsn +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + bool bFilterOutNonAssociatedBSSID = false; + +// +// Commented out by rcnjko, 2005.01.27: +// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). +// +// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success +// SecClearAllKeys(Adapter); + + // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. +#ifdef TO_DO + if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch || + (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key + { + SecClearAllKeys(Adapter); + RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key...")) + } +#endif + // If disconnect, clear RCR CBSSID bit + bFilterOutNonAssociatedBSSID = false; + { + u32 RegRCR, Type; + + Type = bFilterOutNonAssociatedBSSID; + //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR)); + RegRCR = read_nic_dword(dev,RCR); + priv->ReceiveConfig = RegRCR; + + if (Type == true) + RegRCR |= (RCR_CBSSID); + else if (Type == false) + RegRCR &= (~RCR_CBSSID); + + write_nic_dword(dev, RCR,RegRCR); + priv->ReceiveConfig = RegRCR; + + + } + // 2004.10.11, by rcnjko. + //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss ); + MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn ); + + priv->ieee80211->state = IEEE80211_NOLINK; + //pMgntInfo->AsocTimestamp = 0; +} + + +bool +MgntDisconnect( + struct net_device* dev, + u8 asRsn +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + // + // Schedule an workitem to wake up for ps mode, 070109, by rcnjko. + // +#ifdef TO_DO + if(pMgntInfo->mPss != eAwake) + { + // + // Using AwkaeTimer to prevent mismatch ps state. + // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31. + // + // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) ); + PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 ); + } +#endif + // Follow 8180 AP mode, 2005.05.30, by rcnjko. +#ifdef TO_DO + if(pMgntInfo->mActingAsAp) + { + RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n")); + AP_DisassociateAllStation(Adapter, unspec_reason); + return TRUE; + } +#endif + // Indication of disassociation event. + //DrvIFIndicateDisassociation(Adapter, asRsn); + + // In adhoc mode, update beacon frame. + if( priv->ieee80211->state == IEEE80211_LINKED ) + { + if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) + { + //RT_TRACE(COMP_MLME, "MgntDisconnect() ===> MgntDisconnectIBSS\n"); + MgntDisconnectIBSS(dev); + } + if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) + { + // We clear key here instead of MgntDisconnectAP() because that + // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, + // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is + // used to handle disassociation related things to AP, e.g. send Disassoc + // frame to AP. 2005.01.27, by rcnjko. + //IEEE80211_DEBUG(IEEE80211_DL_TRACE,"MgntDisconnect() ===> MgntDisconnectAP\n"); + MgntDisconnectAP(dev, asRsn); + } + + // Inidicate Disconnect, 2005.02.23, by rcnjko. + //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE); + } + + return true; +} + +// +// Description: +// Chang RF Power State. +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. +// +// Assumption: +// PASSIVE LEVEL. +// +bool +MgntActSet_RF_State( + struct net_device* dev, + RT_RF_POWER_STATE StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + bool bActionAllowed = false; + bool bConnectBySSID = false; + RT_RF_POWER_STATE rtState; + u16 RFWaitCounter = 0; + unsigned long flag; + RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); + + //1// + //1//<1>Prevent the race condition of RF state change. + //1// + // Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28. + + while(true) + { + spin_lock_irqsave(&priv->rf_ps_lock,flag); + if(priv->RFChangeInProgress) + { + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet); + + // Set RF after the previous action is done. + while(priv->RFChangeInProgress) + { + RFWaitCounter ++; + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter); + udelay(1000); // 1 ms + + // Wait too long, return FALSE to avoid to be stuck here. + if(RFWaitCounter > 100) + { + RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n"); + // TODO: Reset RF state? + return false; + } + } + } + else + { + priv->RFChangeInProgress = true; + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + break; + } + } + + rtState = priv->ieee80211->eRFPowerState; + + switch(StateToSet) + { + case eRfOn: + // + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. + // + + priv->ieee80211->RfOffReason &= (~ChangeSource); + + if(! priv->ieee80211->RfOffReason) + { + priv->ieee80211->RfOffReason = 0; + bActionAllowed = true; + + + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW ) + { + bConnectBySSID = true; + } + } + else + RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource); + + break; + + case eRfOff: + + if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + // + // 060808, Annie: + // Disconnect to current BSS when radio off. Asked by QuanTa. + // + // Set all link status falg, by Bruce, 2007-06-26. + //MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss ); + MgntDisconnect(dev, disas_lv_ss); + + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. + // 2007.05.28, by shien chang. + + } + + + priv->ieee80211->RfOffReason |= ChangeSource; + bActionAllowed = true; + break; + + case eRfSleep: + priv->ieee80211->RfOffReason |= ChangeSource; + bActionAllowed = true; + break; + + default: + break; + } + + if(bActionAllowed) + { + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason); + // Config HW to the specified mode. + SetRFPowerState(dev, StateToSet); + // Turn on RF. + if(StateToSet == eRfOn) + { + //Adapter->HalFunc.HalEnableRxHandler(Adapter); + if(bConnectBySSID) + { + //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE ); + } + } + // Turn off RF. + else if(StateToSet == eRfOff) + { + //Adapter->HalFunc.HalDisableRxHandler(Adapter); + } + } + else + { + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason); + } + + // Release RF spinlock + spin_lock_irqsave(&priv->rf_ps_lock,flag); + priv->RFChangeInProgress = false; + spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + + RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n"); + return bActionAllowed; +} + + diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h new file mode 100644 index 00000000000..7d9095a70ae --- /dev/null +++ b/drivers/staging/rtl8192e/r8190_rtl8256.h @@ -0,0 +1,28 @@ +/* + This is part of the rtl8180-sa2400 driver + released under the GPL (See file COPYING for details). + Copyright (c) 2005 Andrea Merello + + This files contains programming code for the rtl8256 + radio frontend. + + *Many* thanks to Realtek Corp. for their great support! + +*/ + +#ifndef RTL8225H +#define RTL8225H + +#ifdef RTL8190P +#define RTL819X_TOTAL_RF_PATH 4 +#else +#define RTL819X_TOTAL_RF_PATH 2 //for 8192E +#endif +extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); +extern RT_STATUS PHY_RF8256_Config(struct net_device* dev); +extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev); +extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel); +extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel); +extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource); + +#endif diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h new file mode 100644 index 00000000000..52b1dd06eaf --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E.h @@ -0,0 +1,1554 @@ +/* + This is part of rtl8187 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official realtek driver + + Parts of this driver are based on the rtl8192 driver skeleton + from Patric Schenke & Andres Salomon + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + +#ifndef R819xU_H +#define R819xU_H + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include //for rtnl_lock() +#include +#include +#include // Necessary because we use the proc fs +#include +#include +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) +#include +#endif +#include "ieee80211.h" + + + + +#define RTL819xE_MODULE_NAME "rtl819xE" +//added for HW security, john.0629 +#define FALSE 0 +#define TRUE 1 +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 +// Rx smooth factor +#define Rx_Smooth_Factor 20 +/* 2007/06/04 MH Define sliding window for RSSI history. */ +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_Beacon_RSSI_SLID_WIN_MAX 10 + +#define IC_VersionCut_D 0x3 +#define IC_VersionCut_E 0x4 + +#if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb. +#define DMESG(x,a...) printk(KERN_INFO RTL819xE_MODULE_NAME ": " x "\n", ## a) +#define DMESGW(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": WW:" x "\n", ## a) +#define DMESGE(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": EE:" x "\n", ## a) +#else +#define DMESG(x,a...) +#define DMESGW(x,a...) +#define DMESGE(x,a...) +extern u32 rt_global_debug_component; +#define RT_TRACE(component, x, args...) \ +do { if(rt_global_debug_component & component) \ + printk(KERN_DEBUG RTL819xE_MODULE_NAME ":" x "\n" , \ + ##args);\ +}while(0); + +#define COMP_TRACE BIT0 // For function call tracing. +#define COMP_DBG BIT1 // Only for temporary debug message. +#define COMP_INIT BIT2 // during driver initialization / halt / reset. + + +#define COMP_RECV BIT3 // Reveive part data path. +#define COMP_SEND BIT4 // Send part path. +#define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02. +#define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related. +#define COMP_EPROM BIT7 // 802.11 link related: join/start BSS, leave BSS. +#define COMP_SWBW BIT8 // For bandwidth switch. +#define COMP_SEC BIT9// For Security. + + +#define COMP_TURBO BIT10 // For Turbo Mode related. By Annie, 2005-10-21. +#define COMP_QOS BIT11 // For QoS. + +#define COMP_RATE BIT12 // For Rate Adaptive mechanism, 2006.07.02, by rcnjko. #define COMP_EVENTS 0x00000080 // Event handling +#define COMP_RXDESC BIT13 // Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15. +#define COMP_PHY BIT14 +#define COMP_DIG BIT15 // For DIG, 2006.09.25, by rcnjko. +#define COMP_TXAGC BIT16 // For Tx power, 060928, by rcnjko. +#define COMP_HALDM BIT17 // For HW Dynamic Mechanism, 061010, by rcnjko. +#define COMP_POWER_TRACKING BIT18 //FOR 8190 TX POWER TRACKING +#define COMP_EVENTS BIT19 // Event handling + +#define COMP_RF BIT20 // For RF. +//1!!!!!!!!!!!!!!!!!!!!!!!!!!! +//1//1Attention Please!!!<11n or 8190 specific code should be put below this line> +//1!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#define COMP_FIRMWARE BIT21 //for firmware downloading +#define COMP_HT BIT22 // For 802.11n HT related information. by Emily 2006-8-11 + +#define COMP_RESET BIT23 +#define COMP_CMDPKT BIT24 +#define COMP_SCAN BIT25 +#define COMP_IPS BIT26 +#define COMP_DOWN BIT27 // for rm driver module +#define COMP_INTR BIT28 // for interrupt +#define COMP_ERR BIT31 // for error out, always on +#endif + +#define RTL819x_DEBUG +#ifdef RTL819x_DEBUG +#define assert(expr) \ + if (!(expr)) { \ + printk( "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +//wb added to debug out data buf +//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA +#define RT_DEBUG_DATA(level, data, datalen) \ + do{ if ((rt_global_debug_component & (level)) == (level)) \ + { \ + int i; \ + u8* pdata = (u8*) data; \ + printk(KERN_DEBUG RTL819xE_MODULE_NAME ": %s()\n", __FUNCTION__); \ + for(i=0; i<(int)(datalen); i++) \ + { \ + printk("%2x ", pdata[i]); \ + if ((i+1)%16 == 0) printk("\n"); \ + } \ + printk("\n"); \ + } \ + } while (0) +#else +#define assert(expr) do {} while (0) +#define RT_DEBUG_DATA(level, data, datalen) do {} while(0) +#endif /* RTL8169_DEBUG */ + + +// +// Queue Select Value in TxDesc +// +#define QSLT_BK 0x1 +#define QSLT_BE 0x0 +#define QSLT_VI 0x4 +#define QSLT_VO 0x6 +#define QSLT_BEACON 0x10 +#define QSLT_HIGH 0x11 +#define QSLT_MGNT 0x12 +#define QSLT_CMD 0x13 + +#define DESC90_RATE1M 0x00 +#define DESC90_RATE2M 0x01 +#define DESC90_RATE5_5M 0x02 +#define DESC90_RATE11M 0x03 +#define DESC90_RATE6M 0x04 +#define DESC90_RATE9M 0x05 +#define DESC90_RATE12M 0x06 +#define DESC90_RATE18M 0x07 +#define DESC90_RATE24M 0x08 +#define DESC90_RATE36M 0x09 +#define DESC90_RATE48M 0x0a +#define DESC90_RATE54M 0x0b +#define DESC90_RATEMCS0 0x00 +#define DESC90_RATEMCS1 0x01 +#define DESC90_RATEMCS2 0x02 +#define DESC90_RATEMCS3 0x03 +#define DESC90_RATEMCS4 0x04 +#define DESC90_RATEMCS5 0x05 +#define DESC90_RATEMCS6 0x06 +#define DESC90_RATEMCS7 0x07 +#define DESC90_RATEMCS8 0x08 +#define DESC90_RATEMCS9 0x09 +#define DESC90_RATEMCS10 0x0a +#define DESC90_RATEMCS11 0x0b +#define DESC90_RATEMCS12 0x0c +#define DESC90_RATEMCS13 0x0d +#define DESC90_RATEMCS14 0x0e +#define DESC90_RATEMCS15 0x0f +#define DESC90_RATEMCS32 0x20 + +#define RTL819X_DEFAULT_RF_TYPE RF_1T2R +#define EEPROM_Default_LegacyHTTxPowerDiff 0x4 +#define IEEE80211_WATCH_DOG_TIME 2000 + +/* For rtl819x */ +typedef struct _tx_desc_819x_pci { + //DWORD 0 + u16 PktSize; + u8 Offset; + u8 Reserved1:3; + u8 CmdInit:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 LINIP:1; + u8 OWN:1; + + //DWORD 1 + u8 TxFWInfoSize; + u8 RATid:3; + u8 DISFB:1; + u8 USERATE:1; + u8 MOREFRAG:1; + u8 NoEnc:1; + u8 PIFS:1; + u8 QueueSelect:5; + u8 NoACM:1; + u8 Resv:2; + u8 SecCAMID:5; + u8 SecDescAssign:1; + u8 SecType:2; + + //DWORD 2 + u16 TxBufferSize; + u8 PktId:7; + u8 Resv1:1; + u8 Reserved2; + + //DWORD 3 + u32 TxBuffAddr; + + //DWORD 4 + u32 NextDescAddress; + + //DWORD 5,6,7 + u32 Reserved5; + u32 Reserved6; + u32 Reserved7; +}tx_desc_819x_pci, *ptx_desc_819x_pci; + + +typedef struct _tx_desc_cmd_819x_pci { + //DWORD 0 + u16 PktSize; + u8 Reserved1; + u8 CmdType:3; + u8 CmdInit:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 LINIP:1; + u8 OWN:1; + + //DOWRD 1 + u16 ElementReport; + u16 Reserved2; + + //DOWRD 2 + u16 TxBufferSize; + u16 Reserved3; + + //DWORD 3,4,5 + u32 TxBufferAddr; + u32 NextDescAddress; + u32 Reserved4; + u32 Reserved5; + u32 Reserved6; +}tx_desc_cmd_819x_pci, *ptx_desc_cmd_819x_pci; + + +typedef struct _tx_fwinfo_819x_pci { + //DOWRD 0 + u8 TxRate:7; + u8 CtsEnable:1; + u8 RtsRate:7; + u8 RtsEnable:1; + u8 TxHT:1; + u8 Short:1; //Short PLCP for CCK, or short GI for 11n MCS + u8 TxBandwidth:1; // This is used for HT MCS rate only. + u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. + u8 STBC:2; + u8 AllowAggregation:1; + u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate + u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS + u8 RtsBandwidth:1; // This is used for HT MCS rate only. + u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. + u8 RtsSTBC:2; + u8 EnableCPUDur:1; //Enable firmware to recalculate and assign packet duration + + //DWORD 1 + u8 RxMF:2; + u8 RxAMD:3; + u8 Reserved1:3; + u8 Reserved2; + u8 Reserved3; + u8 Reserved4; + + //u32 Reserved; +}tx_fwinfo_819x_pci, *ptx_fwinfo_819x_pci; + +typedef struct rtl8192_rx_info { + struct urb *urb; + struct net_device *dev; + u8 out_pipe; +}rtl8192_rx_info ; +typedef struct _rx_desc_819x_pci{ + //DOWRD 0 + u16 Length:14; + u16 CRC32:1; + u16 ICV:1; + u8 RxDrvInfoSize; + u8 Shift:2; + u8 PHYStatus:1; + u8 SWDec:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 EOR:1; + u8 OWN:1; + + //DWORD 1 + u32 Reserved2; + + //DWORD 2 + u32 Reserved3; + + //DWORD 3 + u32 BufferAddress; + +}rx_desc_819x_pci, *prx_desc_819x_pci; + +typedef struct _rx_fwinfo_819x_pci{ + //DWORD 0 + u16 Reserved1:12; + u16 PartAggr:1; + u16 FirstAGGR:1; + u16 Reserved2:2; + + u8 RxRate:7; + u8 RxHT:1; + + u8 BW:1; + u8 SPLCP:1; + u8 Reserved3:2; + u8 PAM:1; + u8 Mcast:1; + u8 Bcast:1; + u8 Reserved4:1; + + //DWORD 1 + u32 TSFL; + +}rx_fwinfo_819x_pci, *prx_fwinfo_819x_pci; + +#define MAX_DEV_ADDR_SIZE 8 /* support till 64 bit bus width OS */ +#define MAX_FIRMWARE_INFORMATION_SIZE 32 /*2006/04/30 by Emily forRTL8190*/ +#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) +#define ENCRYPTION_MAX_OVERHEAD 128 +//#define USB_HWDESC_HEADER_LEN sizeof(tx_desc_819x_usb) +//#define TX_PACKET_SHIFT_BYTES (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb)) +#define MAX_FRAGMENT_COUNT 8 +#define MAX_TRANSMIT_BUFFER_SIZE (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT) + +#define scrclng 4 // octets for crc32 (FCS, ICV) +/* 8190 Loopback Mode definition */ +typedef enum _rtl819x_loopback{ + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}rtl819x_loopback_e; + +/* due to rtl8192 firmware */ +typedef enum _desc_packet_type_e{ + DESC_PACKET_TYPE_INIT = 0, + DESC_PACKET_TYPE_NORMAL = 1, +}desc_packet_type_e; + +typedef enum _firmware_source{ + FW_SOURCE_IMG_FILE = 0, + FW_SOURCE_HEADER_FILE = 1, //from header file +}firmware_source_e, *pfirmware_source_e; + +typedef enum _firmware_status{ + FW_STATUS_0_INIT = 0, + FW_STATUS_1_MOVE_BOOT_CODE = 1, + FW_STATUS_2_MOVE_MAIN_CODE = 2, + FW_STATUS_3_TURNON_CPU = 3, + FW_STATUS_4_MOVE_DATA_CODE = 4, + FW_STATUS_5_READY = 5, +}firmware_status_e; + +typedef struct _rt_firmare_seg_container { + u16 seg_size; + u8 *seg_ptr; +}fw_seg_container, *pfw_seg_container; + +typedef struct _rt_firmware{ + firmware_status_e firmware_status; + u16 cmdpacket_frag_thresold; +#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k +#define MAX_FW_INIT_STEP 3 + u8 firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE]; + u16 firmware_buf_size[MAX_FW_INIT_STEP]; +}rt_firmware, *prt_firmware; +//+by amy 080507 +#define MAX_RECEIVE_BUFFER_SIZE 9100 // Add this to 9100 bytes to receive A-MSDU from RT-AP + +/* Firmware Queue Layout */ +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd +#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000 +#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00 +#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08 +#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10 +#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18 +#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10 +#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT 0x08 +#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 +#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 + +//8187B Security +//#define RWCAM 0xA0 // Software read/write CAM config +//#define WCAMI 0xA4 // Software write CAM input content +//#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting +#define DCAM 0xAC // Debug CAM Interface +#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06. + + +#define CAM_CONTENT_COUNT 8 +//#define CFG_DEFAULT_KEY BIT5 +#define CFG_VALID BIT15 +#if 0 +//---------------------------------------------------------------------------- +// 8187B WPA Config Register (offset 0xb0, 1 byte) +//---------------------------------------------------------------------------- +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 + +//---------------------------------------------------------------------------- +// 8187B CAM Config Setting (offset 0xb0, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID 0x8000 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK 0x0020 + + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +//#define CAM_SIZE 16 +#define TOTAL_CAM_ENTRY 16 +#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25. +#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u32)) // 24, unit: in u1byte. Added by Annie, 2006-05-25. + +#define CAM_CONFIG_USEDK 1 +#define CAM_CONFIG_NO_USEDK 0 + +#define CAM_WRITE 0x00010000 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG 0x80000000 + +//================================================================= +//================================================================= + +#endif +#define EPROM_93c46 0 +#define EPROM_93c56 1 + +#define DEFAULT_FRAG_THRESHOLD 2342U +#define MIN_FRAG_THRESHOLD 256U +#define DEFAULT_BEACONINTERVAL 0x64U +#define DEFAULT_BEACON_ESSID "Rtl819xU" + +#define DEFAULT_SSID "" +#define DEFAULT_RETRY_RTS 7 +#define DEFAULT_RETRY_DATA 7 +#define PRISM_HDR_SIZE 64 + +#define PHY_RSSI_SLID_WIN_MAX 100 + + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20 +} WIRELESS_MODE; + +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 + +typedef struct buffer +{ + struct buffer *next; + u32 *buf; + dma_addr_t dma; + +} buffer; + +typedef struct rtl_reg_debug{ + unsigned int cmd; + struct { + unsigned char type; + unsigned char addr; + unsigned char page; + unsigned char length; + } head; + unsigned char buf[0xff]; +}rtl_reg_debug; + +#if 0 + +typedef struct tx_pendingbuf +{ + struct ieee80211_txb *txb; + short ispending; + short descfrag; +} tx_pendigbuf; + +#endif + +typedef struct _rt_9x_tx_rate_history { + u32 cck[4]; + u32 ofdm[8]; + // HT_MCS[0][]: BW=0 SG=0 + // HT_MCS[1][]: BW=1 SG=0 + // HT_MCS[2][]: BW=0 SG=1 + // HT_MCS[3][]: BW=1 SG=1 + u32 ht_mcs[4][16]; +}rt_tx_rahis_t, *prt_tx_rahis_t; + +typedef struct _RT_SMOOTH_DATA_4RF { + char elements[4][100];//array to store values + u32 index; //index to current array to store + u32 TotalNum; //num of valid elements + u32 TotalVal[4]; //sum of valid elements +}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF; + +typedef enum _tag_TxCmd_Config_Index{ + TXCMD_TXRA_HISTORY_CTRL = 0xFF900000, + TXCMD_RESET_TX_PKT_BUFF = 0xFF900001, + TXCMD_RESET_RX_PKT_BUFF = 0xFF900002, + TXCMD_SET_TX_DURATION = 0xFF900003, + TXCMD_SET_RX_RSSI = 0xFF900004, + TXCMD_SET_TX_PWR_TRACKING = 0xFF900005, + TXCMD_XXXX_CTRL, +}DCMD_TXCMD_OP; + +typedef struct Stats +{ + unsigned long txrdu; + unsigned long rxrdu; + //unsigned long rxnolast; + //unsigned long rxnodata; +// unsigned long rxreset; +// unsigned long rxnopointer; + unsigned long rxok; + unsigned long rxframgment; + unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query + unsigned long rxurberr; + unsigned long rxstaterr; + unsigned long rxcrcerrmin;//crc error (0-500) + unsigned long rxcrcerrmid;//crc error (500-1000) + unsigned long rxcrcerrmax;//crc error (>1000) + unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa + unsigned long received_preamble_GI[2][32]; //0: Long preamble/GI, 1:Short preamble/GI + unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K) + unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40) + unsigned long numpacket_matchbssid; // debug use only. + unsigned long numpacket_toself; // debug use only. + unsigned long num_process_phyinfo; // debug use only. + unsigned long numqry_phystatus; + unsigned long numqry_phystatusCCK; + unsigned long numqry_phystatusHT; + unsigned long received_bwtype[5]; //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate + unsigned long txnperr; + unsigned long txnpdrop; + unsigned long txresumed; +// unsigned long rxerr; + unsigned long rxoverflow; + unsigned long rxint; + unsigned long txnpokint; +// unsigned long txhpokint; +// unsigned long txhperr; + unsigned long ints; + unsigned long shints; + unsigned long txoverflow; +// unsigned long rxdmafail; +// unsigned long txbeacon; +// unsigned long txbeaconerr; + unsigned long txlpokint; + unsigned long txlpdrop; + unsigned long txlperr; + unsigned long txbeokint; + unsigned long txbedrop; + unsigned long txbeerr; + unsigned long txbkokint; + unsigned long txbkdrop; + unsigned long txbkerr; + unsigned long txviokint; + unsigned long txvidrop; + unsigned long txvierr; + unsigned long txvookint; + unsigned long txvodrop; + unsigned long txvoerr; + unsigned long txbeaconokint; + unsigned long txbeacondrop; + unsigned long txbeaconerr; + unsigned long txmanageokint; + unsigned long txmanagedrop; + unsigned long txmanageerr; + unsigned long txcmdpktokint; + unsigned long txdatapkt; + unsigned long txfeedback; + unsigned long txfeedbackok; + unsigned long txoktotal; + unsigned long txokbytestotal; + unsigned long txokinperiod; + unsigned long txmulticast; + unsigned long txbytesmulticast; + unsigned long txbroadcast; + unsigned long txbytesbroadcast; + unsigned long txunicast; + unsigned long txbytesunicast; + unsigned long rxbytesunicast; + unsigned long txfeedbackfail; + unsigned long txerrtotal; + unsigned long txerrbytestotal; + unsigned long txerrmulticast; + unsigned long txerrbroadcast; + unsigned long txerrunicast; + unsigned long txretrycount; + unsigned long txfeedbackretry; + u8 last_packet_rate; + unsigned long slide_signal_strength[100]; + unsigned long slide_evm[100]; + unsigned long slide_rssi_total; // For recording sliding window's RSSI value + unsigned long slide_evm_total; // For recording sliding window's EVM value + long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct. + long signal_quality; + long last_signal_strength_inpercent; + long recv_signal_power; // Correct smoothed ss in Dbm, only used in driver to report real power now. + u8 rx_rssi_percentage[4]; + u8 rx_evm_percentage[2]; + long rxSNRdB[4]; + rt_tx_rahis_t txrate; + u32 Slide_Beacon_pwdb[100]; //cosa add for beacon rssi + u32 Slide_Beacon_Total; //cosa add for beacon rssi + RT_SMOOTH_DATA_4RF cck_adc_pwdb; + u32 CurrentShowTxate; + + +} Stats; + + +// Bandwidth Offset +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +//+by amy 080507 + +typedef struct ChnlAccessSetting { + u16 SIFS_Timer; + u16 DIFS_Timer; + u16 SlotTimeTimer; + u16 EIFS_Timer; + u16 CWminIndex; + u16 CWmaxIndex; +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING; + +typedef struct _BB_REGISTER_DEFINITION{ + u32 rfintfs; // set software control: // 0x870~0x877[8 bytes] + u32 rfintfi; // readback data: // 0x8e0~0x8e7[8 bytes] + u32 rfintfo; // output data: // 0x860~0x86f [16 bytes] + u32 rfintfe; // output enable: // 0x860~0x86f [16 bytes] + u32 rf3wireOffset; // LSSI data: // 0x840~0x84f [16 bytes] + u32 rfLSSI_Select; // BB Band Select: // 0x878~0x87f [8 bytes] + u32 rfTxGainStage; // Tx gain stage: // 0x80c~0x80f [4 bytes] + u32 rfHSSIPara1; // wire parameter control1 : // 0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes] + u32 rfHSSIPara2; // wire parameter control2 : // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] + u32 rfSwitchControl; //Tx Rx antenna control : // 0x858~0x85f [16 bytes] + u32 rfAGCControl1; //AGC parameter control1 : // 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] + u32 rfAGCControl2; //AGC parameter control2 : // 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] + u32 rfRxIQImbalance; //OFDM Rx IQ imbalance matrix : // 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] + u32 rfRxAFE; //Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : // 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes] + u32 rfTxIQImbalance; //OFDM Tx IQ imbalance matrix // 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes] + u32 rfTxAFE; //Tx IQ DC Offset and Tx DFIR type // 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] + u32 rfLSSIReadBack; //LSSI RF readback data // 0x8a0~0x8af [16 bytes] +}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; + +typedef enum _RT_RF_TYPE_819xU{ + RF_TYPE_MIN = 0, + RF_8225, + RF_8256, + RF_8258, + RF_PSEUDO_11N = 4, +}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU; + + +typedef struct _rate_adaptive +{ + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40M; + u32 low_rssi_thresh_for_ra40M; + u8 low2high_rssi_thresh_for_ra20M; + u32 low_rssi_thresh_for_ra20M; + u32 upper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40M; + u32 low_rssi_threshold_ratr_20M; + u8 ping_rssi_enable; //cosa add for test + u32 ping_rssi_ratr; //cosa add for test + u32 ping_rssi_thresh_for_ra;//cosa add for test + u32 last_ratr; + +} rate_adaptive, *prate_adaptive; +#define TxBBGainTableLength 37 +#define CCKTxBBGainTableLength 23 +typedef struct _txbbgain_struct +{ + long txbb_iq_amplifygain; + u32 txbbgain_value; +} txbbgain_struct, *ptxbbgain_struct; + +typedef struct _ccktxbbgain_struct +{ + //The Value is from a22 to a29 one Byte one time is much Safer + u8 ccktxbb_valuearray[8]; +} ccktxbbgain_struct,*pccktxbbgain_struct; + + +typedef struct _init_gain +{ + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +} init_gain, *pinit_gain; + +/* 2007/11/02 MH Define RF mode temporarily for test. */ +typedef enum tag_Rf_Operatetion_State +{ + RF_STEP_INIT = 0, + RF_STEP_NORMAL, + RF_STEP_MAX +}RF_STEP_E; + +typedef enum _RT_STATUS{ + RT_STATUS_SUCCESS, + RT_STATUS_FAILURE, + RT_STATUS_PENDING, + RT_STATUS_RESOURCE +}RT_STATUS,*PRT_STATUS; + +typedef enum _RT_CUSTOMER_ID +{ + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31. + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, +}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; + +//================================================================================ +// LED customization. +//================================================================================ + +typedef enum _LED_STRATEGY_8190{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // SW control for PCI Express + SW_LED_MODE2, // SW control for Cameo. + SW_LED_MODE3, // SW contorl for RunTop. + SW_LED_MODE4, // SW control for Netcore + SW_LED_MODE5, //added by vivi, for led new mode, DLINK + SW_LED_MODE6, //added by vivi, for led new mode, PRONET + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) +}LED_STRATEGY_8190, *PLED_STRATEGY_8190; + +#define CHANNEL_PLAN_LEN 10 + +#define sCrcLng 4 + +typedef struct _TX_FWINFO_STRUCUTRE{ + //DOWRD 0 + u8 TxRate:7; + u8 CtsEnable:1; + u8 RtsRate:7; + u8 RtsEnable:1; + u8 TxHT:1; + u8 Short:1; + u8 TxBandwidth:1; + u8 TxSubCarrier:2; + u8 STBC:2; + u8 AllowAggregation:1; + u8 RtsHT:1; + u8 RtsShort:1; + u8 RtsBandwidth:1; + u8 RtsSubcarrier:2; + u8 RtsSTBC:2; + u8 EnableCPUDur:1; + + //DWORD 1 + u32 RxMF:2; + u32 RxAMD:3; + u32 Reserved1:3; + u32 TxAGCOffset:4; + u32 TxAGCSign:1; + u32 Tx_INFO_RSVD:6; + u32 PacketID:13; +}TX_FWINFO_T; + + +typedef struct _TX_FWINFO_8190PCI{ + //DOWRD 0 + u8 TxRate:7; + u8 CtsEnable:1; + u8 RtsRate:7; + u8 RtsEnable:1; + u8 TxHT:1; + u8 Short:1; //Short PLCP for CCK, or short GI for 11n MCS + u8 TxBandwidth:1; // This is used for HT MCS rate only. + u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. + u8 STBC:2; + u8 AllowAggregation:1; + u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate + u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS + u8 RtsBandwidth:1; // This is used for HT MCS rate only. + u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. + u8 RtsSTBC:2; + u8 EnableCPUDur:1; //Enable firmware to recalculate and assign packet duration + + //DWORD 1 + u32 RxMF:2; + u32 RxAMD:3; + u32 TxPerPktInfoFeedback:1; // 1: indicate that the transimission info of this packet should be gathered by Firmware and retured by Rx Cmd. + u32 Reserved1:2; + u32 TxAGCOffset:4; // Only 90 support + u32 TxAGCSign:1; // Only 90 support + u32 RAW_TXD:1; // MAC will send data in txpktbuffer without any processing,such as CRC check + u32 Retry_Limit:4; // CCX Support relative retry limit FW page only support 4 bits now. + u32 Reserved2:1; + u32 PacketID:13; + + // DW 2 + +}TX_FWINFO_8190PCI, *PTX_FWINFO_8190PCI; + +typedef struct _phy_ofdm_rx_status_report_819xpci +{ + u8 trsw_gain_X[4]; + u8 pwdb_all; + u8 cfosho_X[4]; + u8 cfotail_X[4]; + u8 rxevm_X[2]; + u8 rxsnr_X[4]; + u8 pdsnr_X[2]; + u8 csi_current_X[2]; + u8 csi_target_X[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 sgi_en; + u8 rxsc_sgien_exflg; +}phy_sts_ofdm_819xpci_t; + +typedef struct _phy_cck_rx_status_report_819xpci +{ + /* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend + 0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */ + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}phy_sts_cck_819xpci_t; + +typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{ + u8 reserved:4; + u8 rxsc:2; + u8 sgi_en:1; + u8 ex_intf_flag:1; +}phy_ofdm_rx_status_rxsc_sgien_exintfflag; + +typedef enum _RT_OP_MODE{ + RT_OP_MODE_AP, + RT_OP_MODE_INFRASTRUCTURE, + RT_OP_MODE_IBSS, + RT_OP_MODE_NO_LINK, +}RT_OP_MODE, *PRT_OP_MODE; + + +/* 2007/11/02 MH Define RF mode temporarily for test. */ +typedef enum tag_Rf_OpType +{ + RF_OP_By_SW_3wire = 0, + RF_OP_By_FW, + RF_OP_MAX +}RF_OpType_E; + +typedef enum _RESET_TYPE { + RESET_TYPE_NORESET = 0x00, + RESET_TYPE_NORMAL = 0x01, + RESET_TYPE_SILENT = 0x02 +} RESET_TYPE; + +typedef struct _tx_ring{ + u32 * desc; + u8 nStuckCount; + struct _tx_ring * next; +}__attribute__ ((packed)) tx_ring, * ptx_ring; + +struct rtl8192_tx_ring { + tx_desc_819x_pci *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; +}; + +#define NIC_SEND_HANG_THRESHOLD_NORMAL 4 +#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8 +#define MAX_TX_QUEUE 9 // BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. + +#define MAX_RX_COUNT 64 +#define MAX_TX_QUEUE_COUNT 9 + +typedef struct r8192_priv +{ + struct pci_dev *pdev; + //added for maintain info from eeprom + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u8 eeprom_CustomerID; + u16 eeprom_ChannelPlan; + RT_CUSTOMER_ID CustomerID; + LED_STRATEGY_8190 LedStrategy; + //bool bDcut; + u8 IC_Cut; + int irq; + short irq_enabled; + struct ieee80211_device *ieee80211; + bool being_init_adapter; + u8 Rf_Mode; + short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */ + u8 card_8192_version; /* if TCR reports card V B/C this discriminates */ +// short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */ + short enable_gpio0; + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type; + short hw_plcp_len; + short plcp_preamble_mode; + u8 ScanDelay; + spinlock_t irq_lock; + spinlock_t irq_th_lock; + spinlock_t tx_lock; + spinlock_t rf_ps_lock; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + struct semaphore mutex; +#else + struct mutex mutex; +#endif + spinlock_t rf_lock; //used to lock rf write operation added by wb + spinlock_t ps_lock; + + u32 irq_mask; +// short irq_enabled; +// struct net_device *dev; //comment this out. + short chan; + short sens; + short max_sens; + u32 rx_prevlen; +/*RX stuff*/ + rx_desc_819x_pci *rx_ring; + dma_addr_t rx_ring_dma; + unsigned int rx_idx; + struct sk_buff *rx_buf[MAX_RX_COUNT]; + int rxringcount; + u16 rxbuffersize; + + + struct sk_buff *rx_skb; + u32 *rxring; + u32 *rxringtail; + dma_addr_t rxringdma; + struct buffer *rxbuffer; + struct buffer *rxbufferhead; + short rx_skb_complete; +/*TX stuff*/ + struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; + int txringcount; +//{ + int txbuffsize; + int txfwbuffersize; + //struct tx_pendingbuf txnp_pending; + //struct tasklet_struct irq_tx_tasklet; + struct tasklet_struct irq_rx_tasklet; + struct tasklet_struct irq_tx_tasklet; + struct tasklet_struct irq_prepare_beacon_tasklet; + struct buffer *txmapbufs; + struct buffer *txbkpbufs; + struct buffer *txbepbufs; + struct buffer *txvipbufs; + struct buffer *txvopbufs; + struct buffer *txcmdbufs; + struct buffer *txmapbufstail; + struct buffer *txbkpbufstail; + struct buffer *txbepbufstail; + struct buffer *txvipbufstail; + struct buffer *txvopbufstail; + struct buffer *txcmdbufstail; + /* adhoc/master mode stuff */ + ptx_ring txbeaconringtail; + dma_addr_t txbeaconringdma; + ptx_ring txbeaconring; + int txbeaconcount; + struct buffer *txbeaconbufs; + struct buffer *txbeaconbufstail; + ptx_ring txmapring; + ptx_ring txbkpring; + ptx_ring txbepring; + ptx_ring txvipring; + ptx_ring txvopring; + ptx_ring txcmdring; + ptx_ring txmapringtail; + ptx_ring txbkpringtail; + ptx_ring txbepringtail; + ptx_ring txvipringtail; + ptx_ring txvopringtail; + ptx_ring txcmdringtail; + ptx_ring txmapringhead; + ptx_ring txbkpringhead; + ptx_ring txbepringhead; + ptx_ring txvipringhead; + ptx_ring txvopringhead; + ptx_ring txcmdringhead; + dma_addr_t txmapringdma; + dma_addr_t txbkpringdma; + dma_addr_t txbepringdma; + dma_addr_t txvipringdma; + dma_addr_t txvopringdma; + dma_addr_t txcmdringdma; + // u8 chtxpwr[15]; //channels from 1 to 14, 0 not used +// u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used +// u8 cck_txpwr_base; +// u8 ofdm_txpwr_base; +// u8 challow[15]; //channels from 1 to 14, 0 not used + short up; + short crcmon; //if 1 allow bad crc frame reception in monitor mode +// short prism_hdr; + +// struct timer_list scan_timer; + /*short scanpending; + short stopscan;*/ +// spinlock_t scan_lock; +// u8 active_probe; + //u8 active_scan_num; + struct semaphore wx_sem; + struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david +// short hw_wep; + +// short digphy; +// short antb; +// short diversity; +// u8 cs_treshold; +// short rcr_csense; + u8 rf_type; //0 means 1T2R, 1 means 2T4R + RT_RF_TYPE_819xU rf_chip; + +// u32 key0[4]; + short (*rf_set_sens)(struct net_device *dev,short sens); + u8 (*rf_set_chan)(struct net_device *dev,u8 ch); + void (*rf_close)(struct net_device *dev); + void (*rf_init)(struct net_device *dev); + //short rate; + short promisc; + /*stats*/ + struct Stats stats; + struct iw_statistics wstats; + struct proc_dir_entry *dir_dev; + + /*RX stuff*/ +// u32 *rxring; +// u32 *rxringtail; +// dma_addr_t rxringdma; + +#ifdef THOMAS_BEACON + u32 *oldaddr; +#endif +#ifdef THOMAS_TASKLET + atomic_t irt_counter;//count for irq_rx_tasklet +#endif +#ifdef JACKSON_NEW_RX + struct sk_buff **pp_rxskb; + int rx_inx; +#endif + +/* modified by davad for Rx process */ + struct sk_buff_head rx_queue; + struct sk_buff_head skb_queue; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct tq_struct qos_activate; +#else + struct work_struct qos_activate; +#endif + short tx_urb_index; + atomic_t tx_pending[0x10];//UART_PRIORITY+1 + + struct urb *rxurb_task; + + //2 Tx Related variables + u16 ShortRetryLimit; + u16 LongRetryLimit; + u32 TransmitConfig; + u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27. + + u32 LastRxDescTSFHigh; + u32 LastRxDescTSFLow; + + + //2 Rx Related variables + u16 EarlyRxThreshold; + u32 ReceiveConfig; + u8 AcmControl; + + u8 RFProgType; + + u8 retry_data; + u8 retry_rts; + u16 rts; + + struct ChnlAccessSetting ChannelAccessSetting; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct work_struct reset_wq; +#else + struct tq_struct reset_wq; +#endif + +/**********************************************************/ +//for rtl819xPci + // Data Rate Config. Added by Annie, 2006-04-13. + u16 basic_rate; + u8 short_preamble; + u8 slot_time; + u16 SifsTime; +/* WirelessMode*/ + u8 RegWirelessMode; +/*Firmware*/ + prt_firmware pFirmware; + rtl819x_loopback_e LoopbackMode; + firmware_source_e firmware_source; + bool AutoloadFailFlag; + u16 EEPROMTxPowerDiff; + u16 EEPROMAntPwDiff; // Antenna gain offset from B/C/D to A + u8 EEPROMThermalMeter; + u8 EEPROMPwDiff; + u8 EEPROMCrystalCap; + u8 EEPROM_Def_Ver; + u8 EEPROMTxPowerLevelCCK[14];// CCK channel 1~14 + // The following definition is for eeprom 93c56 + u8 EEPROMRfACCKChnl1TxPwLevel[3]; //RF-A CCK Tx Power Level at channel 7 + u8 EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 + u8 EEPROMRfCCCKChnl1TxPwLevel[3]; //RF-C CCK Tx Power Level at channel 7 + u8 EEPROMRfCOfdmChnlTxPwLevel[3];//RF-C CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 + u8 EEPROMTxPowerLevelCCK_V1[3]; + u8 EEPROMTxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14 + u8 EEPROMTxPowerLevelOFDM5G[24]; // OFDM 5G + u8 EEPROMLegacyHTTxPowerDiff; // Legacy to HT rate power diff + bool bTXPowerDataReadFromEEPORM; +/*channel plan*/ + u16 RegChannelPlan; // Channel Plan specifed by user, 15: following setting of EEPROM, 0-14: default channel plan index specified by user. + u16 ChannelPlan; +/*PS related*/ + bool RegRfOff; + // Rf off action for power save + u8 bHwRfOffAction; //0:No action, 1:By GPIO, 2:By Disable +/*PHY related*/ + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + // Read/write are allow for following hardware information variables + u32 MCSTxPowerLevelOriginalOffset[6]; + u32 CCKTxPowerLevelOriginalOffset; + u8 TxPowerLevelCCK[14]; // CCK channel 1~14 + u8 TxPowerLevelCCK_A[14]; // RF-A, CCK channel 1~14 + u8 TxPowerLevelCCK_C[14]; + u8 TxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14 + u8 TxPowerLevelOFDM5G[14]; // OFDM 5G + u8 TxPowerLevelOFDM24G_A[14]; // RF-A, OFDM 2.4G channel 1~14 + u8 TxPowerLevelOFDM24G_C[14]; // RF-C, OFDM 2.4G channel 1~14 + u8 LegacyHTTxPowerDiff; // Legacy to HT rate power diff + u8 TxPowerDiff; + char RF_C_TxPwDiff; // Antenna gain offset, rf-c to rf-a + u8 AntennaTxPwDiff[3]; // Antenna gain offset, index 0 for B, 1 for C, and 2 for D + u8 CrystalCap; // CrystalCap. + u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 + //05/27/2008 cck power enlarge + u8 CckPwEnl; + u16 TSSI_13dBm; + u32 Pwr_Track; + u8 CCKPresentAttentuation_20Mdefault; + u8 CCKPresentAttentuation_40Mdefault; + char CCKPresentAttentuation_difference; + char CCKPresentAttentuation; + // Use to calculate PWBD. + u8 bCckHighPower; + long undecorated_smoothed_pwdb; + long undecorated_smoothed_cck_adc_pwdb[4]; + //for set channel + u8 SwChnlInProgress; + u8 SwChnlStage; + u8 SwChnlStep; + u8 SetBWModeInProgress; + HT_CHANNEL_WIDTH CurrentChannelBW; + + // 8190 40MHz mode + // + u8 nCur40MhzPrimeSC; // Control channel sub-carrier + // Joseph test for shorten RF configuration time. + // We save RF reg0 in this variable to reduce RF reading. + // + u32 RfReg0Value[4]; + u8 NumTotalRFPath; + bool brfpath_rxenable[4]; +//+by amy 080507 + struct timer_list watch_dog_timer; + +//+by amy 080515 for dynamic mechenism + //Add by amy Tx Power Control for Near/Far Range 2008/05/15 + bool bdynamic_txpower; //bDynamicTxPower + bool bDynamicTxHighPower; // Tx high power state + bool bDynamicTxLowPower; // Tx low power state + bool bLastDTPFlag_High; + bool bLastDTPFlag_Low; + + bool bstore_last_dtpflag; + bool bstart_txctrl_bydtp; //Define to discriminate on High power State or on sitesuvey to change Tx gain index + //Add by amy for Rate Adaptive + rate_adaptive rate_adaptive; + //Add by amy for TX power tracking + //2008/05/15 Mars OPEN/CLOSE TX POWER TRACKING + txbbgain_struct txbbgain_table[TxBBGainTableLength]; + u8 txpower_count;//For 6 sec do tracking again + bool btxpower_trackingInit; + u8 OFDM_index; + u8 CCK_index; + u8 Record_CCK_20Mindex; + u8 Record_CCK_40Mindex; + //2007/09/10 Mars Add CCK TX Power Tracking + ccktxbbgain_struct cck_txbbgain_table[CCKTxBBGainTableLength]; + ccktxbbgain_struct cck_txbbgain_ch14_table[CCKTxBBGainTableLength]; + u8 rfa_txpowertrackingindex; + u8 rfa_txpowertrackingindex_real; + u8 rfa_txpowertracking_default; + u8 rfc_txpowertrackingindex; + u8 rfc_txpowertrackingindex_real; + u8 rfc_txpowertracking_default; + bool btxpower_tracking; + bool bcck_in_ch14; + + //For Backup Initial Gain + init_gain initgain_backup; + u8 DefaultInitialGain[4]; + // For EDCA Turbo mode, Added by amy 080515. + bool bis_any_nonbepkts; + bool bcurrent_turbo_EDCA; + + bool bis_cur_rdlstate; + struct timer_list fsync_timer; + bool bfsync_processing; // 500ms Fsync timer is active or not + u32 rate_record; + u32 rateCountDiffRecord; + u32 ContiuneDiffCount; + bool bswitch_fsync; + + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + //Added by amy 080516 for RX related + u16 nrxAMPDU_size; + u8 nrxAMPDU_aggr_num; + + /*Last RxDesc TSF value*/ + u32 last_rxdesc_tsf_high; + u32 last_rxdesc_tsf_low; + + //by amy for gpio + bool bHwRadioOff; + //by amy for ps + bool RFChangeInProgress; // RF Chnage in progress, by Bruce, 2007-10-30 + bool SetRFPowerStateInProgress; + RT_OP_MODE OpMode; + //by amy for reset_count + u32 reset_count; + bool bpbc_pressed; + //by amy for debug + u32 txpower_checkcnt; + u32 txpower_tracking_callback_cnt; + u8 thermal_read_val[40]; + u8 thermal_readback_index; + u32 ccktxpower_adjustcnt_not_ch14; + u32 ccktxpower_adjustcnt_ch14; + u8 tx_fwinfo_force_subcarriermode; + u8 tx_fwinfo_force_subcarrierval; + + //by amy for silent reset + RESET_TYPE ResetProgress; + bool bForcedSilentReset; + bool bDisableNormalResetCheck; + u16 TxCounter; + u16 RxCounter; + int IrpPendingCount; + bool bResetInProgress; + bool force_reset; + u8 InitialGainOperateType; + + //define work item by amy 080526 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + struct delayed_work update_beacon_wq; + struct delayed_work watch_dog_wq; + struct delayed_work txpower_tracking_wq; + struct delayed_work rfpath_check_wq; + struct delayed_work gpio_change_rf_wq; + struct delayed_work initialgain_operate_wq; +#else + struct work_struct update_beacon_wq; + struct work_struct watch_dog_wq; + struct work_struct txpower_tracking_wq; + struct work_struct rfpath_check_wq; + struct work_struct gpio_change_rf_wq; + struct work_struct initialgain_operate_wq; +#endif + struct workqueue_struct *priv_wq; +#else + struct tq_struct update_beacon_wq; + /* used for periodly scan */ + struct tq_struct txpower_tracking_wq; + struct tq_struct rfpath_check_wq; + struct tq_struct watch_dog_wq; + struct tq_struct gpio_change_rf_wq; + struct tq_struct initialgain_operate_wq; +#endif +}r8192_priv; + +// for rtl8187 +// now mirging to rtl8187B +/* +typedef enum{ + LOW_PRIORITY = 0x02, + NORM_PRIORITY + } priority_t; +*/ +//for rtl8187B +#if 0 +typedef enum{ + BULK_PRIORITY = 0x01, + //RSVD0, + //RSVD1, + LOW_PRIORITY, + NORM_PRIORITY, + VO_PRIORITY, + VI_PRIORITY, //0x05 + BE_PRIORITY, + BK_PRIORITY, + CMD_PRIORITY,//0x8 + RSVD3, + BEACON_PRIORITY, //0x0A + HIGH_PRIORITY, + MANAGE_PRIORITY, + RSVD4, + RSVD5, + UART_PRIORITY //0x0F +} priority_t; +#endif +typedef enum{ + NIC_8192E = 1, + } nic_t; + + +#if 0 //defined in Qos.h +//typedef u32 AC_CODING; +#define AC0_BE 0 // ACI: 0x00 // Best Effort +#define AC1_BK 1 // ACI: 0x01 // Background +#define AC2_VI 2 // ACI: 0x10 // Video +#define AC3_VO 3 // ACI: 0x11 // Voice +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum. + +// +// ECWmin/ECWmax field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. +// +typedef union _ECW{ + u8 charData; + struct + { + u8 ECWmin:4; + u8 ECWmax:4; + }f; // Field +}ECW, *PECW; + +// +// ACI/AIFSN Field. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _ACI_AIFSN{ + u8 charData; + + struct + { + u8 AIFSN:4; + u8 ACM:1; + u8 ACI:2; + u8 Reserved:1; + }f; // Field +}ACI_AIFSN, *PACI_AIFSN; + +// +// AC Parameters Record Format. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. +// +typedef union _AC_PARAM{ + u32 longData; + u8 charData[4]; + + struct + { + ACI_AIFSN AciAifsn; + ECW Ecw; + u16 TXOPLimit; + }f; // Field +}AC_PARAM, *PAC_PARAM; + +#endif +bool init_firmware(struct net_device *dev); +void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); +short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); +u32 read_cam(struct net_device *dev, u8 addr); +void write_cam(struct net_device *dev, u8 addr, u32 data); +u8 read_nic_byte(struct net_device *dev, int x); +u8 read_nic_byte_E(struct net_device *dev, int x); +u32 read_nic_dword(struct net_device *dev, int x); +u16 read_nic_word(struct net_device *dev, int x) ; +void write_nic_byte(struct net_device *dev, int x,u8 y); +void write_nic_byte_E(struct net_device *dev, int x,u8 y); +void write_nic_word(struct net_device *dev, int x,u16 y); +void write_nic_dword(struct net_device *dev, int x,u32 y); +void force_pci_posting(struct net_device *dev); + +void rtl8192_rtx_disable(struct net_device *); +void rtl8192_rx_enable(struct net_device *); +void rtl8192_tx_enable(struct net_device *); + +void rtl8192_disassociate(struct net_device *dev); +//void fix_rx_fifo(struct net_device *dev); +void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a); + +void rtl8192_set_anaparam(struct net_device *dev,u32 a); +void rtl8185_set_anaparam2(struct net_device *dev,u32 a); +void rtl8192_update_msr(struct net_device *dev); +int rtl8192_down(struct net_device *dev); +int rtl8192_up(struct net_device *dev); +void rtl8192_commit(struct net_device *dev); +void rtl8192_set_chan(struct net_device *dev,short ch); +void write_phy(struct net_device *dev, u8 adr, u8 data); +void write_phy_cck(struct net_device *dev, u8 adr, u32 data); +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); +void rtl8185_tx_antenna(struct net_device *dev, u8 ant); +void rtl8187_set_rxconf(struct net_device *dev); +//short check_nic_enough_desc(struct net_device *dev, priority_t priority); +void rtl8192_start_beacon(struct net_device *dev); +void CamResetAllEntry(struct net_device* dev); +void EnableHWSecurityConfig8192(struct net_device *dev); +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); +void CamPrintDbgReg(struct net_device* dev); +extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); +extern void firmware_init_param(struct net_device *dev); +extern RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8192_hw_wakeup_wq (struct work_struct *work); +#else +void rtl8192_hw_wakeup_wq(struct net_device *dev); +#endif + +short rtl8192_is_tx_queue_empty(struct net_device *dev); +#ifdef ENABLE_IPS +void IPSEnter(struct net_device *dev); +void IPSLeave(struct net_device *dev); +#endif +#endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c new file mode 100644 index 00000000000..abb6b49ca34 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -0,0 +1,7192 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * Linux device driver for RTL8190P / RTL8192E + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello , et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Jerry chuang + */ + +#ifndef CONFIG_FORCE_HARD_FLOAT +double __floatsidf (int i) { return i; } +unsigned int __fixunsdfsi (double d) { return d; } +double __adddf3(double a, double b) { return a+b; } +double __addsf3(float a, float b) { return a+b; } +double __subdf3(double a, double b) { return a-b; } +double __extendsfdf2(float a) {return a;} +#endif + +#undef LOOP_TEST +#undef RX_DONT_PASS_UL +#undef DEBUG_EPROM +#undef DEBUG_RX_VERBOSE +#undef DUMMY_RX +#undef DEBUG_ZERO_RX +#undef DEBUG_RX_SKB +#undef DEBUG_TX_FRAG +#undef DEBUG_RX_FRAG +#undef DEBUG_TX_FILLDESC +#undef DEBUG_TX +#undef DEBUG_IRQ +#undef DEBUG_RX +#undef DEBUG_RXALLOC +#undef DEBUG_REGISTERS +#undef DEBUG_RING +#undef DEBUG_IRQ_TASKLET +#undef DEBUG_TX_ALLOC +#undef DEBUG_TX_DESC + +//#define CONFIG_RTL8192_IO_MAP +#include +#include "r8192E_hw.h" +#include "r8192E.h" +#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */ +#include "r8180_93cx6.h" /* Card EEPROM */ +#include "r8192E_wx.h" +#include "r819xE_phy.h" //added by WB 4.30.2008 +#include "r819xE_phyreg.h" +#include "r819xE_cmdpkt.h" +#include "r8192E_dm.h" +//#include "r8192xU_phyreg.h" +//#include +// FIXME: check if 2.6.7 is ok + +#ifdef CONFIG_PM_RTL +#include "r8192_pm.h" +#endif + +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +//set here to open your trace code. //WB +u32 rt_global_debug_component = \ + // COMP_INIT | + // COMP_EPROM | + // COMP_PHY | + // COMP_RF | + COMP_FIRMWARE | + // COMP_TRACE | + // COMP_DOWN | + // COMP_SWBW | + // COMP_SEC | +// COMP_QOS | +// COMP_RATE | + // COMP_RECV | + // COMP_SEND | + // COMP_POWER | + // COMP_EVENTS | + // COMP_RESET | + // COMP_CMDPKT | + // COMP_POWER_TRACKING | + // COMP_INTR | + COMP_ERR ; //always open err flags on +#ifndef PCI_DEVICE +#define PCI_DEVICE(vend,dev)\ + .vendor=(vend),.device=(dev),\ + .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID +#endif +static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { +#ifdef RTL8190P + /* Realtek */ + /* Dlink */ + { PCI_DEVICE(0x10ec, 0x8190) }, + /* Corega */ + { PCI_DEVICE(0x07aa, 0x0045) }, + { PCI_DEVICE(0x07aa, 0x0046) }, +#else + /* Realtek */ + { PCI_DEVICE(0x10ec, 0x8192) }, + + /* Corega */ + { PCI_DEVICE(0x07aa, 0x0044) }, + { PCI_DEVICE(0x07aa, 0x0047) }, +#endif + {} +}; + +static char* ifname = "wlan%d"; +#if 0 +static int hwseqnum = 0; +static int hwwep = 0; +#endif +static int hwwep = 1; //default use hw. set 0 to use software security +static int channels = 0x3fff; + +MODULE_LICENSE("GPL"); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +MODULE_VERSION("V 1.1"); +#endif +MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); +//MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); + +#if 0 +MODULE_PARM(ifname,"s"); +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default"); + +MODULE_PARM(hwseqnum,"i"); +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default"); + +MODULE_PARM(hwwep,"i"); +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); + +MODULE_PARM(channels,"i"); +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) +module_param(ifname, charp, S_IRUGO|S_IWUSR ); +//module_param(hwseqnum,int, S_IRUGO|S_IWUSR); +module_param(hwwep,int, S_IRUGO|S_IWUSR); +module_param(channels,int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(ifname, "s"); +//MODULE_PARM(hwseqnum,"i"); +MODULE_PARM(hwwep,"i"); +MODULE_PARM(channels,"i"); +#endif + +MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default"); +//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default"); +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); + +static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev); + +static struct pci_driver rtl8192_pci_driver = { + .name = RTL819xE_MODULE_NAME, /* Driver name */ + .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ + .probe = rtl8192_pci_probe, /* probe fn */ + .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) +#ifdef CONFIG_PM_RTL + .suspend = rtl8192E_suspend, /* PM suspend fn */ + .resume = rtl8192E_resume, /* PM resume fn */ +#else + .suspend = NULL, /* PM suspend fn */ + .resume = NULL, /* PM resume fn */ +#endif +#endif +}; + +#ifdef ENABLE_DOT11D + +typedef struct _CHANNEL_LIST +{ + u8 Channel[32]; + u8 Len; +}CHANNEL_LIST, *PCHANNEL_LIST; + +static CHANNEL_LIST ChannelPlan[] = { + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI. + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1 + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 +}; + +static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) +{ + int i, max_chan=-1, min_chan=-1; + struct ieee80211_device* ieee = priv->ieee80211; + switch (channel_plan) + { + case COUNTRY_CODE_FCC: + case COUNTRY_CODE_IC: + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_ISRAEL: + case COUNTRY_CODE_TELEC: + case COUNTRY_CODE_MIC: + { + Dot11d_Init(ieee); + ieee->bGlobalDomain = false; + //acturally 8225 & 8256 rf chip only support B,G,24N mode + if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) + { + min_chan = 1; + max_chan = 14; + } + else + { + RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__); + } + if (ChannelPlan[channel_plan].Len != 0){ + // Clear old channel map + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); + // Set new channel map + for (i=0;i max_chan) + break; + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1; + } + } + break; + } + case COUNTRY_CODE_GLOBAL_DOMAIN: + { + GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting + Dot11d_Reset(ieee); + ieee->bGlobalDomain = true; + break; + } + default: + break; + } +} +#endif + + +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +/* 2007/07/25 MH Defien temp tx fw info. */ +TX_FWINFO_T Tmp_TxFwInfo; + + +#define rx_hal_is_cck_rate(_pdrvinfo)\ + (_pdrvinfo->RxRate == DESC90_RATE1M ||\ + _pdrvinfo->RxRate == DESC90_RATE2M ||\ + _pdrvinfo->RxRate == DESC90_RATE5_5M ||\ + _pdrvinfo->RxRate == DESC90_RATE11M) &&\ + !_pdrvinfo->RxHT\ + + +void CamResetAllEntry(struct net_device *dev) +{ + //u8 ucIndex; + u32 ulcommand = 0; + +#if 1 + ulcommand |= BIT31|BIT30; + write_nic_dword(dev, RWCAM, ulcommand); +#else + for(ucIndex=0;ucIndexbase_addr +x); +} + +u32 read_nic_dword(struct net_device *dev, int x) +{ + return inl(dev->base_addr +x); +} + +u16 read_nic_word(struct net_device *dev, int x) +{ + return inw(dev->base_addr +x); +} + +void write_nic_byte(struct net_device *dev, int x,u8 y) +{ + outb(y&0xff,dev->base_addr +x); +} + +void write_nic_word(struct net_device *dev, int x,u16 y) +{ + outw(y,dev->base_addr +x); +} + +void write_nic_dword(struct net_device *dev, int x,u32 y) +{ + outl(y,dev->base_addr +x); +} + +#else /* RTL_IO_MAP */ + +u8 read_nic_byte(struct net_device *dev, int x) +{ + return 0xff&readb((u8*)dev->mem_start +x); +} + +u32 read_nic_dword(struct net_device *dev, int x) +{ + return readl((u8*)dev->mem_start +x); +} + +u16 read_nic_word(struct net_device *dev, int x) +{ + return readw((u8*)dev->mem_start +x); +} + +void write_nic_byte(struct net_device *dev, int x,u8 y) +{ + writeb(y,(u8*)dev->mem_start +x); + udelay(20); +} + +void write_nic_dword(struct net_device *dev, int x,u32 y) +{ + writel(y,(u8*)dev->mem_start +x); + udelay(20); +} + +void write_nic_word(struct net_device *dev, int x,u16 y) +{ + writew(y,(u8*)dev->mem_start +x); + udelay(20); +} + +#endif /* RTL_IO_MAP */ + + +/////////////////////////////////////////////////////////// + +//u8 read_phy_cck(struct net_device *dev, u8 adr); +//u8 read_phy_ofdm(struct net_device *dev, u8 adr); +/* this might still called in what was the PHY rtl8185/rtl8192 common code + * plans are to possibilty turn it again in one common code... + */ +inline void force_pci_posting(struct net_device *dev) +{ +} + + +//warning message WB +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs); +#else +irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs); +#endif +#else +irqreturn_t rtl8192_interrupt(int irq, void *netdev); +#endif +//static struct net_device_stats *rtl8192_stats(struct net_device *dev); +void rtl8192_commit(struct net_device *dev); +//void rtl8192_restart(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8192_restart(struct work_struct *work); +//void rtl8192_rq_tx_ack(struct work_struct *work); +#else + void rtl8192_restart(struct net_device *dev); +// //void rtl8192_rq_tx_ack(struct net_device *dev); + #endif + +void watch_dog_timer_callback(unsigned long data); +#ifdef ENABLE_IPS +void IPSEnter(struct net_device *dev); +void IPSLeave(struct net_device *dev); +void InactivePsWorkItemCallback(struct net_device *dev); +#endif +/**************************************************************************** + -----------------------------PROCFS STUFF------------------------- +*****************************************************************************/ + +static struct proc_dir_entry *rtl8192_proc = NULL; + + + +static int proc_get_stats_ap(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + struct ieee80211_network *target; + + int len = 0; + + list_for_each_entry(target, &ieee->network_list, list) { + + len += snprintf(page + len, count - len, + "%s ", target->ssid); + + if(target->wpa_ie_len>0 || target->rsn_ie_len>0){ + len += snprintf(page + len, count - len, + "WPA\n"); + } + else{ + len += snprintf(page + len, count - len, + "non_WPA\n"); + } + + } + + *eof = 1; + return len; +} + +static int proc_get_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; +// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + int i,n; + + int max=0xff; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page 0##################\n "); + + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); + len += snprintf(page + len, count - len, + "\n####################page 1##################\n "); + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,0x100|n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + + len += snprintf(page + len, count - len, + "\n####################page 3##################\n "); + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_nic_byte(dev,0x300|n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + + + *eof = 1; + return len; + +} + + +#if 0 +static int proc_get_cck_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; +// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + int i,n; + + int max = 0x5F; + + /* This dump the current register page */ + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_phy_cck(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); + + + *eof = 1; + return len; +} + +#endif + +#if 0 +static int proc_get_ofdm_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + + struct net_device *dev = data; +// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + int i,n; + + //int max=0xff; + int max = 0x40; + + /* This dump the current register page */ + for(n=0;n<=max;) + { + //printk( "\nD: %2x> ", n); + len += snprintf(page + len, count - len, + "\nD: %2x > ",n); + + for(i=0;i<16 && n<=max;i++,n++) + len += snprintf(page + len, count - len, + "%2x ",read_phy_ofdm(dev,n)); + + // printk("%2x ",read_nic_byte(dev,n)); + } + len += snprintf(page + len, count - len,"\n"); + + + + *eof = 1; + return len; +} + +#endif + +#if 0 +static int proc_get_stats_hw(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "NIC int: %lu\n" + "Total int: %lu\n", + priv->stats.ints, + priv->stats.shints); + + *eof = 1; + return len; +} +#endif + +static int proc_get_stats_tx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "TX VI priority ok int: %lu\n" +// "TX VI priority error int: %lu\n" + "TX VO priority ok int: %lu\n" +// "TX VO priority error int: %lu\n" + "TX BE priority ok int: %lu\n" +// "TX BE priority error int: %lu\n" + "TX BK priority ok int: %lu\n" +// "TX BK priority error int: %lu\n" + "TX MANAGE priority ok int: %lu\n" +// "TX MANAGE priority error int: %lu\n" + "TX BEACON priority ok int: %lu\n" + "TX BEACON priority error int: %lu\n" + "TX CMDPKT priority ok int: %lu\n" +// "TX high priority ok int: %lu\n" +// "TX high priority failed error int: %lu\n" +// "TX queue resume: %lu\n" + "TX queue stopped?: %d\n" + "TX fifo overflow: %lu\n" +// "TX beacon: %lu\n" +// "TX VI queue: %d\n" +// "TX VO queue: %d\n" +// "TX BE queue: %d\n" +// "TX BK queue: %d\n" +// "TX HW queue: %d\n" +// "TX VI dropped: %lu\n" +// "TX VO dropped: %lu\n" +// "TX BE dropped: %lu\n" +// "TX BK dropped: %lu\n" + "TX total data packets %lu\n" + "TX total data bytes :%lu\n", +// "TX beacon aborted: %lu\n", + priv->stats.txviokint, +// priv->stats.txvierr, + priv->stats.txvookint, +// priv->stats.txvoerr, + priv->stats.txbeokint, +// priv->stats.txbeerr, + priv->stats.txbkokint, +// priv->stats.txbkerr, + priv->stats.txmanageokint, +// priv->stats.txmanageerr, + priv->stats.txbeaconokint, + priv->stats.txbeaconerr, + priv->stats.txcmdpktokint, +// priv->stats.txhpokint, +// priv->stats.txhperr, +// priv->stats.txresumed, + netif_queue_stopped(dev), + priv->stats.txoverflow, +// priv->stats.txbeacon, +// atomic_read(&(priv->tx_pending[VI_QUEUE])), +// atomic_read(&(priv->tx_pending[VO_QUEUE])), +// atomic_read(&(priv->tx_pending[BE_QUEUE])), +// atomic_read(&(priv->tx_pending[BK_QUEUE])), +// read_nic_byte(dev, TXFIFOCOUNT), +// priv->stats.txvidrop, +// priv->stats.txvodrop, + priv->ieee80211->stats.tx_packets, + priv->ieee80211->stats.tx_bytes + + +// priv->stats.txbedrop, +// priv->stats.txbkdrop + // priv->stats.txdatapkt +// priv->stats.txbeaconerr + ); + + *eof = 1; + return len; +} + + + +static int proc_get_stats_rx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "RX packets: %lu\n" + "RX desc err: %lu\n" + "RX rx overflow error: %lu\n" + "RX invalid urb error: %lu\n", + priv->stats.rxint, + priv->stats.rxrdu, + priv->stats.rxoverflow, + priv->stats.rxurberr); + + *eof = 1; + return len; +} + +void rtl8192_proc_module_init(void) +{ + RT_TRACE(COMP_INIT, "Initializing proc filesystem"); +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, proc_net); +#else + rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net); +#endif +} + + +void rtl8192_proc_module_remove(void) +{ +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(RTL819xE_MODULE_NAME, proc_net); +#else + remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net); +#endif +} + + +void rtl8192_proc_remove_one(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + printk("dev name=======> %s\n",dev->name); + + if (priv->dir_dev) { + // remove_proc_entry("stats-hw", priv->dir_dev); + remove_proc_entry("stats-tx", priv->dir_dev); + remove_proc_entry("stats-rx", priv->dir_dev); + // remove_proc_entry("stats-ieee", priv->dir_dev); + remove_proc_entry("stats-ap", priv->dir_dev); + remove_proc_entry("registers", priv->dir_dev); + // remove_proc_entry("cck-registers",priv->dir_dev); + // remove_proc_entry("ofdm-registers",priv->dir_dev); + //remove_proc_entry(dev->name, rtl8192_proc); + remove_proc_entry("wlan0", rtl8192_proc); + priv->dir_dev = NULL; + } +} + + +void rtl8192_proc_init_one(struct net_device *dev) +{ + struct proc_dir_entry *e; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + priv->dir_dev = create_proc_entry(dev->name, + S_IFDIR | S_IRUGO | S_IXUGO, + rtl8192_proc); + if (!priv->dir_dev) { + RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", + dev->name); + return; + } + #if 0 + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_hw, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8192/%s/stats-hw\n", + dev->name); + } + #endif + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_rx, dev); + + if (!e) { + RT_TRACE(COMP_ERR,"Unable to initialize " + "/proc/net/rtl8192/%s/stats-rx\n", + dev->name); + } + + + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_tx, dev); + + if (!e) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/stats-tx\n", + dev->name); + } + #if 0 + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_ieee, dev); + + if (!e) { + DMESGE("Unable to initialize " + "/proc/net/rtl8192/%s/stats-ieee\n", + dev->name); + } + + #endif + + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_ap, dev); + + if (!e) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/stats-ap\n", + dev->name); + } + + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers, dev); + if (!e) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers\n", + dev->name); + } +#if 0 + e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_cck_reg, dev); + if (!e) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/cck-registers\n", + dev->name); + } + + e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_ofdm_reg, dev); + if (!e) { + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/ofdm-registers\n", + dev->name); + } +#endif +} +/**************************************************************************** + -----------------------------MISC STUFF------------------------- +*****************************************************************************/ + +/* this is only for debugging */ +void print_buffer(u32 *buffer, int len) +{ + int i; + u8 *buf =(u8*)buffer; + + printk("ASCII BUFFER DUMP (len: %x):\n",len); + + for(i=0;itx_ring[prio]; + + /* for now we reserve two free descriptor as a safety boundary + * between the tail and the head + */ + if (ring->entries - skb_queue_len(&ring->queue) >= 2) { + return 1; + } else { + return 0; + } +} + +void tx_timeout(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + //rtl8192_commit(dev); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + schedule_work(&priv->reset_wq); +#else + schedule_task(&priv->reset_wq); +#endif + printk("TXTIMEOUT"); +} + + +/* this is only for debug */ +void dump_eprom(struct net_device *dev) +{ + int i; + for(i=0; i<0xff; i++) + RT_TRACE(COMP_INIT, "EEPROM addr %x : %x", i, eprom_read(dev,i)); +} + +/* this is only for debug */ +void rtl8192_dump_reg(struct net_device *dev) +{ + int i; + int n; + int max=0x5ff; + + RT_TRACE(COMP_INIT, "Dumping NIC register map"); + + for(n=0;n<=max;) + { + printk( "\nD: %2x> ", n); + for(i=0;i<16 && n<=max;i++,n++) + printk("%2x ",read_nic_byte(dev,n)); + } + printk("\n"); +} + +/**************************************************************************** + ------------------------------HW STUFF--------------------------- +*****************************************************************************/ + + +void rtl8192_irq_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + priv->irq_enabled = 1; + write_nic_dword(dev,INTA_MASK, priv->irq_mask); +} + + +void rtl8192_irq_disable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + write_nic_dword(dev,INTA_MASK,0); + force_pci_posting(dev); + priv->irq_enabled = 0; +} + + +void rtl8192_set_mode(struct net_device *dev,int mode) +{ + u8 ecmd; + ecmd=read_nic_byte(dev, EPROM_CMD); + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK; + ecmd=ecmd | (mode<ieee80211->state == IEEE80211_LINKED){ + + if (priv->ieee80211->iw_mode == IW_MODE_INFRA) + msr |= (MSR_LINK_MANAGED<ieee80211->iw_mode == IW_MODE_ADHOC) + msr |= (MSR_LINK_ADHOC<ieee80211->iw_mode == IW_MODE_MASTER) + msr |= (MSR_LINK_MASTER<%s()====ch:%d\n", __FUNCTION__, ch); + priv->chan=ch; +#if 0 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC || + priv->ieee80211->iw_mode == IW_MODE_MASTER){ + + priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED; + priv->ieee80211->master_chan = ch; + rtl8192_update_beacon_ch(dev); + } +#endif + + /* this hack should avoid frame TX during channel setting*/ + + + // tx = read_nic_dword(dev,TX_CONF); + // tx &= ~TX_LOOPBACK_MASK; + +#ifndef LOOP_TEST + //TODO + // write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<rf_set_chan) + priv->rf_set_chan(dev,priv->chan); + // mdelay(10); + // write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<rx_ring_dma); +} + +/* the TX_DESC_BASE setting is according to the following queue index + * BK_QUEUE ===> 0 + * BE_QUEUE ===> 1 + * VI_QUEUE ===> 2 + * VO_QUEUE ===> 3 + * HCCA_QUEUE ===> 4 + * TXCMD_QUEUE ===> 5 + * MGNT_QUEUE ===> 6 + * HIGH_QUEUE ===> 7 + * BEACON_QUEUE ===> 8 + * */ +u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA}; +void rtl8192_tx_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + u32 i; + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma); + + ieee80211_reset_queue(priv->ieee80211); +} + +#if 0 +void rtl8192_beacon_tx_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + u32 reg; + + reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK); + + /* enable Beacon realted interrupt signal */ + reg |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); + write_nic_byte(dev,reg); +} +#endif + +static void rtl8192_free_rx_ring(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int i; + + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = priv->rx_buf[i]; + if (!skb) + continue; + + pci_unmap_single(priv->pdev, + *((dma_addr_t *)skb->cb), + priv->rxbuffersize, PCI_DMA_FROMDEVICE); + kfree_skb(skb); + } + + pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount, + priv->rx_ring, priv->rx_ring_dma); + priv->rx_ring = NULL; +} + +static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + tx_desc_819x_pci *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; +} + + +void rtl8192_beacon_disable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + u32 reg; + + reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK); + + /* disable Beacon realted interrupt signal */ + reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); + write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg); +} + +void rtl8192_rtx_disable(struct net_device *dev) +{ + u8 cmd; + struct r8192_priv *priv = ieee80211_priv(dev); + int i; + + cmd=read_nic_byte(dev,CMDR); +// if(!priv->ieee80211->bSupportRemoteWakeUp) { + write_nic_byte(dev, CMDR, cmd &~ \ + (CR_TE|CR_RE)); +// } + force_pci_posting(dev); + mdelay(30); + + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_purge(&priv->ieee80211->skb_waitQ [i]); + } + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_purge(&priv->ieee80211->skb_aggQ [i]); + } + + + skb_queue_purge(&priv->skb_queue); + return; +} + +void rtl8192_reset(struct net_device *dev) +{ + rtl8192_irq_disable(dev); + printk("This is RTL819xP Reset procedure\n"); +} + +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540}; +inline u16 rtl8192_rate2rate(short rate) +{ + if (rate >11) return 0; + return rtl_rate[rate]; +} + + + +u32 +rtl819xusb_rx_command_packet( + struct net_device *dev, + struct ieee80211_rx_stats *pstats + ) +{ + u32 status; + + //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n")); + + RT_TRACE(COMP_EVENTS, "---->rtl819xusb_rx_command_packet()\n"); + status = cmpk_message_handle_rx(dev, pstats); + if (status) + { + DMESG("rxcommandpackethandle819xusb: It is a command packet\n"); + } + else + { + //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n")); + } + + //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n")); + return status; +} + +#if 0 +void rtl8192_tx_queues_stop(struct net_device *dev) +{ + //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + u8 dma_poll_mask = (1<dma_poll_mask |= (1<dma_poll_mask); + rtl8192_set_mode(dev,EPROM_CMD_NORMAL); + #endif +} + + +void rtl8192_data_hard_resume(struct net_device *dev) +{ + // FIXME !! + #if 0 + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + priv->dma_poll_mask &= ~(1<dma_poll_mask); + rtl8192_set_mode(dev,EPROM_CMD_NORMAL); + #endif +} + +/* this function TX data frames when the ieee80211 stack requires this. + * It checks also if we need to stop the ieee tx queue, eventually do it + */ +void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + int ret; + //unsigned long flags; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + u8 queue_index = tcb_desc->queue_index; + /* shall not be referred by command packet */ + assert(queue_index != TXCMD_QUEUE); + + //spin_lock_irqsave(&priv->tx_lock,flags); + + memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); +#if 0 + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->bTxEnableFwCalcDur = 1; +#endif + skb_push(skb, priv->ieee80211->tx_headroom); + ret = rtl8192_tx(dev, skb); + if(ret != 0) { + kfree_skb(skb); + }; + +// + if(queue_index!=MGNT_QUEUE) { + priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom); + priv->ieee80211->stats.tx_packets++; + } + + //spin_unlock_irqrestore(&priv->tx_lock,flags); + +// return ret; + return; +} + +/* This is a rough attempt to TX a frame + * This is called by the ieee 80211 stack to TX management frames. + * If the ring is full packet are dropped (for data frame the queue + * is stopped before this can happen). + */ +int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + + int ret; + //unsigned long flags; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + u8 queue_index = tcb_desc->queue_index; + + + //spin_lock_irqsave(&priv->tx_lock,flags); + + memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); + if(queue_index == TXCMD_QUEUE) { + // skb_push(skb, USB_HWDESC_HEADER_LEN); + rtl819xE_tx_cmd(dev, skb); + ret = 0; + //spin_unlock_irqrestore(&priv->tx_lock,flags); + return ret; + } else { + // RT_TRACE(COMP_SEND, "To send management packet\n"); + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->bTxEnableFwCalcDur = 1; + skb_push(skb, priv->ieee80211->tx_headroom); + ret = rtl8192_tx(dev, skb); + if(ret != 0) { + kfree_skb(skb); + }; + } + +// priv->ieee80211->stats.tx_bytes+=skb->len; +// priv->ieee80211->stats.tx_packets++; + + //spin_unlock_irqrestore(&priv->tx_lock,flags); + + return ret; + +} + + +void rtl8192_try_wake_queue(struct net_device *dev, int pri); + +void rtl8192_tx_isr(struct net_device *dev, int prio) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + tx_desc_819x_pci *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + + /* beacon packet will only use the first descriptor defautly, + * and the OWN may not be cleared by the hardware + * */ + if(prio != BEACON_QUEUE) { + if(entry->OWN) + return; + ring->idx = (ring->idx + 1) % ring->entries; + } + + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + + kfree_skb(skb); + } + if (prio == MGNT_QUEUE){ + if (priv->ieee80211->ack_tx_to_ieee){ + if (rtl8192_is_tx_queue_empty(dev)){ + priv->ieee80211->ack_tx_to_ieee = 0; + ieee80211_ps_tx_ack(priv->ieee80211, 1); + } + } + } + + if(prio != BEACON_QUEUE) { + /* try to deal with the pending packets */ + tasklet_schedule(&priv->irq_tx_tasklet); + } + +} + +void rtl8192_stop_beacon(struct net_device *dev) +{ + //rtl8192_beacon_disable(dev); +} + +void rtl8192_config_rate(struct net_device* dev, u16* rate_config) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_network *net; + u8 i=0, basic_rate = 0; + net = & priv->ieee80211->current_network; + + for (i=0; irates_len; i++) + { + basic_rate = net->rates[i]&0x7f; + switch(basic_rate) + { + case MGN_1M: *rate_config |= RRSR_1M; break; + case MGN_2M: *rate_config |= RRSR_2M; break; + case MGN_5_5M: *rate_config |= RRSR_5_5M; break; + case MGN_11M: *rate_config |= RRSR_11M; break; + case MGN_6M: *rate_config |= RRSR_6M; break; + case MGN_9M: *rate_config |= RRSR_9M; break; + case MGN_12M: *rate_config |= RRSR_12M; break; + case MGN_18M: *rate_config |= RRSR_18M; break; + case MGN_24M: *rate_config |= RRSR_24M; break; + case MGN_36M: *rate_config |= RRSR_36M; break; + case MGN_48M: *rate_config |= RRSR_48M; break; + case MGN_54M: *rate_config |= RRSR_54M; break; + } + } + for (i=0; irates_ex_len; i++) + { + basic_rate = net->rates_ex[i]&0x7f; + switch(basic_rate) + { + case MGN_1M: *rate_config |= RRSR_1M; break; + case MGN_2M: *rate_config |= RRSR_2M; break; + case MGN_5_5M: *rate_config |= RRSR_5_5M; break; + case MGN_11M: *rate_config |= RRSR_11M; break; + case MGN_6M: *rate_config |= RRSR_6M; break; + case MGN_9M: *rate_config |= RRSR_9M; break; + case MGN_12M: *rate_config |= RRSR_12M; break; + case MGN_18M: *rate_config |= RRSR_18M; break; + case MGN_24M: *rate_config |= RRSR_24M; break; + case MGN_36M: *rate_config |= RRSR_36M; break; + case MGN_48M: *rate_config |= RRSR_48M; break; + case MGN_54M: *rate_config |= RRSR_54M; break; + } + } +} + + +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + +void rtl8192_update_cap(struct net_device* dev, u16 cap) +{ + u32 tmp = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_network *net = &priv->ieee80211->current_network; + priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE; + tmp = priv->basic_rate; + if (priv->short_preamble) + tmp |= BRSR_AckShortPmb; + write_nic_dword(dev, RRSR, tmp); + + if (net->mode & (IEEE_G|IEEE_N_24G)) + { + u8 slot_time = 0; + if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) + {//short slot time + slot_time = SHORT_SLOT_TIME; + } + else //long slot time + slot_time = NON_SHORT_SLOT_TIME; + priv->slot_time = slot_time; + write_nic_byte(dev, SLOT_TIME, slot_time); + } + +} +void rtl8192_net_update(struct net_device *dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_network *net; + u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; + u16 rate_config = 0; + net = &priv->ieee80211->current_network; + //update Basic rate: RR, BRSR + rtl8192_config_rate(dev, &rate_config); + // 2007.01.16, by Emily + // Select RRSR (in Legacy-OFDM and CCK) + // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. + // We do not use other rates. + priv->basic_rate = rate_config &= 0x15f; + //BSSID + write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]); + write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]); +#if 0 + //MSR + rtl8192_update_msr(dev); +#endif + + +// rtl8192_update_cap(dev, net->capability); + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) + { + write_nic_word(dev, ATIMWND, 2); + write_nic_word(dev, BCN_DMATIME, 256); + write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + // write_nic_word(dev, BcnIntTime, 100); + //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied. + write_nic_word(dev, BCN_DRV_EARLY_INT, 10); + write_nic_byte(dev, BCN_ERR_THRESH, 100); + + BcnTimeCfg |= (BcnCW<tx_ring[TXCMD_QUEUE]; + mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + + spin_lock_irqsave(&priv->irq_th_lock,flags); + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + entry = &ring->desc[idx]; + + tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + memset(entry,0,12); + entry->LINIP = tcb_desc->bLastIniPkt; + entry->FirstSeg = 1;//first segment + entry->LastSeg = 1; //last segment + if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { + entry->CmdInit = DESC_PACKET_TYPE_INIT; + } else { + entry->CmdInit = DESC_PACKET_TYPE_NORMAL; + entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8; + entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset); + entry->QueueSelect = QSLT_CMD; + entry->TxFWInfoSize = 0x08; + entry->RATid = (u8)DESC_PACKET_TYPE_INIT; + } + entry->TxBufferSize = skb->len; + entry->TxBuffAddr = cpu_to_le32(mapping); + entry->OWN = 1; + +#ifdef JOHN_DUMP_TXDESC + { int i; + tx_desc_819x_pci *entry1 = &ring->desc[0]; + unsigned int *ptr= (unsigned int *)entry1; + printk(":\n"); + for (i = 0; i < 8; i++) + printk("%8x ", ptr[i]); + printk("\n"); + } +#endif + __skb_queue_tail(&ring->queue, skb); + spin_unlock_irqrestore(&priv->irq_th_lock,flags); + + write_nic_byte(dev, TPPoll, TPPoll_CQ); + + return; +} + +/* + * Mapping Software/Hardware descriptor queue id to "Queue Select Field" + * in TxFwInfo data structure + * 2006.10.30 by Emily + * + * \param QUEUEID Software Queue +*/ +u8 MapHwQueueToFirmwareQueue(u8 QueueID) +{ + u8 QueueSelect = 0x0; //defualt set to + + switch(QueueID) { + case BE_QUEUE: + QueueSelect = QSLT_BE; //or QSelect = pTcb->priority; + break; + + case BK_QUEUE: + QueueSelect = QSLT_BK; //or QSelect = pTcb->priority; + break; + + case VO_QUEUE: + QueueSelect = QSLT_VO; //or QSelect = pTcb->priority; + break; + + case VI_QUEUE: + QueueSelect = QSLT_VI; //or QSelect = pTcb->priority; + break; + case MGNT_QUEUE: + QueueSelect = QSLT_MGNT; + break; + + case BEACON_QUEUE: + QueueSelect = QSLT_BEACON; + break; + + // TODO: 2006.10.30 mark other queue selection until we verify it is OK + // TODO: Remove Assertions +//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502) + case TXCMD_QUEUE: + QueueSelect = QSLT_CMD; + break; +//#endif + case HIGH_QUEUE: + //QueueSelect = QSLT_HIGH; + //break; + + default: + RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID); + break; + } + return QueueSelect; +} + +u8 MRateToHwRate8190Pci(u8 rate) +{ + u8 ret = DESC90_RATE1M; + + switch(rate) { + case MGN_1M: ret = DESC90_RATE1M; break; + case MGN_2M: ret = DESC90_RATE2M; break; + case MGN_5_5M: ret = DESC90_RATE5_5M; break; + case MGN_11M: ret = DESC90_RATE11M; break; + case MGN_6M: ret = DESC90_RATE6M; break; + case MGN_9M: ret = DESC90_RATE9M; break; + case MGN_12M: ret = DESC90_RATE12M; break; + case MGN_18M: ret = DESC90_RATE18M; break; + case MGN_24M: ret = DESC90_RATE24M; break; + case MGN_36M: ret = DESC90_RATE36M; break; + case MGN_48M: ret = DESC90_RATE48M; break; + case MGN_54M: ret = DESC90_RATE54M; break; + + // HT rate since here + case MGN_MCS0: ret = DESC90_RATEMCS0; break; + case MGN_MCS1: ret = DESC90_RATEMCS1; break; + case MGN_MCS2: ret = DESC90_RATEMCS2; break; + case MGN_MCS3: ret = DESC90_RATEMCS3; break; + case MGN_MCS4: ret = DESC90_RATEMCS4; break; + case MGN_MCS5: ret = DESC90_RATEMCS5; break; + case MGN_MCS6: ret = DESC90_RATEMCS6; break; + case MGN_MCS7: ret = DESC90_RATEMCS7; break; + case MGN_MCS8: ret = DESC90_RATEMCS8; break; + case MGN_MCS9: ret = DESC90_RATEMCS9; break; + case MGN_MCS10: ret = DESC90_RATEMCS10; break; + case MGN_MCS11: ret = DESC90_RATEMCS11; break; + case MGN_MCS12: ret = DESC90_RATEMCS12; break; + case MGN_MCS13: ret = DESC90_RATEMCS13; break; + case MGN_MCS14: ret = DESC90_RATEMCS14; break; + case MGN_MCS15: ret = DESC90_RATEMCS15; break; + case (0x80|0x20): ret = DESC90_RATEMCS32; break; + + default: break; + } + return ret; +} + + +u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc) +{ + u8 tmp_Short; + + tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0); + + if(TxHT==1 && TxRate != DESC90_RATEMCS15) + tmp_Short = 0; + + return tmp_Short; +} + +/* + * The tx procedure is just as following, + * skb->cb will contain all the following information, + * priority, morefrag, rate, &dev. + * */ +short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct rtl8192_tx_ring *ring; + unsigned long flags; + cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tx_desc_819x_pci *pdesc = NULL; + TX_FWINFO_8190PCI *pTxFwInfo = NULL; + dma_addr_t mapping; + bool multi_addr=false,broad_addr=false,uni_addr=false; + u8* pda_addr = NULL; + int idx; + + mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + /* collect the tx packets statitcs */ + pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI); + if(is_multicast_ether_addr(pda_addr)) + multi_addr = true; + else if(is_broadcast_ether_addr(pda_addr)) + broad_addr = true; + else + uni_addr = true; + + if(uni_addr) + priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); + else if(multi_addr) + priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); + else + priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); + + /* fill tx firmware */ + pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data; + memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI)); + pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0; + pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate); + pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur; + pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc); + + /* Aggregation related */ + if(tcb_desc->bAMPDUEnable) { + pTxFwInfo->AllowAggregation = 1; + pTxFwInfo->RxMF = tcb_desc->ampdu_factor; + pTxFwInfo->RxAMD = tcb_desc->ampdu_density; + } else { + pTxFwInfo->AllowAggregation = 0; + pTxFwInfo->RxMF = 0; + pTxFwInfo->RxAMD = 0; + } + + // + // Protection mode related + // + pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0; + pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0; + pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0; + pTxFwInfo->RtsHT= (tcb_desc->rts_rate&0x80)?1:0; + pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate); + pTxFwInfo->RtsBandwidth = 0; + pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC; + pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0); + // + // Set Bandwidth and sub-channel settings. + // + if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) + { + if(tcb_desc->bPacketBW) + { + pTxFwInfo->TxBandwidth = 1; +#ifdef RTL8190P + pTxFwInfo->TxSubCarrier = 3; +#else + pTxFwInfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008 +#endif + } + else + { + pTxFwInfo->TxBandwidth = 0; + pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC; + } + } else { + pTxFwInfo->TxBandwidth = 0; + pTxFwInfo->TxSubCarrier = 0; + } + + if (0) + { + /* 2007/07/25 MH Copy current TX FW info.*/ + memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI)); + printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n"); + printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur); + printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC); + printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier); + printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation); + printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT); + printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate); + printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD); + printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF); + printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth); + printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier); + + printk("<=====**********************out of print\n"); + + } + spin_lock_irqsave(&priv->irq_th_lock,flags); + ring = &priv->tx_ring[tcb_desc->queue_index]; + if (tcb_desc->queue_index != BEACON_QUEUE) { + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + } else { + idx = 0; + } + + pdesc = &ring->desc[idx]; + if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { + RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \ + tcb_desc->queue_index,ring->idx, idx,skb->len); + return skb->len; + } + + /* fill tx descriptor */ + memset((u8*)pdesc,0,12); + /*DWORD 0*/ + pdesc->LINIP = 0; + pdesc->CmdInit = 1; + pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily + pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI); + + /*DWORD 1*/ + pdesc->SecCAMID= 0; + pdesc->RATid = tcb_desc->RATRIndex; + + + pdesc->NoEnc = 1; + pdesc->SecType = 0x0; + if (tcb_desc->bHwSec) { + static u8 tmp =0; + if (!tmp) { + printk("==>================hw sec\n"); + tmp = 1; + } + switch (priv->ieee80211->pairwise_key_type) { + case KEY_TYPE_WEP40: + case KEY_TYPE_WEP104: + pdesc->SecType = 0x1; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_TKIP: + pdesc->SecType = 0x2; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_CCMP: + pdesc->SecType = 0x3; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_NA: + pdesc->SecType = 0x0; + pdesc->NoEnc = 1; + break; + } + } + + // + // Set Packet ID + // + pdesc->PktId = 0x0; + + pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index); + pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI); + + pdesc->DISFB = tcb_desc->bTxDisableRateFallBack; + pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate; + + pdesc->FirstSeg =1; + pdesc->LastSeg = 1; + pdesc->TxBufferSize = skb->len; + + pdesc->TxBuffAddr = cpu_to_le32(mapping); + __skb_queue_tail(&ring->queue, skb); + pdesc->OWN = 1; + spin_unlock_irqrestore(&priv->irq_th_lock,flags); + dev->trans_start = jiffies; + write_nic_word(dev,TPPoll,0x01<queue_index); + return 0; +} + +short rtl8192_alloc_rx_desc_ring(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + rx_desc_819x_pci *entry = NULL; + int i; + + priv->rx_ring = pci_alloc_consistent(priv->pdev, + sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma); + + if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { + RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n"); + return -ENOMEM; + } + + memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount); + priv->rx_idx = 0; + + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); + dma_addr_t *mapping; + entry = &priv->rx_ring[i]; + if (!skb) + return 0; + priv->rx_buf[i] = skb; + mapping = (dma_addr_t *)skb->cb; + *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb), + priv->rxbuffersize, PCI_DMA_FROMDEVICE); + + entry->BufferAddress = cpu_to_le32(*mapping); + + entry->Length = priv->rxbuffersize; + entry->OWN = 1; + } + + entry->EOR = 1; + return 0; +} + +static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, + unsigned int prio, unsigned int entries) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + tx_desc_819x_pci *ring; + dma_addr_t dma; + int i; + + ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); + if (!ring || (unsigned long)ring & 0xFF) { + RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio); + return -ENOMEM; + } + + memset(ring, 0, sizeof(*ring)*entries); + priv->tx_ring[prio].desc = ring; + priv->tx_ring[prio].dma = dma; + priv->tx_ring[prio].idx = 0; + priv->tx_ring[prio].entries = entries; + skb_queue_head_init(&priv->tx_ring[prio].queue); + + for (i = 0; i < entries; i++) + ring[i].NextDescAddress = + cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); + + return 0; +} + + +short rtl8192_pci_initdescring(struct net_device *dev) +{ + u32 ret; + int i; + struct r8192_priv *priv = ieee80211_priv(dev); + + ret = rtl8192_alloc_rx_desc_ring(dev); + if (ret) { + return ret; + } + + + /* general process for other queue */ + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { + if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount))) + goto err_free_rings; + } + +#if 0 + /* specific process for hardware beacon process */ + if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2))) + goto err_free_rings; +#endif + + return 0; + +err_free_rings: + rtl8192_free_rx_ring(dev); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + if (priv->tx_ring[i].desc) + rtl8192_free_tx_ring(dev, i); + return 1; +} + +void rtl8192_pci_resetdescring(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int i; + + /* force the rx_idx to the first one */ + if(priv->rx_ring) { + rx_desc_819x_pci *entry = NULL; + for (i = 0; i < priv->rxringcount; i++) { + entry = &priv->rx_ring[i]; + entry->OWN = 1; + } + priv->rx_idx = 0; + } + + /* after reset, release previous pending packet, and force the + * tx idx to the first one */ + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { + if (priv->tx_ring[i].desc) { + struct rtl8192_tx_ring *ring = &priv->tx_ring[i]; + + while (skb_queue_len(&ring->queue)) { + tx_desc_819x_pci *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + ring->idx = 0; + } + } +} + +#if 1 +extern void rtl8192_update_ratr_table(struct net_device* dev); +void rtl8192_link_change(struct net_device *dev) +{ +// int i; + + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval); + if (ieee->state == IEEE80211_LINKED) + { + rtl8192_net_update(dev); + rtl8192_update_ratr_table(dev); +#if 1 + //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08 + if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) + EnableHWSecurityConfig8192(dev); +#endif + } + else + { + write_nic_byte(dev, 0x173, 0); + } + /*update timing params*/ + //rtl8192_set_chan(dev, priv->chan); + //MSR + rtl8192_update_msr(dev); + + // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have + // // To set CBSSID bit when link with any AP or STA. + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) + { + u32 reg = 0; + reg = read_nic_dword(dev, RCR); + if (priv->ieee80211->state == IEEE80211_LINKED) + priv->ReceiveConfig = reg |= RCR_CBSSID; + else + priv->ReceiveConfig = reg &= ~RCR_CBSSID; + write_nic_dword(dev, RCR, reg); + } +} +#endif + + +static struct ieee80211_qos_parameters def_qos_parameters = { + {3,3,3,3},/* cw_min */ + {7,7,7,7},/* cw_max */ + {2,2,2,2},/* aifs */ + {0,0,0,0},/* flags */ + {0,0,0,0} /* tx_op_limit */ +}; + +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20) +void rtl8192_update_beacon(struct work_struct * work) +{ + struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work); + struct net_device *dev = priv->ieee80211->dev; +#else +void rtl8192_update_beacon(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + struct ieee80211_device* ieee = priv->ieee80211; + struct ieee80211_network* net = &ieee->current_network; + + if (ieee->pHTInfo->bCurrentHTSupport) + HTUpdateSelfAndPeerSetting(ieee, net); + ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime; + rtl8192_update_cap(dev, net->capability); +} +/* +* background support to run QoS activate functionality +*/ +int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO}; +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20) +void rtl8192_qos_activate(struct work_struct * work) +{ + struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate); + struct net_device *dev = priv->ieee80211->dev; +#else +void rtl8192_qos_activate(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; + u8 mode = priv->ieee80211->current_network.mode; +// u32 size = sizeof(struct ieee80211_qos_parameters); + u8 u1bAIFS; + u32 u4bAcParam; + int i; + if (priv == NULL) + return; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + down(&priv->mutex); +#else + mutex_lock(&priv->mutex); +#endif + if(priv->ieee80211->state != IEEE80211_LINKED) + goto success; + RT_TRACE(COMP_QOS,"qos active process with associate response received\n"); + /* It better set slot time at first */ + /* For we just support b/g mode at present, let the slot time at 9/20 selection */ + /* update the ac parameter to related registers */ + for(i = 0; i < QOS_QUEUE_NUM; i++) { + //Mode G/A: slotTimeTimer = 9; Mode B: 20 + u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; + u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| + (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| + (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| + ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); + printk("===>u4bAcParam:%x, ", u4bAcParam); + write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); + //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); + } + +success: +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + up(&priv->mutex); +#else + mutex_unlock(&priv->mutex); +#endif +} + +static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, + int active_network, + struct ieee80211_network *network) +{ + int ret = 0; + u32 size = sizeof(struct ieee80211_qos_parameters); + + if(priv->ieee80211->state !=IEEE80211_LINKED) + return ret; + + if ((priv->ieee80211->iw_mode != IW_MODE_INFRA)) + return ret; + + if (network->flags & NETWORK_HAS_QOS_MASK) { + if (active_network && + (network->flags & NETWORK_HAS_QOS_PARAMETERS)) + network->qos_data.active = network->qos_data.supported; + + if ((network->qos_data.active == 1) && (active_network == 1) && + (network->flags & NETWORK_HAS_QOS_PARAMETERS) && + (network->qos_data.old_param_count != + network->qos_data.param_count)) { + network->qos_data.old_param_count = + network->qos_data.param_count; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(priv->priv_wq, &priv->qos_activate); +#else + schedule_task(&priv->qos_activate); +#endif + RT_TRACE (COMP_QOS, "QoS parameters change call " + "qos_activate\n"); + } + } else { + memcpy(&priv->ieee80211->current_network.qos_data.parameters,\ + &def_qos_parameters, size); + + if ((network->qos_data.active == 1) && (active_network == 1)) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(priv->priv_wq, &priv->qos_activate); +#else + schedule_task(&priv->qos_activate); +#endif + RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n"); + } + network->qos_data.active = 0; + network->qos_data.supported = 0; + } + + return 0; +} + +/* handle manage frame frame beacon and probe response */ +static int rtl8192_handle_beacon(struct net_device * dev, + struct ieee80211_beacon * beacon, + struct ieee80211_network * network) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + rtl8192_qos_handle_probe_response(priv,1,network); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0); +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->update_beacon_wq); +#else + queue_work(priv->priv_wq, &priv->update_beacon_wq); +#endif +#endif + return 0; + +} + +/* +* handling the beaconing responses. if we get different QoS setting +* off the network from the associated setting, adjust the QoS +* setting +*/ +static int rtl8192_qos_association_resp(struct r8192_priv *priv, + struct ieee80211_network *network) +{ + int ret = 0; + unsigned long flags; + u32 size = sizeof(struct ieee80211_qos_parameters); + int set_qos_param = 0; + + if ((priv == NULL) || (network == NULL)) + return ret; + + if(priv->ieee80211->state !=IEEE80211_LINKED) + return ret; + + if ((priv->ieee80211->iw_mode != IW_MODE_INFRA)) + return ret; + + spin_lock_irqsave(&priv->ieee80211->lock, flags); + if(network->flags & NETWORK_HAS_QOS_PARAMETERS) { + memcpy(&priv->ieee80211->current_network.qos_data.parameters,\ + &network->qos_data.parameters,\ + sizeof(struct ieee80211_qos_parameters)); + priv->ieee80211->current_network.qos_data.active = 1; +#if 0 + if((priv->ieee80211->current_network.qos_data.param_count != \ + network->qos_data.param_count)) +#endif + { + set_qos_param = 1; + /* update qos parameter for current network */ + priv->ieee80211->current_network.qos_data.old_param_count = \ + priv->ieee80211->current_network.qos_data.param_count; + priv->ieee80211->current_network.qos_data.param_count = \ + network->qos_data.param_count; + } + } else { + memcpy(&priv->ieee80211->current_network.qos_data.parameters,\ + &def_qos_parameters, size); + priv->ieee80211->current_network.qos_data.active = 0; + priv->ieee80211->current_network.qos_data.supported = 0; + set_qos_param = 1; + } + + spin_unlock_irqrestore(&priv->ieee80211->lock, flags); + + RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active); + if (set_qos_param == 1) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(priv->priv_wq, &priv->qos_activate); +#else + schedule_task(&priv->qos_activate); +#endif + + + return ret; +} + + +static int rtl8192_handle_assoc_response(struct net_device *dev, + struct ieee80211_assoc_response_frame *resp, + struct ieee80211_network *network) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + rtl8192_qos_association_resp(priv, network); + return 0; +} + + +//updateRATRTabel for MCS only. Basic rate is not implement. +void rtl8192_update_ratr_table(struct net_device* dev) + // POCTET_STRING posLegacyRate, + // u8* pMcsRate) + // PRT_WLAN_STA pEntry) +{ + struct r8192_priv* priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + u8* pMcsRate = ieee->dot11HTOperationalRateSet; + //struct ieee80211_network *net = &ieee->current_network; + u32 ratr_value = 0; + u8 rate_index = 0; + + rtl8192_config_rate(dev, (u16*)(&ratr_value)); + ratr_value |= (*(u16*)(pMcsRate)) << 12; +// switch (net->mode) + switch (ieee->mode) + { + case IEEE_A: + ratr_value &= 0x00000FF0; + break; + case IEEE_B: + ratr_value &= 0x0000000F; + break; + case IEEE_G: + ratr_value &= 0x00000FF7; + break; + case IEEE_N_24G: + case IEEE_N_5G: + if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC + ratr_value &= 0x0007F007; + else{ + if (priv->rf_type == RF_1T2R) + ratr_value &= 0x000FF007; + else + ratr_value &= 0x0F81F007; + } + break; + default: + break; + } + ratr_value &= 0x0FFFFFFF; + if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){ + ratr_value |= 0x80000000; + }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){ + ratr_value |= 0x80000000; + } + write_nic_dword(dev, RATR0+rate_index*4, ratr_value); + write_nic_byte(dev, UFWP, 1); +} + +static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; +static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; +bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) +{ +#if 1 + struct r8192_priv* priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + int wpa_ie_len= ieee->wpa_ie_len; + struct ieee80211_crypt_data* crypt; + int encrypt; + + crypt = ieee->crypt[ieee->tx_keyidx]; + encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP"))); + + /* simply judge */ + if(encrypt && (wpa_ie_len == 0)) { + /* wep encryption, no N mode setting */ + return false; +// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) { + } else if((wpa_ie_len != 0)) { + /* parse pairwise key type */ + //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP)) + if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4)))) + return true; + else + return false; + } else { + //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ ); + return true; + } + +#if 0 + //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate. + //We can't force in G mode if Pairwie key is AES and group key is TKIP + if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) || + (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) || + (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption)) + { + return false; + } + else + return true; +#endif + return true; +#endif +} + +void rtl8192_refresh_supportrate(struct r8192_priv* priv) +{ + struct ieee80211_device* ieee = priv->ieee80211; + //we donot consider set support rate for ABG mode, only HT MCS rate is set here. + if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) + { + memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16); + //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16); + //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16); + } + else + memset(ieee->Regdot11HTOperationalRateSet, 0, 16); + return; +} + +u8 rtl8192_getSupportedWireleeMode(struct net_device*dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 ret = 0; + switch(priv->rf_chip) + { + case RF_8225: + case RF_8256: + case RF_PSEUDO_11N: + ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); + break; + case RF_8258: + ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G); + break; + default: + ret = WIRELESS_MODE_B; + break; + } + return ret; +} +void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev); + +#if 1 + if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0)) + { + if(bSupportMode & WIRELESS_MODE_N_24G) + { + wireless_mode = WIRELESS_MODE_N_24G; + } + else if(bSupportMode & WIRELESS_MODE_N_5G) + { + wireless_mode = WIRELESS_MODE_N_5G; + } + else if((bSupportMode & WIRELESS_MODE_A)) + { + wireless_mode = WIRELESS_MODE_A; + } + else if((bSupportMode & WIRELESS_MODE_G)) + { + wireless_mode = WIRELESS_MODE_G; + } + else if((bSupportMode & WIRELESS_MODE_B)) + { + wireless_mode = WIRELESS_MODE_B; + } + else{ + RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode); + wireless_mode = WIRELESS_MODE_B; + } + } +#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA + ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); +#endif + priv->ieee80211->mode = wireless_mode; + + if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G)) + priv->ieee80211->pHTInfo->bEnableHT = 1; + else + priv->ieee80211->pHTInfo->bEnableHT = 0; + RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); + rtl8192_refresh_supportrate(priv); +#endif + +} +//init priv variables here + +bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev) +{ + bool Reval; + struct r8192_priv* priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + + if(ieee->bHalfWirelessN24GMode == true) + Reval = true; + else + Reval = false; + + return Reval; +} + +short rtl8192_is_tx_queue_empty(struct net_device *dev) +{ + int i=0; + struct r8192_priv *priv = ieee80211_priv(dev); + for (i=0; i<=MGNT_QUEUE; i++) + { + if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) ) + continue; + if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){ + printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue)); + return 0; + } + } + return 1; +} +#if 0 +void rtl8192_rq_tx_ack(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + priv->ieee80211->ack_tx_to_ieee = 1; +} +#endif +void rtl8192_hw_sleep_down(struct net_device *dev) +{ + RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__); + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8192_hw_sleep_wq (struct work_struct *work) +{ +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); +// struct ieee80211_device * ieee = (struct ieee80211_device*) +// container_of(work, struct ieee80211_device, watch_dog_wq); + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8192_hw_sleep_wq(struct net_device* dev) +{ +#endif + //printk("=========>%s()\n", __FUNCTION__); + rtl8192_hw_sleep_down(dev); +} +// printk("dev is %d\n",dev); +// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__); +void rtl8192_hw_wakeup(struct net_device* dev) +{ +// u32 flags = 0; + +// spin_lock_irqsave(&priv->ps_lock,flags); + RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__); + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); + //FIXME: will we send package stored while nic is sleep? +// spin_unlock_irqrestore(&priv->ps_lock,flags); +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8192_hw_wakeup_wq (struct work_struct *work) +{ +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); +// struct ieee80211_device * ieee = (struct ieee80211_device*) +// container_of(work, struct ieee80211_device, watch_dog_wq); + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); + struct net_device *dev = ieee->dev; +#else +void rtl8192_hw_wakeup_wq(struct net_device* dev) +{ +#endif + rtl8192_hw_wakeup(dev); + +} + +#define MIN_SLEEP_TIME 50 +#define MAX_SLEEP_TIME 10000 +void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + + u32 rb = jiffies; + unsigned long flags; + + spin_lock_irqsave(&priv->ps_lock,flags); + + /* Writing HW register with 0 equals to disable + * the timer, that is not really what we want + */ + tl -= MSECS(4+16+7); + + //if(tl == 0) tl = 1; + + /* FIXME HACK FIXME HACK */ +// force_pci_posting(dev); + //mdelay(1); + +// rb = read_nic_dword(dev, TSFTR); + + /* If the interval in witch we are requested to sleep is too + * short then give up and remain awake + */ + if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) + ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { + spin_unlock_irqrestore(&priv->ps_lock,flags); + printk("too short to sleep\n"); + return; + } + +// write_nic_dword(dev, TimerInt, tl); +// rb = read_nic_dword(dev, TSFTR); + { + u32 tmp = (tl>rb)?(tl-rb):(rb-tl); + // if (tlieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb + } + /* if we suspect the TimerInt is gone beyond tl + * while setting it, then give up + */ +#if 1 + if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| + ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) { + printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); + spin_unlock_irqrestore(&priv->ps_lock,flags); + return; + } +#endif +// if(priv->rf_sleep) +// priv->rf_sleep(dev); + + //printk("<=========%s()\n", __FUNCTION__); + queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0); + spin_unlock_irqrestore(&priv->ps_lock,flags); +} +static void rtl8192_init_priv_variable(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 i; + priv->being_init_adapter = false; + priv->txbuffsize = 1600;//1024; + priv->txfwbuffersize = 4096; + priv->txringcount = 64;//32; + //priv->txbeaconcount = priv->txringcount; + priv->txbeaconcount = 2; + priv->rxbuffersize = 9100;//2048;//1024; + priv->rxringcount = MAX_RX_COUNT;//64; + priv->irq_enabled=0; + priv->card_8192 = NIC_8192E; + priv->rx_skb_complete = 1; + priv->chan = 1; //set to channel 1 + priv->RegWirelessMode = WIRELESS_MODE_AUTO; + priv->RegChannelPlan = 0xf; + priv->nrxAMPDU_size = 0; + priv->nrxAMPDU_aggr_num = 0; + priv->last_rxdesc_tsf_high = 0; + priv->last_rxdesc_tsf_low = 0; + priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO + priv->ieee80211->iw_mode = IW_MODE_INFRA; + priv->ieee80211->ieee_up=0; + priv->retry_rts = DEFAULT_RETRY_RTS; + priv->retry_data = DEFAULT_RETRY_DATA; + priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD; + priv->ieee80211->rate = 110; //11 mbps + priv->ieee80211->short_slot = 1; + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; + priv->bcck_in_ch14 = false; + priv->bfsync_processing = false; + priv->CCKPresentAttentuation = 0; + priv->rfa_txpowertrackingindex = 0; + priv->rfc_txpowertrackingindex = 0; + priv->CckPwEnl = 6; + priv->ScanDelay = 50;//for Scan TODO + //added by amy for silent reset + priv->ResetProgress = RESET_TYPE_NORESET; + priv->bForcedSilentReset = 0; + priv->bDisableNormalResetCheck = false; + priv->force_reset = false; + //added by amy for power save + priv->RegRfOff = 0; + priv->ieee80211->RfOffReason = 0; + priv->RFChangeInProgress = false; + priv->bHwRfOffAction = 0; + priv->SetRFPowerStateInProgress = false; + priv->ieee80211->PowerSaveControl.bInactivePs = true; + priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; + //just for debug + priv->txpower_checkcnt = 0; + priv->thermal_readback_index =0; + priv->txpower_tracking_callback_cnt = 0; + priv->ccktxpower_adjustcnt_ch14 = 0; + priv->ccktxpower_adjustcnt_not_ch14 = 0; + + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; + priv->ieee80211->iw_mode = IW_MODE_INFRA; + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN | + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* | + IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE; + + priv->ieee80211->active_scan = 1; + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; + priv->ieee80211->host_encrypt = 1; + priv->ieee80211->host_decrypt = 1; + //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604 + //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604 + priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107 + priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107 + priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit; + priv->ieee80211->set_chan = rtl8192_set_chan; + priv->ieee80211->link_change = rtl8192_link_change; + priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit; + priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop; + priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume; + priv->ieee80211->init_wmmparam_flag = 0; + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; + priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc; + priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI); + priv->ieee80211->qos_support = 1; + priv->ieee80211->dot11PowerSaveMode = 0; + //added by WB +// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl; + priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode; + priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response; + priv->ieee80211->handle_beacon = rtl8192_handle_beacon; + + priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup; +// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack; + priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep; + priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty; + //added by david + priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci; + priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode; + priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci; + + //added by amy + priv->ieee80211->InitialGainHandler = InitialGain819xPci; + + priv->card_type = USB; + { + priv->ShortRetryLimit = 0x30; + priv->LongRetryLimit = 0x30; + } + priv->EarlyRxThreshold = 7; + priv->enable_gpio0 = 0; + + priv->TransmitConfig = 0; + + priv->ReceiveConfig = RCR_ADD3 | + RCR_AMF | RCR_ADF | //accept management/data + RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC + RCR_AAP | ((u32)7<irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\ + IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\ + IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\ + IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); + + priv->AcmControl = 0; + priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware)); + if (priv->pFirmware) + memset(priv->pFirmware, 0, sizeof(rt_firmware)); + + /* rx related queue */ + skb_queue_head_init(&priv->rx_queue); + skb_queue_head_init(&priv->skb_queue); + + /* Tx related queue */ + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]); + } + for(i = 0; i < MAX_QUEUE_SIZE; i++) { + skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]); + } + priv->rf_set_chan = rtl8192_phy_SwChnl; +} + +//init lock here +static void rtl8192_init_priv_lock(struct r8192_priv* priv) +{ + spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->irq_lock);//added by thomas + spin_lock_init(&priv->irq_th_lock); + spin_lock_init(&priv->rf_ps_lock); + spin_lock_init(&priv->ps_lock); + //spin_lock_init(&priv->rf_lock); + sema_init(&priv->wx_sem,1); + sema_init(&priv->rf_sem,1); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + sema_init(&priv->mutex, 1); +#else + mutex_init(&priv->mutex); +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void rtl819x_watchdog_wqcallback(struct work_struct *work); +#else +extern void rtl819x_watchdog_wqcallback(struct net_device *dev); +#endif + +void rtl8192_irq_rx_tasklet(struct r8192_priv *priv); +void rtl8192_irq_tx_tasklet(struct r8192_priv *priv); +void rtl8192_prepare_beacon(struct r8192_priv *priv); +//init tasklet and wait_queue here. only 2.6 above kernel is considered +#define DRV_NAME "wlan0" +static void rtl8192_init_priv_task(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#ifdef PF_SYNCTHREAD + priv->priv_wq = create_workqueue(DRV_NAME,0); +#else + priv->priv_wq = create_workqueue(DRV_NAME); +#endif +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart); + INIT_WORK(&priv->reset_wq, rtl8192_restart); +// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog); + INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback); + INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback); + INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback); + INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon); + //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem); + //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem); + INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); + INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq); + INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq); + +#else +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev); + tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev); + tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev); + tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev); + tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev); + //tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev); + //tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev); + tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev); + tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev); + tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev); + +#else + INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev); +// INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev); + INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev); + INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev); + INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev); + INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev); + //INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev); + //INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev); + INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev); + INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev); + INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev); +#endif +#endif + + tasklet_init(&priv->irq_rx_tasklet, + (void(*)(unsigned long))rtl8192_irq_rx_tasklet, + (unsigned long)priv); + tasklet_init(&priv->irq_tx_tasklet, + (void(*)(unsigned long))rtl8192_irq_tx_tasklet, + (unsigned long)priv); + tasklet_init(&priv->irq_prepare_beacon_tasklet, + (void(*)(unsigned long))rtl8192_prepare_beacon, + (unsigned long)priv); +} + +static void rtl8192_get_eeprom_size(struct net_device* dev) +{ + u16 curCR = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__); + curCR = read_nic_dword(dev, EPROM_CMD); + RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR); + //whether need I consider BIT5? + priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46; + RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype); +} + +//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead. +static inline u16 endian_swap(u16* data) +{ + u16 tmp = *data; + *data = (tmp >> 8) | (tmp << 8); + return *data; +} + +/* + * Note: Adapter->EEPROMAddressSize should be set before this function call. + * EEPROM address size can be got through GetEEPROMSize8185() +*/ +static void rtl8192_read_eeprom_info(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + u8 tempval; +#ifdef RTL8192E + u8 ICVer8192, ICVer8256; +#endif + u16 i,usValue, IC_Version; + u16 EEPROMId; +#ifdef RTL8190P + u8 offset;//, tmpAFR; + u8 EepromTxPower[100]; +#endif + u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; + RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n"); + + + // TODO: I don't know if we need to apply EF function to EEPROM read function + + //2 Read EEPROM ID to make sure autoload is success + EEPROMId = eprom_read(dev, 0); + if( EEPROMId != RTL8190_EEPROM_ID ) + { + RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID); + priv->AutoloadFailFlag=true; + } + else + { + priv->AutoloadFailFlag=false; + } + + // + // Assign Chip Version ID + // + // Read IC Version && Channel Plan + if(!priv->AutoloadFailFlag) + { + // VID, PID + priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1)); + priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1)); + + usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ; + priv->eeprom_CustomerID = (u8)( usValue & 0xff); + usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1)); + priv->eeprom_ChannelPlan = usValue&0xff; + IC_Version = ((usValue&0xff00)>>8); + +#ifdef RTL8190P + priv->card_8192_version = (VERSION_8190)(IC_Version); +#else + #ifdef RTL8192E + ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut... + ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut... + RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192); + RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256); + if(ICVer8192 == 0x2) //B-cut + { + if(ICVer8256 == 0x5) //E-cut + priv->card_8192_version= VERSION_8190_BE; + } + #endif +#endif + switch(priv->card_8192_version) + { + case VERSION_8190_BD: + case VERSION_8190_BE: + break; + default: + priv->card_8192_version = VERSION_8190_BD; + break; + } + RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version); + } + else + { + priv->card_8192_version = VERSION_8190_BD; + priv->eeprom_vid = 0; + priv->eeprom_did = 0; + priv->eeprom_CustomerID = 0; + priv->eeprom_ChannelPlan = 0; + RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff); + } + + RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); + RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did); + RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID); + + //2 Read Permanent MAC address + if(!priv->AutoloadFailFlag) + { + for(i = 0; i < 6; i += 2) + { + usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1)); + *(u16*)(&dev->dev_addr[i]) = usValue; + } + } else { + // when auto load failed, the last address byte set to be a random one. + // added by david woo.2007/11/7 + memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); + #if 0 + for(i = 0; i < 6; i++) + { + Adapter->PermanentAddress[i] = sMacAddr[i]; + PlatformEFIOWrite1Byte(Adapter, IDR0+i, sMacAddr[i]); + } + #endif + } + + RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5]); + + //2 TX Power Check EEPROM Fail or not + if(priv->card_8192_version > VERSION_8190_BD) { + priv->bTXPowerDataReadFromEEPORM = true; + } else { + priv->bTXPowerDataReadFromEEPORM = false; + } + + // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R + priv->rf_type = RTL819X_DEFAULT_RF_TYPE; + + if(priv->card_8192_version > VERSION_8190_BD) + { + // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate. + if(!priv->AutoloadFailFlag) + { + tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff; + priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0] + + if (tempval&0x80) //RF-indication, bit[7] + priv->rf_type = RF_1T2R; + else + priv->rf_type = RF_2T4R; + } + else + { + priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff; + } + RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n", + priv->EEPROMLegacyHTTxPowerDiff); + + // Read ThermalMeter from EEPROM + if(!priv->AutoloadFailFlag) + { + priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8); + } + else + { + priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; + } + RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter); + //vivi, for tx power track + priv->TSSI_13dBm = priv->EEPROMThermalMeter *100; + + if(priv->epromtype == EPROM_93c46) + { + // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM + if(!priv->AutoloadFailFlag) + { + usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1)); + priv->EEPROMAntPwDiff = (usValue&0x0fff); + priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12); + } + else + { + priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; + priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap; + } + RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff); + RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap); + + // + // Get per-channel Tx Power Level + // + for(i=0; i<14; i+=2) + { + if(!priv->AutoloadFailFlag) + { + usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) ); + } + else + { + usValue = EEPROM_Default_TxPower; + } + *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue; + RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]); + RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]); + } + for(i=0; i<14; i+=2) + { + if(!priv->AutoloadFailFlag) + { + usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) ); + } + else + { + usValue = EEPROM_Default_TxPower; + } + *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue; + RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]); + RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]); + } + } + else if(priv->epromtype== EPROM_93c56) + { + #ifdef RTL8190P + // Read CrystalCap from EEPROM + if(!priv->AutoloadFailFlag) + { + priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; + priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12); + } + else + { + priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; + priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap; + } + RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff); + RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap); + + // Get Tx Power Level by Channel + if(!priv->AutoloadFailFlag) + { + // Read Tx power of Channel 1 ~ 14 from EEPROM. + for(i = 0; i < 12; i+=2) + { + if (i <6) + offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i; + else + offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6; + usValue = eprom_read(dev, (offset>>1)); + *((u16*)(&EepromTxPower[i])) = usValue; + } + + for(i = 0; i < 12; i++) + { + if (i <= 2) + priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i]; + else if ((i >=3 )&&(i <= 5)) + priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i]; + else if ((i >=6 )&&(i <= 8)) + priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i]; + else + priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i]; + } + } + else + { + priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel; + + priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel; + + priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel; + + priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel; + priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel; + } + RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]); + RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]); +#endif + + } + // + // Update HAL variables. + // + if(priv->epromtype == EPROM_93c46) + { + for(i=0; i<14; i++) + { + priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i]; + priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i]; + } + priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff; + // Antenna B gain offset to antenna A, bit0~3 + priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf); + // Antenna C gain offset to antenna A, bit4~7 + priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4); + // Antenna D gain offset to antenna A, bit8~11 + priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8); + // CrystalCap, bit12~15 + priv->CrystalCap = priv->EEPROMCrystalCap; + // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 + priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); + priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4); + } + else if(priv->epromtype == EPROM_93c56) + { + //char cck_pwr_diff_a=0, cck_pwr_diff_c=0; + + //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1]; + //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1]; + for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level. + { + priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0]; + priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0]; + priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0]; + priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0]; + } + for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level + { + priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1]; + priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1]; + priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1]; + priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1]; + } + for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level + { + priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2]; + priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2]; + priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2]; + priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2]; + } + for(i=0; i<14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]); + for(i=0; i<14; i++) + RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]); + for(i=0; i<14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]); + for(i=0; i<14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]); + priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff; + priv->AntennaTxPwDiff[0] = 0; + priv->AntennaTxPwDiff[1] = 0; + priv->AntennaTxPwDiff[2] = 0; + priv->CrystalCap = priv->EEPROMCrystalCap; + // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 + priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); + priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4); + } + } + + if(priv->rf_type == RF_1T2R) + { + RT_TRACE(COMP_INIT, "\n1T2R config\n"); + } + else if (priv->rf_type == RF_2T4R) + { + RT_TRACE(COMP_INIT, "\n2T4R config\n"); + } + + // 2008/01/16 MH We can only know RF type in the function. So we have to init + // DIG RATR table again. + init_rate_adaptive(dev); + + //1 Make a copy for following variables and we can change them if we want + + priv->rf_chip= RF_8256; + + if(priv->RegChannelPlan == 0xf) + { + priv->ChannelPlan = priv->eeprom_ChannelPlan; + } + else + { + priv->ChannelPlan = priv->RegChannelPlan; + } + + // + // Used PID and DID to Set CustomerID + // + if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 ) + { + priv->CustomerID = RT_CID_DLINK; + } + + switch(priv->eeprom_CustomerID) + { + case EEPROM_CID_DEFAULT: + priv->CustomerID = RT_CID_DEFAULT; + break; + case EEPROM_CID_CAMEO: + priv->CustomerID = RT_CID_819x_CAMEO; + break; + case EEPROM_CID_RUNTOP: + priv->CustomerID = RT_CID_819x_RUNTOP; + break; + case EEPROM_CID_NetCore: + priv->CustomerID = RT_CID_819x_Netcore; + break; + case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31 + priv->CustomerID = RT_CID_TOSHIBA; + if(priv->eeprom_ChannelPlan&0x80) + priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f; + else + priv->ChannelPlan = 0x0; + RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n", + priv->ChannelPlan); + break; + case EEPROM_CID_Nettronix: + priv->ScanDelay = 100; //cosa add for scan + priv->CustomerID = RT_CID_Nettronix; + break; + case EEPROM_CID_Pronet: + priv->CustomerID = RT_CID_PRONET; + break; + case EEPROM_CID_DLINK: + priv->CustomerID = RT_CID_DLINK; + break; + + case EEPROM_CID_WHQL: + //Adapter->bInHctTest = TRUE;//do not supported + + //priv->bSupportTurboMode = FALSE; + //priv->bAutoTurboBy8186 = FALSE; + + //pMgntInfo->PowerSaveControl.bInactivePs = FALSE; + //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE; + //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE; + + break; + default: + // value from RegCustomerID + break; + } + + //Avoid the channel plan array overflow, by Bruce, 2007-08-27. + if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1) + priv->ChannelPlan = 0; //FCC + + switch(priv->CustomerID) + { + case RT_CID_DEFAULT: + #ifdef RTL8190P + priv->LedStrategy = HW_LED; + #else + #ifdef RTL8192E + priv->LedStrategy = SW_LED_MODE1; + #endif + #endif + break; + + case RT_CID_819x_CAMEO: + priv->LedStrategy = SW_LED_MODE2; + break; + + case RT_CID_819x_RUNTOP: + priv->LedStrategy = SW_LED_MODE3; + break; + + case RT_CID_819x_Netcore: + priv->LedStrategy = SW_LED_MODE4; + break; + + case RT_CID_Nettronix: + priv->LedStrategy = SW_LED_MODE5; + break; + + case RT_CID_PRONET: + priv->LedStrategy = SW_LED_MODE6; + break; + + case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31 + // Do nothing. + //break; + + default: + #ifdef RTL8190P + priv->LedStrategy = HW_LED; + #else + #ifdef RTL8192E + priv->LedStrategy = SW_LED_MODE1; + #endif + #endif + break; + } +/* + //2008.06.03, for WOL + if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) + priv->ieee80211->bSupportRemoteWakeUp = TRUE; + else + priv->ieee80211->bSupportRemoteWakeUp = FALSE; +*/ + RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); + RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan); + RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy); + RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n"); + + return ; +} + + +short rtl8192_get_channel_map(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef ENABLE_DOT11D + if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){ + printk("rtl8180_init:Error channel plan! Set to default.\n"); + priv->ChannelPlan= 0; + } + RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan); + + rtl819x_set_channel_map(priv->ChannelPlan, priv); +#else + int ch,i; + //Set Default Channel Plan + if(!channels){ + DMESG("No channels, aborting"); + return -1; + } + ch=channels; + priv->ChannelPlan= 0;//hikaru + // set channels 1..14 allowed in given locale + for (i=1; i<=14; i++) { + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01); + ch >>= 1; + } +#endif + return 0; +} +short rtl8192_init(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + memset(&(priv->stats),0,sizeof(struct Stats)); + rtl8192_init_priv_variable(dev); + rtl8192_init_priv_lock(priv); + rtl8192_init_priv_task(dev); + rtl8192_get_eeprom_size(dev); + rtl8192_read_eeprom_info(dev); + rtl8192_get_channel_map(dev); + init_hal_dm(dev); + init_timer(&priv->watch_dog_timer); + priv->watch_dog_timer.data = (unsigned long)dev; + priv->watch_dog_timer.function = watch_dog_timer_callback; +#if defined(IRQF_SHARED) + if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){ +#else + if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){ +#endif + printk("Error allocating IRQ %d",dev->irq); + return -1; + }else{ + priv->irq=dev->irq; + printk("IRQ %d",dev->irq); + } + if(rtl8192_pci_initdescring(dev)!=0){ + printk("Endopoints initialization failed"); + return -1; + } + + //rtl8192_rx_enable(dev); + //rtl8192_adapter_start(dev); +//#ifdef DEBUG_EPROM +// dump_eprom(dev); +//#endif + //rtl8192_dump_reg(dev); + return 0; +} + +/****************************************************************************** + *function: This function actually only set RRSR, RATR and BW_OPMODE registers + * not to do all the hw config as its name says + * input: net_device dev + * output: none + * return: none + * notice: This part need to modified according to the rate set we filtered + * ****************************************************************************/ +void rtl8192_hwconfig(struct net_device* dev) +{ + u32 regRATR = 0, regRRSR = 0; + u8 regBwOpMode = 0, regTmp = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + +// Set RRSR, RATR, and BW_OPMODE registers + // + switch(priv->ieee80211->mode) + { + case WIRELESS_MODE_B: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK; + regRRSR = RATE_ALL_CCK; + break; + case WIRELESS_MODE_A: + regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ; + regRATR = RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_G: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_AUTO: + case WIRELESS_MODE_N_24G: + // It support CCK rate by default. + // CCK rate will be filtered out only when associated AP does not support it. + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_N_5G: + regBwOpMode = BW_OPMODE_5G; + regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_OFDM_AG; + break; + } + + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + { + u32 ratr_value = 0; + ratr_value = regRATR; + if (priv->rf_type == RF_1T2R) + { + ratr_value &= ~(RATE_ALL_OFDM_2SS); + } + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); + } + regTmp = read_nic_byte(dev, 0x313); + regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); + write_nic_dword(dev, RRSR, regRRSR); + + // + // Set Retry Limit here + // + write_nic_word(dev, RETRY_LIMIT, + priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \ + priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT); + // Set Contention Window here + + // Set Tx AGC + + // Set Tx Antenna including Feedback control + + // Set Auto Rate fallback control + + +} + + +RT_STATUS rtl8192_adapter_start(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +// struct ieee80211_device *ieee = priv->ieee80211; + u32 ulRegRead; + RT_STATUS rtStatus = RT_STATUS_SUCCESS; +// static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG; +// static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG; + //u8 eRFPath; + u8 tmpvalue; +#ifdef RTL8192E + u8 ICVersion,SwitchingRegulatorOutput; +#endif + bool bfirmwareok = true; +#ifdef RTL8190P + u8 ucRegRead; +#endif + u32 tmpRegA, tmpRegC, TempCCk; + int i =0; +// u32 dwRegRead = 0; + + RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__); + priv->being_init_adapter = true; + rtl8192_pci_resetdescring(dev); + // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W. + priv->Rf_Mode = RF_OP_By_SW_3wire; +#ifdef RTL8192E + //dPLL on + if(priv->ResetProgress == RESET_TYPE_NORESET) + { + write_nic_byte(dev, ANAPAR, 0x37); + // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms + // Joseph increae the time to prevent firmware download fail + mdelay(500); + } +#endif + //PlatformSleepUs(10000); + // For any kind of InitializeAdapter process, we shall use system now!! + priv->pFirmware->firmware_status = FW_STATUS_0_INIT; + + // Set to eRfoff in order not to count receive count. + if(priv->RegRfOff == TRUE) + priv->ieee80211->eRFPowerState = eRfOff; + + // + //3 //Config CPUReset Register + //3// + //3 Firmware Reset Or Not + ulRegRead = read_nic_dword(dev, CPU_GEN); + if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT) + { //called from MPInitialized. do nothing + ulRegRead |= CPU_GEN_SYSTEM_RESET; + }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY) + ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset + else + RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status); + +#ifdef RTL8190P + //2008.06.03, for WOL 90 hw bug + ulRegRead &= (~(CPU_GEN_GPIO_UART)); +#endif + + write_nic_dword(dev, CPU_GEN, ulRegRead); + //mdelay(100); + +#ifdef RTL8192E + + //3// + //3 //Fix the issue of E-cut high temperature issue + //3// + // TODO: E cut only + ICVersion = read_nic_byte(dev, IC_VERRSION); + if(ICVersion >= 0x4) //E-cut only + { + // HW SD suggest that we should not wirte this register too often, so driver + // should readback this register. This register will be modified only when + // power on reset + SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR); + if(SwitchingRegulatorOutput != 0xb8) + { + write_nic_byte(dev, SWREGULATOR, 0xa8); + mdelay(1); + write_nic_byte(dev, SWREGULATOR, 0xb8); + } + } +#endif + + + //3// + //3// Initialize BB before MAC + //3// + //rtl8192_dump_reg(dev); + RT_TRACE(COMP_INIT, "BB Config Start!\n"); + rtStatus = rtl8192_BBConfig(dev); + if(rtStatus != RT_STATUS_SUCCESS) + { + RT_TRACE(COMP_ERR, "BB Config failed\n"); + return rtStatus; + } + RT_TRACE(COMP_INIT,"BB Config Finished!\n"); + + //rtl8192_dump_reg(dev); + // + //3//Set Loopback mode or Normal mode + //3// + //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings + // because setting of System_Reset bit reset MAC to default transmission mode. + //Loopback mode or not + priv->LoopbackMode = RTL819X_NO_LOOPBACK; + //priv->LoopbackMode = RTL819X_MAC_LOOPBACK; + if(priv->ResetProgress == RESET_TYPE_NORESET) + { + ulRegRead = read_nic_dword(dev, CPU_GEN); + if(priv->LoopbackMode == RTL819X_NO_LOOPBACK) + { + ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET); + } + else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK ) + { + ulRegRead |= CPU_CCK_LOOPBACK; + } + else + { + RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n"); + } + + //2008.06.03, for WOL + //ulRegRead &= (~(CPU_GEN_GPIO_UART)); + write_nic_dword(dev, CPU_GEN, ulRegRead); + + // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily + udelay(500); + } + //3Set Hardware(Do nothing now) + rtl8192_hwconfig(dev); + //2======================================================= + // Common Setting for all of the FPGA platform. (part 1) + //2======================================================= + // If there is changes, please make sure it applies to all of the FPGA version + //3 Turn on Tx/Rx + write_nic_byte(dev, CMDR, CR_RE|CR_TE); + + //2Set Tx dma burst +#ifdef RTL8190P + write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<dev_addr)[0]); + write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]); + //set RCR + write_nic_dword(dev, RCR, priv->ReceiveConfig); + + //3 Initialize Number of Reserved Pages in Firmware Queue + #ifdef TO_DO_LIST + if(priv->bInHctTest) + { + PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\ + NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \ + NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \ + NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <RegWirelessMode); + if(priv->ResetProgress == RESET_TYPE_NORESET) + rtl8192_SetWirelessMode(dev, priv->ieee80211->mode); + //----------------------------------------------------------------------------- + // Set up security related. 070106, by rcnjko: + // 1. Clear all H/W keys. + // 2. Enable H/W encryption/decryption. + //----------------------------------------------------------------------------- + CamResetAllEntry(dev); + { + u8 SECR_value = 0x0; + SECR_value |= SCR_TxEncEnable; + SECR_value |= SCR_RxDecEnable; + SECR_value |= SCR_NoSKMC; + write_nic_byte(dev, SECR, SECR_value); + } + //3Beacon related + write_nic_word(dev, ATIMWND, 2); + write_nic_word(dev, BCN_INTERVAL, 100); + { + int i; + for (i=0; icard_8192_version > (u8) VERSION_8190_BD) { + rtl8192_phy_getTxPower(dev); + rtl8192_phy_setTxPower(dev, priv->chan); + } + + //if D or C cut + tmpvalue = read_nic_byte(dev, IC_VERRSION); + priv->IC_Cut = tmpvalue; + RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut); + if(priv->IC_Cut >= IC_VersionCut_D) + { + //pHalData->bDcut = TRUE; + if(priv->IC_Cut == IC_VersionCut_D) + RT_TRACE(COMP_INIT, "D-cut\n"); + if(priv->IC_Cut == IC_VersionCut_E) + { + RT_TRACE(COMP_INIT, "E-cut\n"); + // HW SD suggest that we should not wirte this register too often, so driver + // should readback this register. This register will be modified only when + // power on reset + } + } + else + { + //pHalData->bDcut = FALSE; + RT_TRACE(COMP_INIT, "Before C-cut\n"); + } + +#if 1 + //Firmware download + RT_TRACE(COMP_INIT, "Load Firmware!\n"); + bfirmwareok = init_firmware(dev); + if(bfirmwareok != true) { + rtStatus = RT_STATUS_FAILURE; + return rtStatus; + } + RT_TRACE(COMP_INIT, "Load Firmware finished!\n"); +#endif + //RF config + if(priv->ResetProgress == RESET_TYPE_NORESET) + { + RT_TRACE(COMP_INIT, "RF Config Started!\n"); + rtStatus = rtl8192_phy_RFConfig(dev); + if(rtStatus != RT_STATUS_SUCCESS) + { + RT_TRACE(COMP_ERR, "RF Config failed\n"); + return rtStatus; + } + RT_TRACE(COMP_INIT, "RF Config Finished!\n"); + } + rtl8192_phy_updateInitGain(dev); + + /*---- Set CCK and OFDM Block "ON"----*/ + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); + +#ifdef RTL8192E + //Enable Led + write_nic_byte(dev, 0x87, 0x0); +#endif +#ifdef RTL8190P + //2008.06.03, for WOL + ucRegRead = read_nic_byte(dev, GPE); + ucRegRead |= BIT0; + write_nic_byte(dev, GPE, ucRegRead); + + ucRegRead = read_nic_byte(dev, GPO); + ucRegRead &= ~BIT0; + write_nic_byte(dev, GPO, ucRegRead); +#endif + + //2======================================================= + // RF Power Save + //2======================================================= +#ifdef ENABLE_IPS + +{ + if(priv->RegRfOff == TRUE) + { // User disable RF via registry. + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__); + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW); +#if 0//cosa, ask SD3 willis and he doesn't know what is this for + // Those action will be discard in MgntActSet_RF_State because off the same state + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); +#endif + } + else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { // H/W or S/W RF OFF before sleep. + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); + } + else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS) + { // H/W or S/W RF OFF before sleep. + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); + } + else + { + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__); + priv->ieee80211->eRFPowerState = eRfOn; + priv->ieee80211->RfOffReason = 0; + //DrvIFIndicateCurrentPhyStatus(Adapter); + // LED control + //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON); + + // + // If inactive power mode is enabled, disable rf while in disconnected state. + // But we should still tell upper layer we are in rf on state. + // 2007.07.16, by shien chang. + // + //if(!Adapter->bInHctTest) + //IPSEnter(Adapter); + + } +} +#endif + if(1){ +#ifdef RTL8192E + // We can force firmware to do RF-R/W + if(priv->ieee80211->FwRWRF) + priv->Rf_Mode = RF_OP_By_FW; + else + priv->Rf_Mode = RF_OP_By_SW_3wire; +#else + priv->Rf_Mode = RF_OP_By_SW_3wire; +#endif + } +#ifdef RTL8190P + if(priv->ResetProgress == RESET_TYPE_NORESET) + { + dm_initialize_txpower_tracking(dev); + + tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord); + tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord); + + if(priv->rf_type == RF_2T4R){ + for(i = 0; itxbbgain_table[i].txbbgain_value) + { + priv->rfa_txpowertrackingindex= (u8)i; + priv->rfa_txpowertrackingindex_real= (u8)i; + priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex; + break; + } + } + } + for(i = 0; itxbbgain_table[i].txbbgain_value) + { + priv->rfc_txpowertrackingindex= (u8)i; + priv->rfc_txpowertrackingindex_real= (u8)i; + priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex; + break; + } + } + TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + + for(i=0 ; icck_txbbgain_table[i].ccktxbb_valuearray[0]) + { + priv->CCKPresentAttentuation_20Mdefault =(u8) i; + break; + } + } + priv->CCKPresentAttentuation_40Mdefault = 0; + priv->CCKPresentAttentuation_difference = 0; + priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault; + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation); + } +#else + #ifdef RTL8192E + if(priv->ResetProgress == RESET_TYPE_NORESET) + { + dm_initialize_txpower_tracking(dev); + + if(priv->IC_Cut >= IC_VersionCut_D) + { + tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord); + tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord); + for(i = 0; itxbbgain_table[i].txbbgain_value) + { + priv->rfa_txpowertrackingindex= (u8)i; + priv->rfa_txpowertrackingindex_real= (u8)i; + priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex; + break; + } + } + + TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + + for(i=0 ; icck_txbbgain_table[i].ccktxbb_valuearray[0]) + { + priv->CCKPresentAttentuation_20Mdefault =(u8) i; + break; + } + } + priv->CCKPresentAttentuation_40Mdefault = 0; + priv->CCKPresentAttentuation_difference = 0; + priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault; + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation); + priv->btxpower_tracking = FALSE;//TEMPLY DISABLE + } + } + #endif +#endif + rtl8192_irq_enable(dev); + priv->being_init_adapter = false; + return rtStatus; + +} + +void rtl8192_prepare_beacon(struct r8192_priv *priv) +{ + struct sk_buff *skb; + //unsigned long flags; + cb_desc *tcb_desc; + + skb = ieee80211_get_beacon(priv->ieee80211); + tcb_desc = (cb_desc *)(skb->cb + 8); + //printk("===========> %s\n", __FUNCTION__); + //spin_lock_irqsave(&priv->tx_lock,flags); + /* prepare misc info for the beacon xmit */ + tcb_desc->queue_index = BEACON_QUEUE; + /* IBSS does not support HT yet, use 1M defautly */ + tcb_desc->data_rate = 2; + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + + skb_push(skb, priv->ieee80211->tx_headroom); + if(skb){ + rtl8192_tx(priv->ieee80211->dev,skb); + } + //spin_unlock_irqrestore (&priv->tx_lock, flags); +} + +#if 0 +void rtl8192_beacon_tx_enable(struct net_device *dev) +{ + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + + rtl8180_set_mode(dev,EPROM_CMD_CONFIG); +#ifdef CONFIG_RTL8185B + priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);MgntQuery_MgntFrameTxRateMgntQuery_MgntFrameTxRate + write_nic_byte(dev,TPPollStop, priv->dma_poll_mask); +#else + priv->dma_poll_mask &=~(1<dma_poll_mask); +#endif + rtl8180_set_mode(dev,EPROM_CMD_NORMAL); +} +#endif + + +/* this configures registers for beacon tx and enables it via + * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might + * be used to stop beacon transmission + */ +void rtl8192_start_beacon(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct ieee80211_network *net = &priv->ieee80211->current_network; + u16 BcnTimeCfg = 0; + u16 BcnCW = 6; + u16 BcnIFS = 0xf; + + DMESG("Enabling beacon TX"); + //rtl8192_prepare_beacon(dev); + rtl8192_irq_disable(dev); + //rtl8192_beacon_tx_enable(dev); + + /* ATIM window */ + write_nic_word(dev, ATIMWND, 2); + + /* Beacon interval (in unit of TU) */ + write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + + /* + * DrvErlyInt (in unit of TU). + * (Time to send interrupt to notify driver to c + * hange beacon content) + * */ + write_nic_word(dev, BCN_DRV_EARLY_INT, 10); + + /* + * BcnDMATIM(in unit of us). + * Indicates the time before TBTT to perform beacon queue DMA + * */ + write_nic_word(dev, BCN_DMATIME, 256); + + /* + * Force beacon frame transmission even after receiving + * beacon frame from other ad hoc STA + * */ + write_nic_byte(dev, BCN_ERR_THRESH, 100); + + /* Set CW and IFS */ + BcnTimeCfg |= BcnCW<ieee80211->stats; +} +#endif + + + +bool HalTxCheckStuck8190Pci(struct net_device *dev) +{ + u16 RegTxCounter = read_nic_word(dev, 0x128); + struct r8192_priv *priv = ieee80211_priv(dev); + bool bStuck = FALSE; + RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter); + if(priv->TxCounter==RegTxCounter) + bStuck = TRUE; + + priv->TxCounter = RegTxCounter; + + return bStuck; +} + +/* +* +* First added: 2006.11.19 by emily +*/ +RESET_TYPE +TxCheckStuck(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 QueueID; + ptx_ring head=NULL,tail=NULL,txring = NULL; + u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + bool bCheckFwTxCnt = false; + //unsigned long flags; + + // + // Decide Stuch threshold according to current power save mode + // + //printk("++++++++++++>%s()\n",__FUNCTION__); + switch (priv->ieee80211->dot11PowerSaveMode) + { + // The threshold value may required to be adjusted . + case eActive: // Active/Continuous access. + ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL; + break; + case eMaxPs: // Max power save mode. + ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + break; + case eFastPs: // Fast power save mode. + ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + break; + } + + // + // Check whether specific tcb has been queued for a specific time + // + for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) + { + + + if(QueueID == TXCMD_QUEUE) + continue; + + switch(QueueID) { + case MGNT_QUEUE: + tail=priv->txmapringtail; + head=priv->txmapringhead; + break; + + case BK_QUEUE: + tail=priv->txbkpringtail; + head=priv->txbkpringhead; + break; + + case BE_QUEUE: + tail=priv->txbepringtail; + head=priv->txbepringhead; + break; + + case VI_QUEUE: + tail=priv->txvipringtail; + head=priv->txvipringhead; + break; + + case VO_QUEUE: + tail=priv->txvopringtail; + head=priv->txvopringhead; + break; + + default: + tail=head=NULL; + break; + } + + if(tail == head) + continue; + else + { + txring = head; + if(txring == NULL) + { + RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__); + continue; + } + txring->nStuckCount++; + #if 0 + if(txring->nStuckCount > ResetThreshold) + { + RT_TRACE( COMP_RESET, "<== TxCheckStuck()\n" ); + return RESET_TYPE_NORMAL; + } + #endif + bCheckFwTxCnt = TRUE; + } + } +#if 1 + if(bCheckFwTxCnt) + { + if(HalTxCheckStuck8190Pci(dev)) + { + RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n"); + return RESET_TYPE_SILENT; + } + } +#endif + return RESET_TYPE_NORESET; +} + + +bool HalRxCheckStuck8190Pci(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u16 RegRxCounter = read_nic_word(dev, 0x130); + bool bStuck = FALSE; + static u8 rx_chk_cnt = 0; + RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter); + // If rssi is small, we should check rx for long time because of bad rx. + // or maybe it will continuous silent reset every 2 seconds. + rx_chk_cnt++; + if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) + { + rx_chk_cnt = 0; //high rssi, check rx stuck right now. + } + else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) && + ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) || + (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) ) + + { + if(rx_chk_cnt < 2) + { + return bStuck; + } + else + { + rx_chk_cnt = 0; + } + } + else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdbCurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdbundecorated_smoothed_pwdb >= VeryLowRSSI) + { + if(rx_chk_cnt < 4) + { + //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI); + return bStuck; + } + else + { + rx_chk_cnt = 0; + //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI); + } + } + else + { + if(rx_chk_cnt < 8) + { + //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI); + return bStuck; + } + else + { + rx_chk_cnt = 0; + //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI); + } + } +#if 0 + if (rx_chk_cnt < 2) + return bStuck; + else + rx_chk_cnt = 0; +#endif + if(priv->RxCounter==RegRxCounter) + bStuck = TRUE; + + priv->RxCounter = RegRxCounter; + + return bStuck; +} + +RESET_TYPE RxCheckStuck(struct net_device *dev) +{ + + if(HalRxCheckStuck8190Pci(dev)) + { + RT_TRACE(COMP_RESET, "RxStuck Condition\n"); + return RESET_TYPE_SILENT; + } + + return RESET_TYPE_NORESET; +} + +RESET_TYPE +rtl819x_ifcheck_resetornot(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RESET_TYPE TxResetType = RESET_TYPE_NORESET; + RESET_TYPE RxResetType = RESET_TYPE_NORESET; + RT_RF_POWER_STATE rfState; + + rfState = priv->ieee80211->eRFPowerState; + + TxResetType = TxCheckStuck(dev); +#if 1 + if( rfState != eRfOff && + /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/ + (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) + { + // If driver is in the status of firmware download failure , driver skips RF initialization and RF is + // in turned off state. Driver should check whether Rx stuck and do silent reset. And + // if driver is in firmware download failure status, driver should initialize RF in the following + // silent reset procedure Emily, 2008.01.21 + + // Driver should not check RX stuck in IBSS mode because it is required to + // set Check BSSID in order to send beacon, however, if check BSSID is + // set, STA cannot hear any packet a all. Emily, 2008.04.12 + RxResetType = RxCheckStuck(dev); + } +#endif + + RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType); + if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL) + return RESET_TYPE_NORMAL; + else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT) + return RESET_TYPE_SILENT; + else + return RESET_TYPE_NORESET; + +} + + +void CamRestoreAllEntry( struct net_device *dev) +{ + u8 EntryId = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + u8* MacAddr = priv->ieee80211->current_network.bssid; + + static u8 CAM_CONST_ADDR[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; + static u8 CAM_CONST_BROAD[] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n"); + + + if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)|| + (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) + { + + for(EntryId=0; EntryId<4; EntryId++) + { + { + MacAddr = CAM_CONST_ADDR[EntryId]; + setKey(dev, + EntryId , + EntryId, + priv->ieee80211->pairwise_key_type, + MacAddr, + 0, + NULL); + } + } + + } + else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) + { + + { + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + setKey(dev, + 4, + 0, + priv->ieee80211->pairwise_key_type, + (u8*)dev->dev_addr, + 0, + NULL); + else + setKey(dev, + 4, + 0, + priv->ieee80211->pairwise_key_type, + MacAddr, + 0, + NULL); + } + } + else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) + { + + { + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + setKey(dev, + 4, + 0, + priv->ieee80211->pairwise_key_type, + (u8*)dev->dev_addr, + 0, + NULL); + else + setKey(dev, + 4, + 0, + priv->ieee80211->pairwise_key_type, + MacAddr, + 0, + NULL); + } + } + + + + if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP) + { + MacAddr = CAM_CONST_BROAD; + for(EntryId=1 ; EntryId<4 ; EntryId++) + { + { + setKey(dev, + EntryId, + EntryId, + priv->ieee80211->group_key_type, + MacAddr, + 0, + NULL); + } + } + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + setKey(dev, + 0, + 0, + priv->ieee80211->group_key_type, + CAM_CONST_ADDR[0], + 0, + NULL); + } + else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP) + { + MacAddr = CAM_CONST_BROAD; + for(EntryId=1; EntryId<4 ; EntryId++) + { + { + setKey(dev, + EntryId , + EntryId, + priv->ieee80211->group_key_type, + MacAddr, + 0, + NULL); + } + } + + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + setKey(dev, + 0 , + 0, + priv->ieee80211->group_key_type, + CAM_CONST_ADDR[0], + 0, + NULL); + } +} + +void rtl8192_cancel_deferred_work(struct r8192_priv* priv); +int _rtl8192_up(struct net_device *dev); + +/* + * This function is used to fix Tx/Rx stop bug temporarily. + * This function will do "system reset" to NIC when Tx or Rx is stuck. + * The method checking Tx/Rx stuck of this function is supported by FW, + * which reports Tx and Rx counter to register 0x128 and 0x130. + * */ +void rtl819x_ifsilentreset(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 reset_times = 0; + int reset_status = 0; + struct ieee80211_device *ieee = priv->ieee80211; + + + // 2007.07.20. If we need to check CCK stop, please uncomment this line. + //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); + + if(priv->ResetProgress==RESET_TYPE_NORESET) + { +RESET_START: + + RT_TRACE(COMP_RESET,"=========>Reset progress!! \n"); + + // Set the variable for reset. + priv->ResetProgress = RESET_TYPE_SILENT; +// rtl8192_close(dev); +#if 1 + down(&priv->wx_sem); + if(priv->up == 0) + { + RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__); + up(&priv->wx_sem); + return ; + } + priv->up = 0; + RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__); + if(!netif_queue_stopped(dev)) + netif_stop_queue(dev); + + dm_backup_dynamic_mechanism_state(dev); + + rtl8192_irq_disable(dev); + rtl8192_cancel_deferred_work(priv); + deinit_hal_dm(dev); + del_timer_sync(&priv->watch_dog_timer); + ieee->sync_scan_hurryup = 1; + if(ieee->state == IEEE80211_LINKED) + { + down(&ieee->wx_sem); + printk("ieee->state is IEEE80211_LINKED\n"); + ieee80211_stop_send_beacons(priv->ieee80211); + del_timer_sync(&ieee->associate_timer); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&ieee->associate_retry_wq); +#endif + ieee80211_stop_scan(ieee); + netif_carrier_off(dev); + up(&ieee->wx_sem); + } + else{ + printk("ieee->state is NOT LINKED\n"); + ieee80211_softmac_stop_protocol(priv->ieee80211); + } + rtl8192_rtx_disable(dev); + up(&priv->wx_sem); + RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); + RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); + reset_status = _rtl8192_up(dev); + + RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__); + if(reset_status == -1) + { + if(reset_times < 3) + { + reset_times++; + goto RESET_START; + } + else + { + RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__); + } + } +#endif + ieee->is_silent_reset = 1; +#if 1 + EnableHWSecurityConfig8192(dev); +#if 1 + if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) + { + ieee->set_chan(ieee->dev, ieee->current_network.channel); + +#if 1 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_complete_wq); +#else + schedule_task(&ieee->associate_complete_wq); +#endif +#endif + + } + else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) + { + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->link_change(ieee->dev); + + // notify_wx_assoc_event(ieee); + + ieee80211_start_send_beacons(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + netif_carrier_on(ieee->dev); + } +#endif + + CamRestoreAllEntry(dev); + + // Restore the previous setting for all dynamic mechanism + dm_restore_dynamic_mechanism_state(dev); + + priv->ResetProgress = RESET_TYPE_NORESET; + priv->reset_count++; + + priv->bForcedSilentReset =false; + priv->bResetInProgress = false; + + // For test --> force write UFWP. + write_nic_byte(dev, UFWP, 1); + RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count); +#endif + } +} + +#ifdef ENABLE_IPS +void InactivePsWorkItemCallback(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + //u8 index = 0; + + RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n"); + // + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem + // is really scheduled. + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing + // blocks the IPS procedure of switching RF. + // By Bruce, 2007-12-25. + // + pPSC->bSwRfProcessing = TRUE; + + RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \ + pPSC->eInactivePowerState == eRfOff?"OFF":"ON"); + + + MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); + + // + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. + // +#if 0 + if(pPSC->eInactivePowerState == eRfOn) + CamRestoreAllEntry(dev); +#endif + pPSC->bSwRfProcessing = FALSE; + RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n"); +} + +// +// Description: +// Enter the inactive power save mode. RF will be off +// 2007.08.17, by shien chang. +// +void +IPSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + RT_RF_POWER_STATE rtState; + + if (pPSC->bInactivePs) + { + rtState = priv->ieee80211->eRFPowerState; + // + // Added by Bruce, 2007-12-25. + // Do not enter IPS in the following conditions: + // (1) RF is already OFF or Sleep + // (2) bSwRfProcessing (indicates the IPS is still under going) + // (3) Connectted (only disconnected can trigger IPS) + // (4) IBSS (send Beacon) + // (5) AP mode (send Beacon) + // + if (rtState == eRfOn && !pPSC->bSwRfProcessing + && (priv->ieee80211->state != IEEE80211_LINKED) ) + { + RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); + pPSC->eInactivePowerState = eRfOff; +// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); + InactivePsWorkItemCallback(dev); + } + } +} + +// +// Description: +// Leave the inactive power save mode, RF will be on. +// 2007.08.17, by shien chang. +// +void +IPSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + RT_RF_POWER_STATE rtState; + + if (pPSC->bInactivePs) + { + rtState = priv->ieee80211->eRFPowerState; + if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); + pPSC->eInactivePowerState = eRfOn; +// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); + InactivePsWorkItemCallback(dev); + } + } +} +#endif +void CAM_read_entry( + struct net_device *dev, + u32 iIndex +) +{ + u32 target_command=0; + u32 target_content=0; + u8 entry_i=0; + u32 ulStatus; + s32 i=100; +// printk("=======>start read CAM\n"); + for(entry_i=0;entry_i=0) + { + ulStatus = read_nic_dword(dev, RWCAM); + if(ulStatus & BIT31){ + continue; + } + else{ + break; + } + } +#endif + write_nic_dword(dev, RWCAM, target_command); + RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command); + // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command); + target_content = read_nic_dword(dev, RCAMO); + RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content); + // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content); + } + printk("\n"); +} + +void rtl819x_update_rxcounts( + struct r8192_priv *priv, + u32* TotalRxBcnNum, + u32* TotalRxDataNum +) +{ + u16 SlotIndex; + u8 i; + + *TotalRxBcnNum = 0; + *TotalRxDataNum = 0; + + SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum); + priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod; + priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod; + for( i=0; iieee80211->LinkDetectInfo.SlotNum; i++ ){ + *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i]; + *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i]; + } +} + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void rtl819x_watchdog_wqcallback(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq); + struct net_device *dev = priv->ieee80211->dev; +#else +extern void rtl819x_watchdog_wqcallback(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + struct ieee80211_device* ieee = priv->ieee80211; + RESET_TYPE ResetType = RESET_TYPE_NORESET; + static u8 check_reset_cnt=0; + unsigned long flags; + bool bBusyTraffic = false; + static u8 last_time = 0; + if(!priv->up) + return; + hal_dm_watchdog(dev); +#ifdef ENABLE_IPS +// printk("watch_dog ENABLE_IPS\n"); + if(ieee->actscanning == false){ + if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){ + if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ + printk("====================>haha:IPSEnter()\n"); + IPSEnter(dev); + //ieee80211_stop_scan(priv->ieee80211); + } + } + } +#endif + {//to get busy traffic condition + if(ieee->state == IEEE80211_LINKED) + { + if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 || + ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) { + bBusyTraffic = true; + } + + } + ieee->LinkDetectInfo.NumRxOkInPeriod = 0; + ieee->LinkDetectInfo.NumTxOkInPeriod = 0; + ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + } + + + //added by amy for AP roaming + if (1) + { + if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) + { + u32 TotalRxBcnNum = 0; + u32 TotalRxDataNum = 0; + + rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); + if((TotalRxBcnNum+TotalRxDataNum) == 0) + { + if( ieee->eRFPowerState == eRfOff) + RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); + printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); + // Dot11d_Reset(dev); + ieee->state = IEEE80211_ASSOCIATING; + notify_wx_assoc_event(priv->ieee80211); + RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); + ieee->is_roaming = true; + ieee->is_set_key = false; + ieee->link_change(dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + queue_work(ieee->wq, &ieee->associate_procedure_wq); +#else + schedule_task(&ieee->associate_procedure_wq); +#endif + } + } + ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; + ieee->LinkDetectInfo.NumRecvDataInPeriod=0; + + } +// CAM_read_entry(dev,0); + //check if reset the driver + spin_lock_irqsave(&priv->tx_lock,flags); + if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1)) + { + ResetType = rtl819x_ifcheck_resetornot(dev); + check_reset_cnt = 3; + //DbgPrint("Start to check silent reset\n"); + } + spin_unlock_irqrestore(&priv->tx_lock,flags); + if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) + { + priv->ResetProgress = RESET_TYPE_NORMAL; + RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__); + return; + } + /* disable silent reset temply 2008.9.11*/ +#if 1 + if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo + { + last_time = 1; + rtl819x_ifsilentreset(dev); + } + else + last_time = 0; +#endif + priv->force_reset = false; + priv->bForcedSilentReset = false; + priv->bResetInProgress = false; + RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); + +} + +void watch_dog_timer_callback(unsigned long data) +{ + struct r8192_priv *priv = ieee80211_priv((struct net_device *) data); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0); +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->watch_dog_wq); +#else + queue_work(priv->priv_wq,&priv->watch_dog_wq); +#endif +#endif + mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); + +} +int _rtl8192_up(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + //int i; + RT_STATUS init_status = RT_STATUS_SUCCESS; + priv->up=1; + priv->ieee80211->ieee_up=1; + RT_TRACE(COMP_INIT, "Bringing up iface"); + + init_status = rtl8192_adapter_start(dev); + if(init_status != RT_STATUS_SUCCESS) + { + RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); + return -1; + } + RT_TRACE(COMP_INIT, "start adapter finished\n"); +#ifdef RTL8192E + if(priv->ieee80211->eRFPowerState!=eRfOn) + MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason); +#endif + if(priv->ieee80211->state != IEEE80211_LINKED) + ieee80211_softmac_start_protocol(priv->ieee80211); + ieee80211_reset_queue(priv->ieee80211); + watch_dog_timer_callback((unsigned long) dev); + if(!netif_queue_stopped(dev)) + netif_start_queue(dev); + else + netif_wake_queue(dev); + + return 0; +} + + +int rtl8192_open(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int ret; + + down(&priv->wx_sem); + ret = rtl8192_up(dev); + up(&priv->wx_sem); + return ret; + +} + + +int rtl8192_up(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if (priv->up == 1) return -1; + + return _rtl8192_up(dev); +} + + +int rtl8192_close(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int ret; + + down(&priv->wx_sem); + + ret = rtl8192_down(dev); + + up(&priv->wx_sem); + + return ret; + +} + +int rtl8192_down(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +// int i; +#if 0 + u8 ucRegRead; + u32 ulRegRead; +#endif + if (priv->up == 0) return -1; + + priv->up=0; + priv->ieee80211->ieee_up = 0; + RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__); +/* FIXME */ + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + + rtl8192_irq_disable(dev); +#if 0 + if(!priv->ieee80211->bSupportRemoteWakeUp) { + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); + // 2006.11.30. System reset bit + ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead|=CPU_GEN_SYSTEM_RESET; + write_nic_dword(dev, CPU_GEN, ulRegRead); + } else { + //2008.06.03 for WOL + write_nic_dword(dev, WFCRC0, 0xffffffff); + write_nic_dword(dev, WFCRC1, 0xffffffff); + write_nic_dword(dev, WFCRC2, 0xffffffff); +#ifdef RTL8190P + //GPIO 0 = TRUE + ucRegRead = read_nic_byte(dev, GPO); + ucRegRead |= BIT0; + write_nic_byte(dev, GPO, ucRegRead); +#endif + //Write PMR register + write_nic_byte(dev, PMR, 0x5); + //Disable tx, enanble rx + write_nic_byte(dev, MacBlkCtrl, 0xa); + } +#endif +// flush_scheduled_work(); + rtl8192_cancel_deferred_work(priv); + deinit_hal_dm(dev); + del_timer_sync(&priv->watch_dog_timer); + + ieee80211_softmac_stop_protocol(priv->ieee80211); +#ifdef ENABLE_IPS + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); +#endif + rtl8192_rtx_disable(dev); + memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list)); + + RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__); + + return 0; +} + + +void rtl8192_commit(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if (priv->up == 0) return ; + + + ieee80211_softmac_stop_protocol(priv->ieee80211); + + rtl8192_irq_disable(dev); + rtl8192_rtx_disable(dev); + _rtl8192_up(dev); +} + +/* +void rtl8192_restart(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +void rtl8192_restart(struct work_struct *work) +{ + struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq); + struct net_device *dev = priv->ieee80211->dev; +#else +void rtl8192_restart(struct net_device *dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + + down(&priv->wx_sem); + + rtl8192_commit(dev); + + up(&priv->wx_sem); +} + +static void r8192_set_multicast(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + short promisc; + + //down(&priv->wx_sem); + + /* FIXME FIXME */ + + promisc = (dev->flags & IFF_PROMISC) ? 1:0; + + if (promisc != priv->promisc) { + ; + // rtl8192_commit(dev); + } + + priv->promisc = promisc; + + //schedule_work(&priv->reset_wq); + //up(&priv->wx_sem); +} + + +int r8192_set_mac_adr(struct net_device *dev, void *mac) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct sockaddr *addr = mac; + + down(&priv->wx_sem); + + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + schedule_work(&priv->reset_wq); +#else + schedule_task(&priv->reset_wq); +#endif + up(&priv->wx_sem); + + return 0; +} + +/* based on ipw2200 driver */ +int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct iwreq *wrq = (struct iwreq *)rq; + int ret=-1; + struct ieee80211_device *ieee = priv->ieee80211; + u32 key[4]; + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + struct iw_point *p = &wrq->u.data; + struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer; + + down(&priv->wx_sem); + + + if (p->length < sizeof(struct ieee_param) || !p->pointer){ + ret = -EINVAL; + goto out; + } + + ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + if (ipw == NULL){ + ret = -ENOMEM; + goto out; + } + if (copy_from_user(ipw, p->pointer, p->length)) { + kfree(ipw); + ret = -EFAULT; + goto out; + } + + switch (cmd) { + case RTL_IOCTL_WPA_SUPPLICANT: + //parse here for HW security + if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) + { + if (ipw->u.crypt.set_tx) + { + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->pairwise_key_type = KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->pairwise_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) + { + if (ipw->u.crypt.key_len == 13) + ieee->pairwise_key_type = KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->pairwise_key_type = KEY_TYPE_WEP40; + } + else + ieee->pairwise_key_type = KEY_TYPE_NA; + + if (ieee->pairwise_key_type) + { + memcpy((u8*)key, ipw->u.crypt.key, 16); + EnableHWSecurityConfig8192(dev); + //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching! + //added by WB. + setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); + if (ieee->auth_mode != 2) //LEAP WEP will never set this. + setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); + } + if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ + write_nic_byte(dev, 0x173, 1); //fix aes bug + } + + } + else //if (ipw->u.crypt.idx) //group key use idx > 0 + { + memcpy((u8*)key, ipw->u.crypt.key, 16); + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->group_key_type= KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->group_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) + { + if (ipw->u.crypt.key_len == 13) + ieee->group_key_type = KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->group_key_type = KEY_TYPE_WEP40; + } + else + ieee->group_key_type = KEY_TYPE_NA; + + if (ieee->group_key_type) + { + setKey( dev, + ipw->u.crypt.idx, + ipw->u.crypt.idx, //KeyIndex + ieee->group_key_type, //KeyType + broadcast_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + } + } +#ifdef JOHN_DEBUG + //john's test 0711 + { + int i; + printk("@@ wrq->u pointer = "); + for(i=0;iu.data.length;i++){ + if(i%10==0) printk("\n"); + printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] ); + } + printk("\n"); + } +#endif /*JOHN_DEBUG*/ + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data); + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + kfree(ipw); +out: + up(&priv->wx_sem); + + return ret; +} + +u8 HwRateToMRate90(bool bIsHT, u8 rate) +{ + u8 ret_rate = 0x02; + + if(!bIsHT) { + switch(rate) { + case DESC90_RATE1M: ret_rate = MGN_1M; break; + case DESC90_RATE2M: ret_rate = MGN_2M; break; + case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break; + case DESC90_RATE11M: ret_rate = MGN_11M; break; + case DESC90_RATE6M: ret_rate = MGN_6M; break; + case DESC90_RATE9M: ret_rate = MGN_9M; break; + case DESC90_RATE12M: ret_rate = MGN_12M; break; + case DESC90_RATE18M: ret_rate = MGN_18M; break; + case DESC90_RATE24M: ret_rate = MGN_24M; break; + case DESC90_RATE36M: ret_rate = MGN_36M; break; + case DESC90_RATE48M: ret_rate = MGN_48M; break; + case DESC90_RATE54M: ret_rate = MGN_54M; break; + + default: + RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT); + break; + } + + } else { + switch(rate) { + case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break; + case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break; + case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break; + case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break; + case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break; + case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break; + case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break; + case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break; + case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break; + case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break; + case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break; + case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break; + case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break; + case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break; + case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break; + case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break; + case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break; + + default: + RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT); + break; + } + } + + return ret_rate; +} + +/** + * Function: UpdateRxPktTimeStamp + * Overview: Recored down the TSF time stamp when receiving a packet + * + * Input: + * PADAPTER Adapter + * PRT_RFD pRfd, + * + * Output: + * PRT_RFD pRfd + * (pRfd->Status.TimeStampHigh is updated) + * (pRfd->Status.TimeStampLow is updated) + * Return: + * None + */ +void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + if(stats->bIsAMPDU && !stats->bFirstMPDU) { + stats->mac_time[0] = priv->LastRxDescTSFLow; + stats->mac_time[1] = priv->LastRxDescTSFHigh; + } else { + priv->LastRxDescTSFLow = stats->mac_time[0]; + priv->LastRxDescTSFHigh = stats->mac_time[1]; + } +} + +long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index. +{ + long signal_power; // in dBm. + + // Translate to dBm (x=0.5y-95). + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + + return signal_power; +} + +// +// Description: +// Update Rx signal related information in the packet reeived +// to RxStats. User application can query RxStats to realize +// current Rx signal status. +// +// Assumption: +// In normal operation, user only care about the information of the BSS +// and we shall invoke this function if the packet received is from the BSS. +// +void +rtl819x_update_rxsignalstatistics8190pci( + struct r8192_priv * priv, + struct ieee80211_rx_stats * pprevious_stats + ) +{ + int weighting = 0; + + //2 Update Rx Statistics (such as signal strength and signal quality). + + // Initila state + if(priv->stats.recv_signal_power == 0) + priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower; + + // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the + // reaction of smoothed Signal Power. + if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power) + weighting = 5; + else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power) + weighting = (-5); + // + // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated, + // so we record the correct power in Dbm here. By Bruce, 2008-03-07. + // + priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6; +} + +void +rtl8190_process_cck_rxpathsel( + struct r8192_priv * priv, + struct ieee80211_rx_stats * pprevious_stats + ) +{ +#ifdef RTL8190P //Only 90P 2T4R need to check + char last_cck_adc_pwdb[4]={0,0,0,0}; + u8 i; +//cosa add for Rx path selection + if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable) + { + if(pprevious_stats->bIsCCK && + (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon)) + { + /* record the cck adc_pwdb to the sliding window. */ + if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX) + { + priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX; + for(i=RF90_PATH_A; istats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index]; + priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i]; + } + } + for(i=RF90_PATH_A; istats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i]; + priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i]; + } + priv->stats.cck_adc_pwdb.index++; + if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX) + priv->stats.cck_adc_pwdb.index = 0; + + for(i=RF90_PATH_A; istats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum; + } + + for(i=RF90_PATH_A; icck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i]) + { + priv->undecorated_smoothed_cck_adc_pwdb[i] = + ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) + + (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor); + priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1; + } + else + { + priv->undecorated_smoothed_cck_adc_pwdb[i] = + ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) + + (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor); + } + } + } + } +#endif +} + + +/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to + be a local static. Otherwise, it may increase when we return from S3/S4. The + value will be kept in memory or disk. We must delcare the value in adapter + and it will be reinitialized when return from S3/S4. */ +void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats) +{ + bool bcheck = false; + u8 rfpath; + u32 nspatial_stream, tmp_val; + //u8 i; + static u32 slide_rssi_index=0, slide_rssi_statistics=0; + static u32 slide_evm_index=0, slide_evm_statistics=0; + static u32 last_rssi=0, last_evm=0; + //cosa add for rx path selection +// static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0; +// static char last_cck_adc_pwdb[4]={0,0,0,0}; + //cosa add for beacon rssi smoothing + static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0; + static u32 last_beacon_adc_pwdb=0; + + struct ieee80211_hdr_3addr *hdr; + u16 sc ; + unsigned int frag,seq; + hdr = (struct ieee80211_hdr_3addr *)buffer; + sc = le16_to_cpu(hdr->seq_ctl); + frag = WLAN_GET_SEQ_FRAG(sc); + seq = WLAN_GET_SEQ_SEQ(sc); + //cosa add 04292008 to record the sequence number + pcurrent_stats->Seq_Num = seq; + // + // Check whether we should take the previous packet into accounting + // + if(!pprevious_stats->bIsAMPDU) + { + // if previous packet is not aggregated packet + bcheck = true; + }else + { +//remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault. +#if 0 + // if previous packet is aggregated packet, and current packet + // (1) is not AMPDU + // (2) is the first packet of one AMPDU + // that means the previous packet is the last one aggregated packet + if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU) + bcheck = true; +#endif + } + + if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) + { + slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; + last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; + priv->stats.slide_rssi_total -= last_rssi; + } + priv->stats.slide_rssi_total += pprevious_stats->SignalStrength; + + priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength; + if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) + slide_rssi_index = 0; + + // <1> Showed on UI for user, in dbm + tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics; + priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val); + pcurrent_stats->rssi = priv->stats.signal_strength; + // + // If the previous packet does not match the criteria, neglect it + // + if(!pprevious_stats->bPacketMatchBSSID) + { + if(!pprevious_stats->bToSelfBA) + return; + } + + if(!bcheck) + return; + + rtl8190_process_cck_rxpathsel(priv,pprevious_stats); + + // + // Check RSSI + // + priv->stats.num_process_phyinfo++; +#if 0 + /* record the general signal strength to the sliding window. */ + if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) + { + slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; + last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; + priv->stats.slide_rssi_total -= last_rssi; + } + priv->stats.slide_rssi_total += pprevious_stats->SignalStrength; + + priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength; + if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) + slide_rssi_index = 0; + + // <1> Showed on UI for user, in dbm + tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics; + priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val); + +#endif + // <2> Showed on UI for engineering + // hardware does not provide rssi information for each rf path in CCK + if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf) + { + for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++) + { + if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath)) + continue; + RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] ); + //Fixed by Jacken 2008-03-20 + if(priv->stats.rx_rssi_percentage[rfpath] == 0) + { + priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath]; + //DbgPrint("MIMO RSSI initialize \n"); + } + if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) + { + priv->stats.rx_rssi_percentage[rfpath] = + ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) + + (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor); + priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1; + } + else + { + priv->stats.rx_rssi_percentage[rfpath] = + ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) + + (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor); + } + RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] ); + } + } + + + // + // Check PWDB. + // + //cosa add for beacon rssi smoothing by average. + if(pprevious_stats->bPacketBeacon) + { + /* record the beacon pwdb to the sliding window. */ + if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) + { + slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX; + last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index]; + priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb; + //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n", + // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total); + } + priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll; + priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll; + //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll); + slide_beacon_adc_pwdb_index++; + if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) + slide_beacon_adc_pwdb_index = 0; + pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics; + if(pprevious_stats->RxPWDBAll >= 3) + pprevious_stats->RxPWDBAll -= 3; + } + + RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n", + pprevious_stats->bIsCCK? "CCK": "OFDM", + pprevious_stats->RxPWDBAll); + + if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) + { + if(priv->undecorated_smoothed_pwdb < 0) // initialize + { + priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll; + //DbgPrint("First pwdb initialize \n"); + } +#if 1 + if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) + { + priv->undecorated_smoothed_pwdb = + ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) + + (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor); + priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1; + } + else + { + priv->undecorated_smoothed_pwdb = + ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) + + (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor); + } +#else + //Fixed by Jacken 2008-03-20 + if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB) + { + pHalData->UndecoratedSmoothedPWDB = + ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6; + pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1; + } + else + { + pHalData->UndecoratedSmoothedPWDB = + ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6; + } +#endif + rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats); + } + + // + // Check EVM + // + /* record the general EVM to the sliding window. */ + if(pprevious_stats->SignalQuality == 0) + { + } + else + { + if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){ + if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){ + slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; + last_evm = priv->stats.slide_evm[slide_evm_index]; + priv->stats.slide_evm_total -= last_evm; + } + + priv->stats.slide_evm_total += pprevious_stats->SignalQuality; + + priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality; + if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) + slide_evm_index = 0; + + // <1> Showed on UI for user, in percentage. + tmp_val = priv->stats.slide_evm_total/slide_evm_statistics; + priv->stats.signal_quality = tmp_val; + //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality. + priv->stats.last_signal_strength_inpercent = tmp_val; + } + + // <2> Showed on UI for engineering + if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) + { + for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream + { + if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) + { + if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize + { + priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream]; + } + priv->stats.rx_evm_percentage[nspatial_stream] = + ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) + + (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor); + } + } + } + } + +} + +/*----------------------------------------------------------------------------- + * Function: rtl819x_query_rxpwrpercentage() + * + * Overview: + * + * Input: char antpower + * + * Output: NONE + * + * Return: 0-100 percentage + * + * Revised History: + * When Who Remark + * 05/26/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static u8 rtl819x_query_rxpwrpercentage( + char antpower + ) +{ + if ((antpower <= -100) || (antpower >= 20)) + { + return 0; + } + else if (antpower >= 0) + { + return 100; + } + else + { + return (100+antpower); + } + +} /* QueryRxPwrPercentage */ + +static u8 +rtl819x_evm_dbtopercentage( + char value + ) +{ + char ret_val; + + ret_val = value; + + if(ret_val >= 0) + ret_val = 0; + if(ret_val <= -33) + ret_val = -33; + ret_val = 0 - ret_val; + ret_val*=3; + if(ret_val == 99) + ret_val = 100; + return(ret_val); +} + +// +// Description: +// We want good-looking for signal strength/quality +// 2007/7/19 01:09, by cosa. +// +long +rtl819x_signal_scale_mapping( + long currsig + ) +{ + long retsig; + + // Step 1. Scale mapping. + if(currsig >= 61 && currsig <= 100) + { + retsig = 90 + ((currsig - 60) / 4); + } + else if(currsig >= 41 && currsig <= 60) + { + retsig = 78 + ((currsig - 40) / 2); + } + else if(currsig >= 31 && currsig <= 40) + { + retsig = 66 + (currsig - 30); + } + else if(currsig >= 21 && currsig <= 30) + { + retsig = 54 + (currsig - 20); + } + else if(currsig >= 5 && currsig <= 20) + { + retsig = 42 + (((currsig - 5) * 2) / 3); + } + else if(currsig == 4) + { + retsig = 36; + } + else if(currsig == 3) + { + retsig = 27; + } + else if(currsig == 2) + { + retsig = 18; + } + else if(currsig == 1) + { + retsig = 9; + } + else + { + retsig = currsig; + } + + return retsig; +} + +static void rtl8192_query_rxphystatus( + struct r8192_priv * priv, + struct ieee80211_rx_stats * pstats, + prx_desc_819x_pci pdesc, + prx_fwinfo_819x_pci pdrvinfo, + struct ieee80211_rx_stats * precord_stats, + bool bpacket_match_bssid, + bool bpacket_toself, + bool bPacketBeacon, + bool bToSelfBA + ) +{ + //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status); + phy_sts_ofdm_819xpci_t* pofdm_buf; + phy_sts_cck_819xpci_t * pcck_buf; + phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc; + u8 *prxpkt; + u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg; + char rx_pwr[4], rx_pwr_all=0; + //long rx_avg_pwr = 0; + char rx_snrX, rx_evmX; + u8 evm, pwdb_all; + u32 RSSI, total_rssi=0;//, total_evm=0; +// long signal_strength_index = 0; + u8 is_cck_rate=0; + u8 rf_rx_num = 0; + + /* 2007/07/04 MH For OFDM RSSI. For high power or not. */ + static u8 check_reg824 = 0; + static u32 reg824_bit9 = 0; + + priv->stats.numqry_phystatus++; + + is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); + + // Record it for next packet processing + memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats)); + pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid; + pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; + pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo); + pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; + pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; + /*2007.08.30 requested by SD3 Jerry */ + if(check_reg824 == 0) + { + reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200); + check_reg824 = 1; + } + + + prxpkt = (u8*)pdrvinfo; + + /* Move pointer to the 16th bytes. Phy status start address. */ + prxpkt += sizeof(rx_fwinfo_819x_pci); + + /* Initial the cck and ofdm buffer pointer */ + pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt; + pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt; + + pstats->RxMIMOSignalQuality[0] = -1; + pstats->RxMIMOSignalQuality[1] = -1; + precord_stats->RxMIMOSignalQuality[0] = -1; + precord_stats->RxMIMOSignalQuality[1] = -1; + + if(is_cck_rate) + { + // + // (1)Hardware does not provide RSSI for CCK + // + + // + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + u8 report;//, cck_agc_rpt; +#ifdef RTL8190P + u8 tmp_pwdb; + char cck_adc_pwdb[4]; +#endif + priv->stats.numqry_phystatusCCK++; + +#ifdef RTL8190P //Only 90P 2T4R need to check + if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid) + { + for(i=RF90_PATH_A; iadc_pwdb_X[i]; + cck_adc_pwdb[i] = (char)tmp_pwdb; + cck_adc_pwdb[i] /= 2; + pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i]; + //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]); + } + } +#endif + + if(!reg824_bit9) + { + report = pcck_buf->cck_agc_rpt & 0xc0; + report = report>>6; + switch(report) + { + //Fixed by Jacken from Bryant 2008-03-20 + //Original value is -38 , -26 , -14 , -2 + //Fixed value is -35 , -23 , -11 , 6 + case 0x3: + rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e); + break; + } + } + else + { + report = pcck_buf->cck_agc_rpt & 0x60; + report = report>>5; + switch(report) + { + case 0x3: + rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x2: + rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1); + break; + case 0x1: + rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x0: + rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + } + } + + pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); + pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; + pstats->RecvSignalPower = rx_pwr_all; + + // + // (3) Get Signal Quality (EVM) + // + if(bpacket_match_bssid) + { + u8 sq; + + if(pstats->RxPWDBAll > 40) + { + sq = 100; + }else + { + sq = pcck_buf->sq_rpt; + + if(pcck_buf->sq_rpt > 64) + sq = 0; + else if (pcck_buf->sq_rpt < 20) + sq = 100; + else + sq = ((64-sq) * 100) / 44; + } + pstats->SignalQuality = precord_stats->SignalQuality = sq; + pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq; + pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1; + } + } + else + { + priv->stats.numqry_phystatusHT++; + // + // (1)Get RSSI for HT rate + // + for(i=RF90_PATH_A; ibrfpath_rxenable[i]) + rf_rx_num++; + //else + //continue; + + //Fixed by Jacken from Bryant 2008-03-20 + //Original value is 106 +#ifdef RTL8190P //Modify by Jacken 2008/03/31 + rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106; +#else + rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110; +#endif + + //Get Rx snr value in DB + tmp_rxsnr = pofdm_buf->rxsnr_X[i]; + rx_snrX = (char)(tmp_rxsnr); + rx_snrX /= 2; + priv->stats.rxSNRdB[i] = (long)rx_snrX; + + /* Translate DBM to percentage. */ + RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); + if (priv->brfpath_rxenable[i]) + total_rssi += RSSI; + + /* Record Signal Strength for next packet */ + if(bpacket_match_bssid) + { + pstats->RxMIMOSignalStrength[i] =(u8) RSSI; + precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI; + } + } + + + // + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + //Fixed by Jacken from Bryant 2008-03-20 + //Original value is 106 + rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106; + pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); + + pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; + pstats->RxPower = precord_stats->RxPower = rx_pwr_all; + pstats->RecvSignalPower = rx_pwr_all; + // + // (3)EVM of HT rate + // + if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 && + pdrvinfo->RxRate<=DESC90_RATEMCS15) + max_spatial_stream = 2; //both spatial stream make sense + else + max_spatial_stream = 1; //only spatial stream 1 makes sense + + for(i=0; irxevm_X[i]; + rx_evmX = (char)(tmp_rxevm); + + // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment + // fill most significant bit to "zero" when doing shifting operation which may change a negative + // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. + rx_evmX /= 2; //dbm + + evm = rtl819x_evm_dbtopercentage(rx_evmX); +#if 0 + EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100 +#endif + if(bpacket_match_bssid) + { + if(i==0) // Fill value in RFD, Get the first spatial stream only + pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff); + pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff); + } + } + + + /* record rx statistics for debug */ + rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg; + prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg; + if(pdrvinfo->BW) //40M channel + priv->stats.received_bwtype[1+prxsc->rxsc]++; + else //20M channel + priv->stats.received_bwtype[0]++; + } + + //UI BSS List signal strength(in percentage), make it good looking, from 0~100. + //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). + if(is_cck_rate) + { + pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL; + + } + else + { + //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX); + // We can judge RX path number now. + if (rf_rx_num != 0) + pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num))); + } +} /* QueryRxPhyStatus8190Pci */ + +void +rtl8192_record_rxdesc_forlateruse( + struct ieee80211_rx_stats * psrc_stats, + struct ieee80211_rx_stats * ptarget_stats +) +{ + ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; + ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; + //ptarget_stats->Seq_Num = psrc_stats->Seq_Num; +} + + + +void TranslateRxSignalStuff819xpci(struct net_device *dev, + struct sk_buff *skb, + struct ieee80211_rx_stats * pstats, + prx_desc_819x_pci pdesc, + prx_fwinfo_819x_pci pdrvinfo) +{ + // TODO: We must only check packet for current MAC address. Not finish + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + bool bpacket_match_bssid, bpacket_toself; + bool bPacketBeacon=false, bToSelfBA=false; + static struct ieee80211_rx_stats previous_stats; + struct ieee80211_hdr_3addr *hdr; + u16 fc,type; + + // Get Signal Quality for only RX data queue (but not command queue) + + u8* tmp_buf; + u8 *praddr; + + /* Get MAC frame start address. */ + tmp_buf = skb->data; + + hdr = (struct ieee80211_hdr_3addr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + + /* Check if the received packet is acceptabe. */ + bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) && + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) + && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); + bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr)); +#if 1//cosa + if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON) + { + bPacketBeacon = true; + //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf); + } + if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) + { + if((eqMacAddr(praddr,dev->dev_addr))) + bToSelfBA = true; + //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf); + } + +#endif + if(bpacket_match_bssid) + { + priv->stats.numpacket_matchbssid++; + } + if(bpacket_toself){ + priv->stats.numpacket_toself++; + } + // + // Process PHY information for previous packet (RSSI/PWDB/EVM) + // + // Because phy information is contained in the last packet of AMPDU only, so driver + // should process phy information of previous packet + rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats); + rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid, + bpacket_toself ,bPacketBeacon, bToSelfBA); + rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats); + +} + + +void rtl8192_tx_resume(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + struct sk_buff *skb; + int queue_index; + + for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) { + while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&& + (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) { + /* 1. dequeue the packet from the wait queue */ + skb = skb_dequeue(&ieee->skb_waitQ[queue_index]); + /* 2. tx the packet directly */ + ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/); + #if 0 + if(queue_index!=MGNT_QUEUE) { + ieee->stats.tx_packets++; + ieee->stats.tx_bytes += skb->len; + } + #endif + } + } +} + +void rtl8192_irq_tx_tasklet(struct r8192_priv *priv) +{ + rtl8192_tx_resume(priv->ieee80211->dev); +} + +/** +* Function: UpdateReceivedRateHistogramStatistics +* Overview: Recored down the received data rate +* +* Input: +* PADAPTER Adapter +* PRT_RFD pRfd, +* +* Output: +* PRT_TCB Adapter +* (Adapter->RxStats.ReceivedRateHistogram[] is updated) +* Return: +* None +*/ +void UpdateReceivedRateHistogramStatistics8190( + struct net_device *dev, + struct ieee80211_rx_stats* pstats + ) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV + u32 rateIndex; + u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI + + /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */ + #if 0 + if (pRfd->queue_id == CMPK_RX_QUEUE_ID) + return; + #endif + if(pstats->bCRC) + rcvType = 2; + else if(pstats->bICV) + rcvType = 3; + + if(pstats->bShortPreamble) + preamble_guardinterval = 1;// short + else + preamble_guardinterval = 0;// long + + switch(pstats->rate) + { + // + // CCK rate + // + case MGN_1M: rateIndex = 0; break; + case MGN_2M: rateIndex = 1; break; + case MGN_5_5M: rateIndex = 2; break; + case MGN_11M: rateIndex = 3; break; + // + // Legacy OFDM rate + // + case MGN_6M: rateIndex = 4; break; + case MGN_9M: rateIndex = 5; break; + case MGN_12M: rateIndex = 6; break; + case MGN_18M: rateIndex = 7; break; + case MGN_24M: rateIndex = 8; break; + case MGN_36M: rateIndex = 9; break; + case MGN_48M: rateIndex = 10; break; + case MGN_54M: rateIndex = 11; break; + // + // 11n High throughput rate + // + case MGN_MCS0: rateIndex = 12; break; + case MGN_MCS1: rateIndex = 13; break; + case MGN_MCS2: rateIndex = 14; break; + case MGN_MCS3: rateIndex = 15; break; + case MGN_MCS4: rateIndex = 16; break; + case MGN_MCS5: rateIndex = 17; break; + case MGN_MCS6: rateIndex = 18; break; + case MGN_MCS7: rateIndex = 19; break; + case MGN_MCS8: rateIndex = 20; break; + case MGN_MCS9: rateIndex = 21; break; + case MGN_MCS10: rateIndex = 22; break; + case MGN_MCS11: rateIndex = 23; break; + case MGN_MCS12: rateIndex = 24; break; + case MGN_MCS13: rateIndex = 25; break; + case MGN_MCS14: rateIndex = 26; break; + case MGN_MCS15: rateIndex = 27; break; + default: rateIndex = 28; break; + } + priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++; + priv->stats.received_rate_histogram[0][rateIndex]++; //total + priv->stats.received_rate_histogram[rcvType][rateIndex]++; +} + +void rtl8192_rx(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct ieee80211_hdr_1addr *ieee80211_hdr = NULL; + bool unicast_packet = false; + struct ieee80211_rx_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + .freq = IEEE80211_24GHZ_BAND, + }; + unsigned int count = priv->rxringcount; + + stats.nic_type = NIC_8192E; + + while (count--) { + rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor + struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt + + if (pdesc->OWN){ + /* wait data to be filled by hardware */ + return; + } else { + stats.bICV = pdesc->ICV; + stats.bCRC = pdesc->CRC32; + stats.bHwError = pdesc->CRC32 | pdesc->ICV; + + stats.Length = pdesc->Length; + if(stats.Length < 24) + stats.bHwError |= 1; + + if(stats.bHwError) { + stats.bShift = false; + + if(pdesc->CRC32) { + if (pdesc->Length <500) + priv->stats.rxcrcerrmin++; + else if (pdesc->Length >1000) + priv->stats.rxcrcerrmax++; + else + priv->stats.rxcrcerrmid++; + } + goto done; + } else { + prx_fwinfo_819x_pci pDrvInfo = NULL; + struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize); + + if (unlikely(!new_skb)) { + goto done; + } + + stats.RxDrvInfoSize = pdesc->RxDrvInfoSize; + stats.RxBufShift = ((pdesc->Shift)&0x03); + stats.Decrypted = !pdesc->SWDec; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + pci_dma_sync_single_for_cpu(priv->pdev, +#else + pci_unmap_single(priv->pdev, +#endif + *((dma_addr_t *)skb->cb), + priv->rxbuffersize, + PCI_DMA_FROMDEVICE); + skb_put(skb, pdesc->Length); + pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift); + skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift); + + stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate); + stats.bShortPreamble = pDrvInfo->SPLCP; + + /* it is debug only. It should be disabled in released driver. + * 2007.1.11 by Emily + * */ + UpdateReceivedRateHistogramStatistics8190(dev, &stats); + + stats.bIsAMPDU = (pDrvInfo->PartAggr==1); + stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1); + + stats.TimeStampLow = pDrvInfo->TSFL; + stats.TimeStampHigh = read_nic_dword(dev, TSFR+4); + + UpdateRxPktTimeStamp8190(dev, &stats); + + // + // Get Total offset of MPDU Frame Body + // + if((stats.RxBufShift + stats.RxDrvInfoSize) > 0) + stats.bShift = 1; + + stats.RxIs40MHzPacket = pDrvInfo->BW; + + /* ???? */ + TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo); + + /* Rx A-MPDU */ + if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1) + RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n", + pDrvInfo->FirstAGGR, pDrvInfo->PartAggr); + skb_trim(skb, skb->len - 4/*sCrcLng*/); + /* rx packets statistics */ + ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data; + unicast_packet = false; + + if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) { + //TODO + }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){ + //TODO + }else { + /* unicast packet */ + unicast_packet = true; + } + + stats.packetlength = stats.Length-4; + stats.fraglength = stats.packetlength; + stats.fragoffset = 0; + stats.ntotalfrag = 1; + + if(!ieee80211_rx(priv->ieee80211, skb, &stats)){ + dev_kfree_skb_any(skb); + } else { + priv->stats.rxok++; + if(unicast_packet) { + priv->stats.rxbytesunicast += skb->len; + } + } + + skb = new_skb; + priv->rx_buf[priv->rx_idx] = skb; + *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE); +// *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); + } + + } +done: + pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); + pdesc->OWN = 1; + pdesc->Length = priv->rxbuffersize; + if (priv->rx_idx == priv->rxringcount-1) + pdesc->EOR = 1; + priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount; + } + +} + +void rtl8192_irq_rx_tasklet(struct r8192_priv *priv) +{ + rtl8192_rx(priv->ieee80211->dev); + /* unmask RDU */ + write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU); +} + +static const struct net_device_ops rtl8192_netdev_ops = { + .ndo_open = rtl8192_open, + .ndo_stop = rtl8192_close, +/* .ndo_get_stats = rtl8192_stats, */ + .ndo_tx_timeout = tx_timeout, + .ndo_do_ioctl = rtl8192_ioctl, + .ndo_set_multicast_list = r8192_set_multicast, + .ndo_set_mac_address = r8192_set_mac_adr, + .ndo_start_xmit = ieee80211_xmit, +}; + +/**************************************************************************** + ---------------------------- PCI_STUFF--------------------------- +*****************************************************************************/ + +static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + unsigned long ioaddr = 0; + struct net_device *dev = NULL; + struct r8192_priv *priv= NULL; + u8 unit = 0; + +#ifdef CONFIG_RTL8192_IO_MAP + unsigned long pio_start, pio_len, pio_flags; +#else + unsigned long pmem_start, pmem_len, pmem_flags; +#endif //end #ifdef RTL_IO_MAP + + RT_TRACE(COMP_INIT,"Configuring chip resources"); + + if( pci_enable_device (pdev) ){ + RT_TRACE(COMP_ERR,"Failed to enable PCI device"); + return -EIO; + } + + pci_set_master(pdev); + //pci_set_wmi(pdev); + pci_set_dma_mask(pdev, 0xffffff00ULL); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + pci_set_consistent_dma_mask(pdev,0xffffff00ULL); +#endif + dev = alloc_ieee80211(sizeof(struct r8192_priv)); + if (!dev) + return -ENOMEM; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(dev); +#endif + + pci_set_drvdata(pdev, dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + SET_NETDEV_DEV(dev, &pdev->dev); +#endif + priv = ieee80211_priv(dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + priv->ieee80211 = netdev_priv(dev); +#else + priv->ieee80211 = (struct ieee80211_device *)dev->priv; +#endif + priv->pdev=pdev; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){ + priv->ieee80211->bSupportRemoteWakeUp = 1; + } else +#endif + { + priv->ieee80211->bSupportRemoteWakeUp = 0; + } + +#ifdef CONFIG_RTL8192_IO_MAP + + pio_start = (unsigned long)pci_resource_start (pdev, 0); + pio_len = (unsigned long)pci_resource_len (pdev, 0); + pio_flags = (unsigned long)pci_resource_flags (pdev, 0); + + if (!(pio_flags & IORESOURCE_IO)) { + RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting"); + goto fail; + } + + //DMESG("IO space @ 0x%08lx", pio_start ); + if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){ + RT_TRACE(COMP_ERR,"request_region failed!"); + goto fail; + } + + ioaddr = pio_start; + dev->base_addr = ioaddr; // device I/O address + +#else + + pmem_start = pci_resource_start(pdev, 1); + pmem_len = pci_resource_len(pdev, 1); + pmem_flags = pci_resource_flags (pdev, 1); + + if (!(pmem_flags & IORESOURCE_MEM)) { + RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting"); + goto fail; + } + + //DMESG("Memory mapped space @ 0x%08lx ", pmem_start); + if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) { + RT_TRACE(COMP_ERR,"request_mem_region failed!"); + goto fail; + } + + + ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len); + if( ioaddr == (unsigned long)NULL ){ + RT_TRACE(COMP_ERR,"ioremap failed!"); + // release_mem_region( pmem_start, pmem_len ); + goto fail1; + } + + dev->mem_start = ioaddr; // shared mem start + dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end + +#endif //end #ifdef RTL_IO_MAP + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, 0x41, 0x00); + + + pci_read_config_byte(pdev, 0x05, &unit); + pci_write_config_byte(pdev, 0x05, unit & (~0x04)); + + dev->irq = pdev->irq; + priv->irq = 0; + + dev->netdev_ops = &rtl8192_netdev_ops; +#if 0 + dev->open = rtl8192_open; + dev->stop = rtl8192_close; + //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit; + dev->tx_timeout = tx_timeout; + //dev->wireless_handlers = &r8192_wx_handlers_def; + dev->do_ioctl = rtl8192_ioctl; + dev->set_multicast_list = r8192_set_multicast; + dev->set_mac_address = r8192_set_mac_adr; +#endif + + //DMESG("Oops: i'm coming\n"); +#if WIRELESS_EXT >= 12 +#if WIRELESS_EXT < 17 + dev->get_wireless_stats = r8192_get_wireless_stats; +#endif + dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def; +#endif + //dev->get_wireless_stats = r8192_get_wireless_stats; + dev->type=ARPHRD_ETHER; + + dev->watchdog_timeo = HZ*3; //modified by john, 0805 + + if (dev_alloc_name(dev, ifname) < 0){ + RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); + ifname = "wlan%d"; + dev_alloc_name(dev, ifname); + } + + RT_TRACE(COMP_INIT, "Driver probe completed1\n"); + if(rtl8192_init(dev)!=0){ + RT_TRACE(COMP_ERR, "Initialization failed"); + goto fail; + } + + netif_carrier_off(dev); + netif_stop_queue(dev); + + register_netdev(dev); + RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name); + rtl8192_proc_init_one(dev); + + + RT_TRACE(COMP_INIT, "Driver probe completed\n"); +//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +// return dev; +//#else + return 0; +//#endif + +fail1: + +#ifdef CONFIG_RTL8180_IO_MAP + + if( dev->base_addr != 0 ){ + + release_region(dev->base_addr, + pci_resource_len(pdev, 0) ); + } +#else + if( dev->mem_start != (unsigned long)NULL ){ + iounmap( (void *)dev->mem_start ); + release_mem_region( pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1) ); + } +#endif //end #ifdef RTL_IO_MAP + +fail: + if(dev){ + + if (priv->irq) { + free_irq(dev->irq, dev); + dev->irq=0; + } + free_ieee80211(dev); + } + + pci_disable_device(pdev); + + DMESG("wlan driver load failed\n"); + pci_set_drvdata(pdev, NULL); + return -ENODEV; + +} + +/* detach all the work and timer structure declared or inititialized + * in r8192_init function. + * */ +void rtl8192_cancel_deferred_work(struct r8192_priv* priv) +{ + /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code + * is or is newer than 2.6.20 and work structure is defined to be struct work_struct. + * Otherwise call cancel_delayed_work is enough. + * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel) + * */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&priv->watch_dog_wq); + cancel_delayed_work(&priv->update_beacon_wq); + cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); + cancel_delayed_work(&priv->ieee80211->hw_sleep_wq); +#ifdef RTL8192E + cancel_delayed_work(&priv->gpio_change_rf_wq); +#endif +#endif +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,22) + cancel_work_sync(&priv->reset_wq); + cancel_work_sync(&priv->qos_activate); + //cancel_work_sync(&priv->SetBWModeWorkItem); + //cancel_work_sync(&priv->SwChnlWorkItem); +#else +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&priv->reset_wq); + cancel_delayed_work(&priv->qos_activate); + //cancel_delayed_work(&priv->SetBWModeWorkItem); + //cancel_delayed_work(&priv->SwChnlWorkItem); +#endif +#endif + +} + + +static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct r8192_priv *priv ; + + if(dev){ + + unregister_netdev(dev); + + priv=ieee80211_priv(dev); + + rtl8192_proc_remove_one(dev); + + rtl8192_down(dev); + if (priv->pFirmware) + { + vfree(priv->pFirmware); + priv->pFirmware = NULL; + } + // priv->rf_close(dev); + // rtl8192_usb_deleteendpoints(dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + destroy_workqueue(priv->priv_wq); +#endif + /* redundant with rtl8192_down */ + // rtl8192_irq_disable(dev); + // rtl8192_reset(dev); + // mdelay(10); + { + u32 i; + /* free tx/rx rings */ + rtl8192_free_rx_ring(dev); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { + rtl8192_free_tx_ring(dev, i); + } + } + if(priv->irq){ + + printk("Freeing irq %d\n",dev->irq); + free_irq(dev->irq, dev); + priv->irq=0; + + } + + + + // free_beacon_desc_ring(dev,priv->txbeaconcount); + +#ifdef CONFIG_RTL8180_IO_MAP + + if( dev->base_addr != 0 ){ + + release_region(dev->base_addr, + pci_resource_len(pdev, 0) ); + } +#else + if( dev->mem_start != (unsigned long)NULL ){ + iounmap( (void *)dev->mem_start ); + release_mem_region( pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1) ); + } +#endif /*end #ifdef RTL_IO_MAP*/ + free_ieee80211(dev); + + } + + pci_disable_device(pdev); + RT_TRACE(COMP_DOWN, "wlan driver removed\n"); +} + +extern int ieee80211_init(void); +extern void ieee80211_exit(void); + +static int __init rtl8192_pci_module_init(void) +{ + int retval; + + retval = ieee80211_init(); + if (retval) + return retval; + + printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n"); + printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n"); + RT_TRACE(COMP_INIT, "Initializing module"); + RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT); + rtl8192_proc_module_init(); +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) + if(0!=pci_module_init(&rtl8192_pci_driver)) +#else + if(0!=pci_register_driver(&rtl8192_pci_driver)) +#endif + { + DMESG("No device found"); + /*pci_unregister_driver (&rtl8192_pci_driver);*/ + return -ENODEV; + } + return 0; +} + + +static void __exit rtl8192_pci_module_exit(void) +{ + pci_unregister_driver(&rtl8192_pci_driver); + + RT_TRACE(COMP_DOWN, "Exiting"); + rtl8192_proc_module_remove(); + ieee80211_exit(); +} + +//warning message WB +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +void rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs) +#else +irqreturn_t rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs) +#endif +#else +irqreturn_t rtl8192_interrupt(int irq, void *netdev) +#endif +{ + struct net_device *dev = (struct net_device *) netdev; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + unsigned long flags; + u32 inta; + /* We should return IRQ_NONE, but for now let me keep this */ + if(priv->irq_enabled == 0){ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return; +#else + return IRQ_HANDLED; +#endif + } + + spin_lock_irqsave(&priv->irq_th_lock,flags); + + //ISR: 4bytes + + inta = read_nic_dword(dev, ISR);// & priv->IntrMask; + write_nic_dword(dev,ISR,inta); // reset int situation + + priv->stats.shints++; + //DMESG("Enter interrupt, ISR value = 0x%08x", inta); + if(!inta){ + spin_unlock_irqrestore(&priv->irq_th_lock,flags); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return; +#else + return IRQ_HANDLED; +#endif + /* + most probably we can safely return IRQ_NONE, + but for now is better to avoid problems + */ + } + + if(inta == 0xffff){ + /* HW disappared */ + spin_unlock_irqrestore(&priv->irq_th_lock,flags); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return; +#else + return IRQ_HANDLED; +#endif + } + + priv->stats.ints++; +#ifdef DEBUG_IRQ + DMESG("NIC irq %x",inta); +#endif + //priv->irqpending = inta; + + + if(!netif_running(dev)) { + spin_unlock_irqrestore(&priv->irq_th_lock,flags); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return; +#else + return IRQ_HANDLED; +#endif + } + + if(inta & IMR_TIMEOUT0){ + // write_nic_dword(dev, TimerInt, 0); + //DMESG("=================>waking up"); + // rtl8180_hw_wakeup(dev); + } + + if(inta & IMR_TBDOK){ + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + rtl8192_tx_isr(dev, BEACON_QUEUE); + priv->stats.txbeaconokint++; + } + + if(inta & IMR_TBDER){ + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + rtl8192_tx_isr(dev, BEACON_QUEUE); + priv->stats.txbeaconerr++; + } + + if(inta & IMR_MGNTDOK ) { + RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); + priv->stats.txmanageokint++; + rtl8192_tx_isr(dev,MGNT_QUEUE); + + } + + if(inta & IMR_COMDOK) + { + priv->stats.txcmdpktokint++; + rtl8192_tx_isr(dev,TXCMD_QUEUE); + } + + if(inta & IMR_ROK){ +#ifdef DEBUG_RX + DMESG("Frame arrived !"); +#endif + priv->stats.rxint++; + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if(inta & IMR_BcnInt) { + RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); + tasklet_schedule(&priv->irq_prepare_beacon_tasklet); + } + + if(inta & IMR_RDU){ + RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); + priv->stats.rxrdu++; + /* reset int situation */ + write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU); + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if(inta & IMR_RXFOVW){ + RT_TRACE(COMP_INTR, "rx overflow !\n"); + priv->stats.rxoverflow++; + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if(inta & IMR_TXFOVW) priv->stats.txoverflow++; + + if(inta & IMR_BKDOK){ + RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); + priv->stats.txbkokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev,BK_QUEUE); + rtl8192_try_wake_queue(dev, BK_QUEUE); + } + + if(inta & IMR_BEDOK){ + RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); + priv->stats.txbeokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev,BE_QUEUE); + rtl8192_try_wake_queue(dev, BE_QUEUE); + } + + if(inta & IMR_VIDOK){ + RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); + priv->stats.txviokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev,VI_QUEUE); + rtl8192_try_wake_queue(dev, VI_QUEUE); + } + + if(inta & IMR_VODOK){ + priv->stats.txvookint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev,VO_QUEUE); + rtl8192_try_wake_queue(dev, VO_QUEUE); + } + + force_pci_posting(dev); + spin_unlock_irqrestore(&priv->irq_th_lock,flags); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + return; +#else + return IRQ_HANDLED; +#endif +} + +void rtl8192_try_wake_queue(struct net_device *dev, int pri) +{ +#if 0 + unsigned long flags; + short enough_desc; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + + spin_lock_irqsave(&priv->tx_lock,flags); + enough_desc = check_nic_enough_desc(dev,pri); + spin_unlock_irqrestore(&priv->tx_lock,flags); + + if(enough_desc) + ieee80211_wake_queue(priv->ieee80211); +#endif +} + + +void EnableHWSecurityConfig8192(struct net_device *dev) +{ + u8 SECR_value = 0x0; + // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev); + //printk("==>ieee1:%p, dev:%p\n", ieee1, dev); + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + //printk("==>ieee:%p, dev:%p\n", ieee, dev); + SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; +#if 1 + if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) + { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } + else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) + { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } + +#endif + + //add HWSec active enable here. +//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4 + ieee->hwsec_active = 1; + + if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off + { + ieee->hwsec_active = 0; + SECR_value &= ~SCR_RxDecEnable; + } + + RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \ + ieee->hwsec_active, ieee->pairwise_key_type, SECR_value); + { + write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK ); + } + +} +#define TOTAL_CAM_ENTRY 32 +//#define CAM_CONTENT_COUNT 8 +void setKey( struct net_device *dev, + u8 EntryNo, + u8 KeyIndex, + u16 KeyType, + u8 *MacAddr, + u8 DefaultKey, + u32 *KeyContent ) +{ + u32 TargetCommand = 0; + u32 TargetContent = 0; + u16 usConfig = 0; + u8 i; +#ifdef ENABLE_IPS + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + rtState = priv->ieee80211->eRFPowerState; + if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if(rtState == eRfOff){ + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); + up(&priv->wx_sem); + return ; + } + else{ + IPSLeave(dev); + } + } + } + priv->ieee80211->is_set_key = true; +#endif + if (EntryNo >= TOTAL_CAM_ENTRY) + RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); + + RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); + + if (DefaultKey) + usConfig |= BIT15 | (KeyType<<2); + else + usConfig |= BIT15 | (KeyType<<2) | KeyIndex; +// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex; + + + for(i=0 ; iafter set key, usconfig:%x\n", usConfig); +// CAM_read_entry(dev, 0); +} +// This function seems not ready! WB +void CamPrintDbgReg(struct net_device* dev) +{ + unsigned long rvalue; + unsigned char ucValue; + write_nic_dword(dev, DCAM, 0x80000000); + msleep(40); + rvalue = read_nic_dword(dev, DCAM); //delay_ms(40); + RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue); + if((rvalue & 0x40000000) != 0x4000000) + RT_TRACE(COMP_SEC, "-->TX Key Not Found "); + msleep(20); + write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40); + rvalue = read_nic_dword(dev, DCAM); //delay_ms(40); + RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue); + if((rvalue & 0x40000000) != 0x4000000) + RT_TRACE(COMP_SEC, "-->CAM Key Not Found "); + ucValue = read_nic_byte(dev, SECR); + RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue); +} + + +/*************************************************************************** + ------------------- module init / exit stubs ---------------- +****************************************************************************/ +module_init(rtl8192_pci_module_init); +module_exit(rtl8192_pci_module_exit); diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c new file mode 100644 index 00000000000..596e500126c --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -0,0 +1,4257 @@ +/*++ +Copyright-c Realtek Semiconductor Corp. All rights reserved. + +Module Name: + r8192U_dm.c + +Abstract: + HW dynamic mechanism. + +Major Change History: + When Who What + ---------- --------------- ------------------------------- + 2008-05-14 amy create version 0 porting from windows code. + +--*/ +#include "r8192E.h" +#include "r8192E_dm.h" +#include "r8192E_hw.h" +#include "r819xE_phy.h" +#include "r819xE_phyreg.h" +#include "r8190_rtl8256.h" +/*---------------------------Define Local Constant---------------------------*/ +// +// Indicate different AP vendor for IOT issue. +// +#ifdef RTL8190P +static u32 edca_setting_DL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; +static u32 edca_setting_UL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; +#else +#ifdef RTL8192E +static u32 edca_setting_DL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; +static u32 edca_setting_UL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; +#else +static u32 edca_setting_DL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f}; +static u32 edca_setting_UL[HT_IOT_PEER_MAX] = +{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f}; +#endif +#endif + +#define RTK_UL_EDCA 0xa44f +#define RTK_DL_EDCA 0x5e4322 +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ +// Debug variable ? +dig_t dm_digtable; +// Store current shoftware write register content for MAC PHY. +u8 dm_shadow[16][256] = {{0}}; +// For Dynamic Rx Path Selection by Signal Strength +DRxPathSel DM_RxPathSelTable; +/*------------------------Define global variable-----------------------------*/ + + +/*------------------------Define local variable------------------------------*/ +/*------------------------Define local variable------------------------------*/ + + +/*--------------------Define export function prototype-----------------------*/ +extern void init_hal_dm(struct net_device *dev); +extern void deinit_hal_dm(struct net_device *dev); + +extern void hal_dm_watchdog(struct net_device *dev); + + +extern void init_rate_adaptive(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_txpower_trackingcallback(struct work_struct *work); +#else +extern void dm_txpower_trackingcallback(struct net_device *dev); +#endif + +extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); +extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); +extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); +extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, + u32 dm_value); +extern void DM_ChangeFsyncSetting(struct net_device *dev, + s32 DM_Type, + s32 DM_Value); +extern void dm_force_tx_fw_info(struct net_device *dev, + u32 force_type, + u32 force_value); +extern void dm_init_edca_turbo(struct net_device *dev); +extern void dm_rf_operation_test_callback(unsigned long data); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work); +#else +extern void dm_rf_pathcheck_workitemcallback(struct net_device *dev); +#endif +extern void dm_fsync_timer_callback(unsigned long data); +#if 0 +extern bool dm_check_lbus_status(struct net_device *dev); +#endif +extern void dm_check_fsync(struct net_device *dev); +extern void dm_shadow_init(struct net_device *dev); +extern void dm_initialize_txpower_tracking(struct net_device *dev); + +#ifdef RTL8192E +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_gpio_change_rf_callback(struct work_struct *work); +#else +extern void dm_gpio_change_rf_callback(struct net_device *dev); +#endif +#endif + + + +/*--------------------Define export function prototype-----------------------*/ + + +/*---------------------Define local function prototype-----------------------*/ +// DM --> Rate Adaptive +static void dm_check_rate_adaptive(struct net_device *dev); + +// DM --> Bandwidth switch +static void dm_init_bandwidth_autoswitch(struct net_device *dev); +static void dm_bandwidth_autoswitch( struct net_device *dev); + +// DM --> TX power control +//static void dm_initialize_txpower_tracking(struct net_device *dev); + +static void dm_check_txpower_tracking(struct net_device *dev); + + + +//static void dm_txpower_reset_recovery(struct net_device *dev); + + +// DM --> BB init gain restore +#ifndef RTL8192U +static void dm_bb_initialgain_restore(struct net_device *dev); + + +// DM --> BB init gain backup +static void dm_bb_initialgain_backup(struct net_device *dev); +#endif + +// DM --> Dynamic Init Gain by RSSI +static void dm_dig_init(struct net_device *dev); +static void dm_ctrl_initgain_byrssi(struct net_device *dev); +static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); +static void dm_ctrl_initgain_byrssi_by_driverrssi( struct net_device *dev); +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev); +static void dm_initial_gain(struct net_device *dev); +static void dm_pd_th(struct net_device *dev); +static void dm_cs_ratio(struct net_device *dev); + +static void dm_init_ctstoself(struct net_device *dev); +// DM --> EDCA turboe mode control +static void dm_check_edca_turbo(struct net_device *dev); + +// DM --> HW RF control +static void dm_check_rfctrl_gpio(struct net_device *dev); + +#ifndef RTL8190P +//static void dm_gpio_change_rf(struct net_device *dev); +#endif +// DM --> Check PBC +static void dm_check_pbc_gpio(struct net_device *dev); + + +// DM --> Check current RX RF path state +static void dm_check_rx_path_selection(struct net_device *dev); +static void dm_init_rxpath_selection(struct net_device *dev); +static void dm_rxpath_sel_byrssi(struct net_device *dev); + + +// DM --> Fsync for broadcom ap +static void dm_init_fsync(struct net_device *dev); +static void dm_deInit_fsync(struct net_device *dev); + +//Added by vivi, 20080522 +static void dm_check_txrateandretrycount(struct net_device *dev); + +/*---------------------Define local function prototype-----------------------*/ + +/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18 +static void dm_init_dynamic_txpower(struct net_device *dev); +static void dm_dynamic_txpower(struct net_device *dev); + + +// DM --> For rate adaptive and DIG, we must send RSSI to firmware +static void dm_send_rssi_tofw(struct net_device *dev); +static void dm_ctstoself(struct net_device *dev); +/*---------------------------Define function prototype------------------------*/ +//================================================================================ +// HW Dynamic mechanism interface. +//================================================================================ + +// +// Description: +// Prepare SW resource for HW dynamic mechanism. +// +// Assumption: +// This function is only invoked at driver intialization once. +// +// +extern void +init_hal_dm(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. + priv->undecorated_smoothed_pwdb = -1; + + //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. + dm_init_dynamic_txpower(dev); + init_rate_adaptive(dev); + //dm_initialize_txpower_tracking(dev); + dm_dig_init(dev); + dm_init_edca_turbo(dev); + dm_init_bandwidth_autoswitch(dev); + dm_init_fsync(dev); + dm_init_rxpath_selection(dev); + dm_init_ctstoself(dev); +#ifdef RTL8192E +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback); +#else + INIT_WORK(&priv->gpio_change_rf_wq, (void(*)(void*)) dm_gpio_change_rf_callback,dev); +#endif +#endif + +} // InitHalDm + +extern void deinit_hal_dm(struct net_device *dev) +{ + + dm_deInit_fsync(dev); + +} + + +#ifdef USB_RX_AGGREGATION_SUPPORT +void dm_CheckRxAggregation(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); + PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; + static unsigned long lastTxOkCnt = 0; + static unsigned long lastRxOkCnt = 0; + unsigned long curTxOkCnt = 0; + unsigned long curRxOkCnt = 0; + +/* + if (pHalData->bForcedUsbRxAggr) { + if (pHalData->ForcedUsbRxAggrInfo == 0) { + if (pHalData->bCurrentRxAggrEnable) { + Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE); + } + } else { + if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) { + Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE); + } + } + return; + } + +*/ + curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; + curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; + + if((curTxOkCnt + curRxOkCnt) < 15000000) { + return; + } + + if(curTxOkCnt > 4*curRxOkCnt) { + if (priv->bCurrentRxAggrEnable) { + write_nic_dword(dev, 0x1a8, 0); + priv->bCurrentRxAggrEnable = false; + } + }else{ + if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) { + u32 ulValue; + ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) | + (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout); + /* + * If usb rx firmware aggregation is enabled, + * when anyone of three threshold conditions above is reached, + * firmware will send aggregated packet to driver. + */ + write_nic_dword(dev, 0x1a8, ulValue); + priv->bCurrentRxAggrEnable = true; + } + } + + lastTxOkCnt = priv->stats.txbytesunicast; + lastRxOkCnt = priv->stats.rxbytesunicast; +} // dm_CheckEdcaTurbo +#endif + + + +extern void hal_dm_watchdog(struct net_device *dev) +{ + //struct r8192_priv *priv = ieee80211_priv(dev); + + //static u8 previous_bssid[6] ={0}; + + /*Add by amy 2008/05/15 ,porting from windows code.*/ + dm_check_rate_adaptive(dev); + dm_dynamic_txpower(dev); + dm_check_txrateandretrycount(dev); + + dm_check_txpower_tracking(dev); + + dm_ctrl_initgain_byrssi(dev); + dm_check_edca_turbo(dev); + dm_bandwidth_autoswitch(dev); + + dm_check_rfctrl_gpio(dev); + dm_check_rx_path_selection(dev); + dm_check_fsync(dev); + + // Add by amy 2008-05-15 porting from windows code. + dm_check_pbc_gpio(dev); + dm_send_rssi_tofw(dev); + dm_ctstoself(dev); + +#ifdef USB_RX_AGGREGATION_SUPPORT + dm_CheckRxAggregation(dev); +#endif +} //HalDmWatchDog + + +/* + * Decide Rate Adaptive Set according to distance (signal strength) + * 01/11/2008 MHC Modify input arguments and RATR table level. + * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call + * the function after making sure RF_Type. + */ +extern void init_rate_adaptive(struct net_device * dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; + + pra->ratr_state = DM_RATR_STA_MAX; + pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; + pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5; + pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5; + + pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5; + pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M; + pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M; + + if(priv->CustomerID == RT_CID_819x_Netcore) + pra->ping_rssi_enable = 1; + else + pra->ping_rssi_enable = 0; + pra->ping_rssi_thresh_for_ra = 15; + + + if (priv->rf_type == RF_2T4R) + { + // 07/10/08 MH Modify for RA smooth scheme. + /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/ + pra->upper_rssi_threshold_ratr = 0x8f0f0000; + pra->middle_rssi_threshold_ratr = 0x8f0ff000; + pra->low_rssi_threshold_ratr = 0x8f0ff001; + pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; + pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; + pra->ping_rssi_ratr = 0x0000000d;//cosa add for test + } + else if (priv->rf_type == RF_1T2R) + { + pra->upper_rssi_threshold_ratr = 0x000f0000; + pra->middle_rssi_threshold_ratr = 0x000ff000; + pra->low_rssi_threshold_ratr = 0x000ff001; + pra->low_rssi_threshold_ratr_40M = 0x000ff005; + pra->low_rssi_threshold_ratr_20M = 0x000ff001; + pra->ping_rssi_ratr = 0x0000000d;//cosa add for test + } + +} // InitRateAdaptive + + +/*----------------------------------------------------------------------------- + * Function: dm_check_rate_adaptive() + * + * Overview: + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/26/08 amy Create version 0 proting from windows code. + * + *---------------------------------------------------------------------------*/ +static void dm_check_rate_adaptive(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; + prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; + u32 currentRATR, targetRATR = 0; + u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; + bool bshort_gi_enabled = false; + static u8 ping_rssi_state=0; + + + if(!priv->up) + { + RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); + return; + } + + if(pra->rate_adaptive_disabled)//this variable is set by ioctl. + return; + + // TODO: Only 11n mode is implemented currently, + if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G || + priv->ieee80211->mode == WIRELESS_MODE_N_5G)) + return; + + if( priv->ieee80211->state == IEEE80211_LINKED ) + { + // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t"); + + // + // Check whether Short GI is enabled + // + bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || + (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); + + + pra->upper_rssi_threshold_ratr = + (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; + + pra->middle_rssi_threshold_ratr = + (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; + + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + pra->low_rssi_threshold_ratr = + (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; + } + else + { + pra->low_rssi_threshold_ratr = + (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; + } + //cosa add for test + pra->ping_rssi_ratr = + (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; + + /* 2007/10/08 MH We support RA smooth scheme now. When it is the first + time to link with AP. We will not change upper/lower threshold. If + STA stay in high or low level, we must change two different threshold + to prevent jumping frequently. */ + if (pra->ratr_state == DM_RATR_STA_HIGH) + { + HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? + (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); + } + else if (pra->ratr_state == DM_RATR_STA_LOW) + { + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? + (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M); + } + else + { + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? + (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); + } + + //DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA); + if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) + { + //DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB); + pra->ratr_state = DM_RATR_STA_HIGH; + targetRATR = pra->upper_rssi_threshold_ratr; + }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) + { + //DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB); + pra->ratr_state = DM_RATR_STA_MIDDLE; + targetRATR = pra->middle_rssi_threshold_ratr; + }else + { + //DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB); + pra->ratr_state = DM_RATR_STA_LOW; + targetRATR = pra->low_rssi_threshold_ratr; + } + + //cosa add for test + if(pra->ping_rssi_enable) + { + //pHalData->UndecoratedSmoothedPWDB = 19; + if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) + { + if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || + ping_rssi_state ) + { + //DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR); + pra->ratr_state = DM_RATR_STA_LOW; + targetRATR = pra->ping_rssi_ratr; + ping_rssi_state = 1; + } + //else + // DbgPrint("TestRSSI is between the range. \n"); + } + else + { + //DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR); + ping_rssi_state = 0; + } + } + + // 2008.04.01 +#if 1 + // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. + if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev)) + targetRATR &= 0xf00fffff; +#endif + + // + // Check whether updating of RATR0 is required + // + currentRATR = read_nic_dword(dev, RATR0); + if( targetRATR != currentRATR ) + { + u32 ratr_value; + ratr_value = targetRATR; + RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR); + if(priv->rf_type == RF_1T2R) + { + ratr_value &= ~(RATE_ALL_OFDM_2SS); + } + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); + + pra->last_ratr = targetRATR; + } + + } + else + { + pra->ratr_state = DM_RATR_STA_MAX; + } + +} // dm_CheckRateAdaptive + + +static void dm_init_bandwidth_autoswitch(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; + priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; + priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; + priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false; + +} // dm_init_bandwidth_autoswitch + + +static void dm_bandwidth_autoswitch(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){ + return; + }else{ + if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40 + if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz) + priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true; + }else{//in force send packets in 20 Mhz in 20/40 + if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz) + priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; + + } + } +} // dm_BandwidthAutoSwitch + +//OFDM default at 0db, index=6. +#ifndef RTL8190P +static u32 OFDMSwingTable[OFDM_Table_Length] = { + 0x7f8001fe, // 0, +6db + 0x71c001c7, // 1, +5db + 0x65400195, // 2, +4db + 0x5a400169, // 3, +3db + 0x50800142, // 4, +2db + 0x47c0011f, // 5, +1db + 0x40000100, // 6, +0db ===> default, upper for higher temprature, lower for low temprature + 0x390000e4, // 7, -1db + 0x32c000cb, // 8, -2db + 0x2d4000b5, // 9, -3db + 0x288000a2, // 10, -4db + 0x24000090, // 11, -5db + 0x20000080, // 12, -6db + 0x1c800072, // 13, -7db + 0x19800066, // 14, -8db + 0x26c0005b, // 15, -9db + 0x24400051, // 16, -10db + 0x12000048, // 17, -11db + 0x10000040 // 18, -12db +}; +static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db +}; + +static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db +}; +#endif +#define Pw_Track_Flag 0x11d +#define Tssi_Mea_Value 0x13c +#define Tssi_Report_Value1 0x134 +#define Tssi_Report_Value2 0x13e +#define FW_Busy_Flag 0x13f +static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) + { + struct r8192_priv *priv = ieee80211_priv(dev); + bool bHighpowerstate, viviflag = FALSE; + DCMD_TXCMD_T tx_cmd; + u8 powerlevelOFDM24G; + int i =0, j = 0, k = 0; + u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0}; + u32 Value; + u8 Pwr_Flag; + u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0; +#ifdef RTL8192U + RT_STATUS rtStatus = RT_STATUS_SUCCESS; +#endif +// bool rtStatus = true; + u32 delta=0; + RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); +// write_nic_byte(dev, 0x1ba, 0); + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + priv->ieee80211->bdynamic_txpower_enable = false; + bHighpowerstate = priv->bDynamicTxHighPower; + + powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); + RF_Type = priv->rf_type; + Value = (RF_Type<<8) | powerlevelOFDM24G; + + RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G); + + for(j = 0; j<=30; j++) +{ //fill tx_cmd + + tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; + tx_cmd.Length = 4; + tx_cmd.Value = Value; +#ifdef RTL8192U + rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12); + if (rtStatus == RT_STATUS_FAILURE) + { + RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n"); + } +#else + cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); +#endif + mdelay(1); + //DbgPrint("hi, vivi, strange\n"); + for(i = 0;i <= 30; i++) + { + Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag); + + if (Pwr_Flag == 0) + { + mdelay(1); + continue; + } + + Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value); + + if(Avg_TSSI_Meas == 0) + { + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + return; + } + + for(k = 0;k < 5; k++) + { + if(k !=4) + tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value1+k); + else + tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value2); + + RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]); + } + + //check if the report value is right + for(k = 0;k < 5; k++) + { + if(tmp_report[k] <= 20) + { + viviflag =TRUE; + break; + } + } + if(viviflag ==TRUE) + { + write_nic_byte(dev, Pw_Track_Flag, 0); + viviflag = FALSE; + RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); + for(k = 0;k < 5; k++) + tmp_report[k] = 0; + break; + } + + for(k = 0;k < 5; k++) + { + Avg_TSSI_Meas_from_driver += tmp_report[k]; + } + + Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5; + RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver); + TSSI_13dBm = priv->TSSI_13dBm; + RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm); + + //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK) + // For MacOS-compatible + if(Avg_TSSI_Meas_from_driver > TSSI_13dBm) + delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; + else + delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver; + + if(delta <= E_FOR_TX_POWER_TRACK) + { + priv->ieee80211->bdynamic_txpower_enable = TRUE; + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); +#ifdef RTL8190P + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real); +#endif + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); + return; + } + else + { + if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) + { + if (RF_Type == RF_2T4R) + { + + if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0)) + { + priv->rfa_txpowertrackingindex--; + if(priv->rfa_txpowertrackingindex_real > 4) + { + priv->rfa_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + } + + priv->rfc_txpowertrackingindex--; + if(priv->rfc_txpowertrackingindex_real > 4) + { + priv->rfc_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } + } + else + { + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + } + } + else + { + if(priv->rfc_txpowertrackingindex > 0) + { + priv->rfc_txpowertrackingindex--; + if(priv->rfc_txpowertrackingindex_real > 4) + { + priv->rfc_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } + } + else + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + } + } + else + { + if (RF_Type == RF_2T4R) + { + if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1)) + { + priv->rfa_txpowertrackingindex++; + priv->rfa_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + priv->rfc_txpowertrackingindex++; + priv->rfc_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } + else + { + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + } + } + else + { + if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1)) + { + priv->rfc_txpowertrackingindex++; + priv->rfc_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } + else + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + } + } + if (RF_Type == RF_2T4R) + priv->CCKPresentAttentuation_difference + = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; + else + priv->CCKPresentAttentuation_difference + = priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default; + + if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) + priv->CCKPresentAttentuation + = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; + else + priv->CCKPresentAttentuation + = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; + + if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) + priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; + if(priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + if(1) + { + if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = TRUE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = FALSE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); +#ifdef RTL8190P + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real); +#endif + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); + + if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24) + { + priv->ieee80211->bdynamic_txpower_enable = TRUE; + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); + return; + } + + + } + write_nic_byte(dev, Pw_Track_Flag, 0); + Avg_TSSI_Meas_from_driver = 0; + for(k = 0;k < 5; k++) + tmp_report[k] = 0; + break; + } + write_nic_byte(dev, FW_Busy_Flag, 0); +} + priv->ieee80211->bdynamic_txpower_enable = TRUE; + write_nic_byte(dev, Pw_Track_Flag, 0); +} +#ifndef RTL8190P +static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) +{ +#define ThermalMeterVal 9 + struct r8192_priv *priv = ieee80211_priv(dev); + u32 tmpRegA, TempCCk; + u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; + int i =0, CCKSwingNeedUpdate=0; + + if(!priv->btxpower_trackingInit) + { + //Query OFDM default setting + tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); + for(i=0; iOFDM_index= (u8)i; + RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n", + rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index); + } + } + + //Query CCK default setting From 0xa22 + TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + for(i=0 ; iCCK_index =(u8) i; + RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n", + rCCK0_TxFilter1, TempCCk, priv->CCK_index); + break; + } +} + priv->btxpower_trackingInit = TRUE; + //pHalData->TXPowercount = 0; + return; + } + + //========================== + // this is only for test, should be masked +#if 0 +{ + //UINT32 eRFPath; + //UINT32 start_rf, end_rf; + UINT32 curr_addr; + //UINT32 reg_addr; + //UINT32 reg_addr_end; + UINT32 reg_value; + //start_rf = RF90_PATH_A; + //end_rf = RF90_PATH_B;//RF90_PATH_MAX; + //reg_addr = 0x0; + //reg_addr_end = 0x2F; + + for (curr_addr = 0; curr_addr < 0x2d; curr_addr++) + { + reg_value = PHY_QueryRFReg( Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, + curr_addr, bMaskDWord); + } + + pHalData->TXPowercount = 0; + return; +} +#endif + //========================== + + // read and filter out unreasonable value + tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7] + RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA); + if(tmpRegA < 3 || tmpRegA > 13) + return; + if(tmpRegA >= 12) // if over 12, TP will be bad when high temprature + tmpRegA = 12; + RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA); + priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion + priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion + + //Get current RF-A temprature index + if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temprature + { + tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); + tmpCCK40Mindex = tmpCCK20Mindex - 6; + if(tmpOFDMindex >= OFDM_Table_Length) + tmpOFDMindex = OFDM_Table_Length-1; + if(tmpCCK20Mindex >= CCK_Table_length) + tmpCCK20Mindex = CCK_Table_length-1; + if(tmpCCK40Mindex >= CCK_Table_length) + tmpCCK40Mindex = CCK_Table_length-1; + } + else + { + tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); + if(tmpval >= 6) // higher temprature + tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB + else + tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; + tmpCCK40Mindex = 0; + } + //DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d", + //((u1Byte)tmpRegA - pHalData->ThermalMeter[0]), + //tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex); + if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M + tmpCCKindex = tmpCCK40Mindex; + else + tmpCCKindex = tmpCCK20Mindex; + + //record for bandwidth swith + priv->Record_CCK_20Mindex = tmpCCK20Mindex; + priv->Record_CCK_40Mindex = tmpCCK40Mindex; + RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n", + priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex); + + if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = TRUE; + CCKSwingNeedUpdate = 1; + } + else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = FALSE; + CCKSwingNeedUpdate = 1; + } + + if(priv->CCK_index != tmpCCKindex) +{ + priv->CCK_index = tmpCCKindex; + CCKSwingNeedUpdate = 1; + } + + if(CCKSwingNeedUpdate) + { + //DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index); + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } + if(priv->OFDM_index != tmpOFDMindex) + { + priv->OFDM_index = tmpOFDMindex; + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); + RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", + priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]); + } + priv->txpower_count = 0; +} +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_txpower_trackingcallback(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); + struct net_device *dev = priv->ieee80211->dev; +#else +extern void dm_txpower_trackingcallback(struct net_device *dev) +{ +#ifndef RTL8190P + struct r8192_priv *priv = ieee80211_priv(dev); +#endif +#endif + +#ifdef RTL8190P + dm_TXPowerTrackingCallback_TSSI(dev); +#else + //if(priv->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) + dm_TXPowerTrackingCallback_TSSI(dev); + else + dm_TXPowerTrackingCallback_ThermalMeter(dev); +#endif +} + + +static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + + //Initial the Tx BB index and mapping value + priv->txbbgain_table[0].txbb_iq_amplifygain = 12; + priv->txbbgain_table[0].txbbgain_value=0x7f8001fe; + priv->txbbgain_table[1].txbb_iq_amplifygain = 11; + priv->txbbgain_table[1].txbbgain_value=0x788001e2; + priv->txbbgain_table[2].txbb_iq_amplifygain = 10; + priv->txbbgain_table[2].txbbgain_value=0x71c001c7; + priv->txbbgain_table[3].txbb_iq_amplifygain = 9; + priv->txbbgain_table[3].txbbgain_value=0x6b8001ae; + priv->txbbgain_table[4].txbb_iq_amplifygain = 8; + priv->txbbgain_table[4].txbbgain_value=0x65400195; + priv->txbbgain_table[5].txbb_iq_amplifygain = 7; + priv->txbbgain_table[5].txbbgain_value=0x5fc0017f; + priv->txbbgain_table[6].txbb_iq_amplifygain = 6; + priv->txbbgain_table[6].txbbgain_value=0x5a400169; + priv->txbbgain_table[7].txbb_iq_amplifygain = 5; + priv->txbbgain_table[7].txbbgain_value=0x55400155; + priv->txbbgain_table[8].txbb_iq_amplifygain = 4; + priv->txbbgain_table[8].txbbgain_value=0x50800142; + priv->txbbgain_table[9].txbb_iq_amplifygain = 3; + priv->txbbgain_table[9].txbbgain_value=0x4c000130; + priv->txbbgain_table[10].txbb_iq_amplifygain = 2; + priv->txbbgain_table[10].txbbgain_value=0x47c0011f; + priv->txbbgain_table[11].txbb_iq_amplifygain = 1; + priv->txbbgain_table[11].txbbgain_value=0x43c0010f; + priv->txbbgain_table[12].txbb_iq_amplifygain = 0; + priv->txbbgain_table[12].txbbgain_value=0x40000100; + priv->txbbgain_table[13].txbb_iq_amplifygain = -1; + priv->txbbgain_table[13].txbbgain_value=0x3c8000f2; + priv->txbbgain_table[14].txbb_iq_amplifygain = -2; + priv->txbbgain_table[14].txbbgain_value=0x390000e4; + priv->txbbgain_table[15].txbb_iq_amplifygain = -3; + priv->txbbgain_table[15].txbbgain_value=0x35c000d7; + priv->txbbgain_table[16].txbb_iq_amplifygain = -4; + priv->txbbgain_table[16].txbbgain_value=0x32c000cb; + priv->txbbgain_table[17].txbb_iq_amplifygain = -5; + priv->txbbgain_table[17].txbbgain_value=0x300000c0; + priv->txbbgain_table[18].txbb_iq_amplifygain = -6; + priv->txbbgain_table[18].txbbgain_value=0x2d4000b5; + priv->txbbgain_table[19].txbb_iq_amplifygain = -7; + priv->txbbgain_table[19].txbbgain_value=0x2ac000ab; + priv->txbbgain_table[20].txbb_iq_amplifygain = -8; + priv->txbbgain_table[20].txbbgain_value=0x288000a2; + priv->txbbgain_table[21].txbb_iq_amplifygain = -9; + priv->txbbgain_table[21].txbbgain_value=0x26000098; + priv->txbbgain_table[22].txbb_iq_amplifygain = -10; + priv->txbbgain_table[22].txbbgain_value=0x24000090; + priv->txbbgain_table[23].txbb_iq_amplifygain = -11; + priv->txbbgain_table[23].txbbgain_value=0x22000088; + priv->txbbgain_table[24].txbb_iq_amplifygain = -12; + priv->txbbgain_table[24].txbbgain_value=0x20000080; + priv->txbbgain_table[25].txbb_iq_amplifygain = -13; + priv->txbbgain_table[25].txbbgain_value=0x1a00006c; + priv->txbbgain_table[26].txbb_iq_amplifygain = -14; + priv->txbbgain_table[26].txbbgain_value=0x1c800072; + priv->txbbgain_table[27].txbb_iq_amplifygain = -15; + priv->txbbgain_table[27].txbbgain_value=0x18000060; + priv->txbbgain_table[28].txbb_iq_amplifygain = -16; + priv->txbbgain_table[28].txbbgain_value=0x19800066; + priv->txbbgain_table[29].txbb_iq_amplifygain = -17; + priv->txbbgain_table[29].txbbgain_value=0x15800056; + priv->txbbgain_table[30].txbb_iq_amplifygain = -18; + priv->txbbgain_table[30].txbbgain_value=0x26c0005b; + priv->txbbgain_table[31].txbb_iq_amplifygain = -19; + priv->txbbgain_table[31].txbbgain_value=0x14400051; + priv->txbbgain_table[32].txbb_iq_amplifygain = -20; + priv->txbbgain_table[32].txbbgain_value=0x24400051; + priv->txbbgain_table[33].txbb_iq_amplifygain = -21; + priv->txbbgain_table[33].txbbgain_value=0x1300004c; + priv->txbbgain_table[34].txbb_iq_amplifygain = -22; + priv->txbbgain_table[34].txbbgain_value=0x12000048; + priv->txbbgain_table[35].txbb_iq_amplifygain = -23; + priv->txbbgain_table[35].txbbgain_value=0x11000044; + priv->txbbgain_table[36].txbb_iq_amplifygain = -24; + priv->txbbgain_table[36].txbbgain_value=0x10000040; + + //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 + //This Table is for CH1~CH13 + priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04; + + priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04; + + priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01; + + //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 + //This Table is for CH14 + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00; + + priv->btxpower_tracking = TRUE; + priv->txpower_count = 0; + priv->btxpower_trackingInit = FALSE; + +} +#ifndef RTL8190P +static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism + // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w + // 3-wire by driver cause RF goes into wrong state. + if(priv->ieee80211->FwRWRF) + priv->btxpower_tracking = TRUE; + else + priv->btxpower_tracking = FALSE; + priv->txpower_count = 0; + priv->btxpower_trackingInit = FALSE; +} +#endif + +void dm_initialize_txpower_tracking(struct net_device *dev) +{ +#ifndef RTL8190P + struct r8192_priv *priv = ieee80211_priv(dev); +#endif +#ifdef RTL8190P + dm_InitializeTXPowerTracking_TSSI(dev); +#else + //if(priv->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) + dm_InitializeTXPowerTracking_TSSI(dev); + else + dm_InitializeTXPowerTracking_ThermalMeter(dev); +#endif +} // dm_InitializeTXPowerTracking + + +static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u32 tx_power_track_counter = 0; + RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); + if(read_nic_byte(dev, 0x11e) ==1) + return; + if(!priv->btxpower_tracking) + return; + tx_power_track_counter++; + + + if(tx_power_track_counter > 90) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); + #else + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->txpower_tracking_wq); + #else + queue_work(priv->priv_wq,&priv->txpower_tracking_wq); + #endif + #endif + tx_power_track_counter =0; + } + +} + +#ifndef RTL8190P +static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u8 TM_Trigger=0; +#if 0 + u1Byte i; + u4Byte tmpRegA; + for(i=0; i<50; i++) + { + tmpRegA = PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7] + PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + //delay_us(100); + PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + //delay_us(100); + } + DbgPrint("Trigger and readback ThermalMeter, write RF reg0x2 = 0x4d to 0x4f for 50 times\n"); +#else + //DbgPrint("dm_CheckTXPowerTracking() \n"); + if(!priv->btxpower_tracking) + return; + else + { + if(priv->txpower_count <= 2) + { + priv->txpower_count++; + return; + } + } + + if(!TM_Trigger) + { + //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash + //actually write reg0x02 bit1=0, then bit1=1. + //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + TM_Trigger = 1; + return; + } + else + { + //DbgPrint("Schedule TxPowerTrackingWorkItem\n"); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); + #else + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->txpower_tracking_wq); + #else + queue_work(priv->priv_wq,&priv->txpower_tracking_wq); + #endif + #endif + TM_Trigger = 0; + } +#endif + } +#endif + +static void dm_check_txpower_tracking(struct net_device *dev) +{ +#ifndef RTL8190P + struct r8192_priv *priv = ieee80211_priv(dev); + //static u32 tx_power_track_counter = 0; +#endif +#ifdef RTL8190P + dm_CheckTXPowerTracking_TSSI(dev); +#else + //if(priv->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) + dm_CheckTXPowerTracking_TSSI(dev); + else + dm_CheckTXPowerTracking_ThermalMeter(dev); +#endif + +} // dm_CheckTXPowerTracking + + +static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) +{ + u32 TempVal; + struct r8192_priv *priv = ieee80211_priv(dev); + //Write 0xa22 0xa23 + TempVal = 0; + if(!bInCH14){ + //Write 0xa22 0xa23 + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal); + //Write 0xa24 ~ 0xa27 + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); + rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal); + //Write 0xa28 0xa29 + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal); + } + else + { + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal); + //Write 0xa24 ~ 0xa27 + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); + rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal); + //Write 0xa28 0xa29 + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal); + } + + +} +#ifndef RTL8190P +static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) +{ + u32 TempVal; + struct r8192_priv *priv = ieee80211_priv(dev); + + TempVal = 0; + if(!bInCH14) + { + //Write 0xa22 0xa23 + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ; + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter1, TempVal); + //Write 0xa24 ~ 0xa27 + TempVal = 0; + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+ + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter2, TempVal); + //Write 0xa28 0xa29 + TempVal = 0; + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_DebugPort, TempVal); + } + else + { +// priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug. + //Write 0xa22 0xa23 + TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + + (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter1, TempVal); + //Write 0xa24 ~ 0xa27 + TempVal = 0; + TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+ + (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter2, TempVal); + //Write 0xa28 0xa29 + TempVal = 0; + TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_DebugPort, TempVal); + } + } +#endif + + +extern void dm_cck_txpower_adjust( + struct net_device *dev, + bool binch14 +) +{ // dm_CCKTxPowerAdjust +#ifndef RTL8190P + struct r8192_priv *priv = ieee80211_priv(dev); +#endif +#ifdef RTL8190P + dm_CCKTxPowerAdjust_TSSI(dev, binch14); +#else + //if(priv->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) + dm_CCKTxPowerAdjust_TSSI(dev, binch14); + else + dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); +#endif +} + + +#ifndef RTL8192U +static void dm_txpower_reset_recovery( + struct net_device *dev +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->CCKPresentAttentuation); + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain); + +} // dm_TXPowerResetRecovery + +extern void dm_restore_dynamic_mechanism_state(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 reg_ratr = priv->rate_adaptive.last_ratr; + + if(!priv->up) + { + RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); + return; + } + + // + // Restore previous state for rate adaptive + // + if(priv->rate_adaptive.rate_adaptive_disabled) + return; + // TODO: Only 11n mode is implemented currently, + if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G || + priv->ieee80211->mode==WIRELESS_MODE_N_5G)) + return; + { + /* 2007/11/15 MH Copy from 8190PCI. */ + u32 ratr_value; + ratr_value = reg_ratr; + if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled + { + ratr_value &=~ (RATE_ALL_OFDM_2SS); + //DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value); + } + //DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value); + //cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]); + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); +#if 0 // Disable old code. + u1Byte index; + u4Byte input_value; + index = (u1Byte)((((pu4Byte)(val))[0]) >> 28); + input_value = (((pu4Byte)(val))[0]) & 0x0fffffff; + // TODO: Correct it. Emily 2007.01.11 + PlatformEFIOWrite4Byte(Adapter, RATR0+index*4, input_value); +#endif + } + //Resore TX Power Tracking Index + if(priv->btxpower_trackingInit && priv->btxpower_tracking){ + dm_txpower_reset_recovery(dev); + } + + // + //Restore BB Initial Gain + // + dm_bb_initialgain_restore(dev); + +} // DM_RestoreDynamicMechanismState + +static void dm_bb_initialgain_restore(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 bit_mask = 0x7f; //Bit0~ Bit6 + + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + return; + + //Disable Initial Gain + //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1); + bit_mask = bMaskByte2; + rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); + + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); + //Enable Initial Gain + //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100); + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. + +} // dm_BBInitialGainRestore + + +extern void dm_backup_dynamic_mechanism_state(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + // Fsync to avoid reset + priv->bswitch_fsync = false; + priv->bfsync_processing = false; + //Backup BB InitialGain + dm_bb_initialgain_backup(dev); + +} // DM_BackupDynamicMechanismState + + +static void dm_bb_initialgain_backup(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 bit_mask = bMaskByte0; //Bit0~ Bit6 + + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + return; + + //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask); + priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask); + priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask); + priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask); + bit_mask = bMaskByte2; + priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); + + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); + +} // dm_BBInitialGainBakcup + +#endif +/*----------------------------------------------------------------------------- + * Function: dm_change_dynamic_initgain_thresh() + * + * Overview: + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/29/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, + u32 dm_value) +{ + if (dm_type == DIG_TYPE_THRESH_HIGH) + { + dm_digtable.rssi_high_thresh = dm_value; + } + else if (dm_type == DIG_TYPE_THRESH_LOW) + { + dm_digtable.rssi_low_thresh = dm_value; + } + else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) + { + dm_digtable.rssi_high_power_highthresh = dm_value; + } + else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) + { + dm_digtable.rssi_high_power_highthresh = dm_value; + } + else if (dm_type == DIG_TYPE_ENABLE) + { + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_enable_flag = true; + } + else if (dm_type == DIG_TYPE_DISABLE) + { + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_enable_flag = false; + } + else if (dm_type == DIG_TYPE_DBG_MODE) + { + if(dm_value >= DM_DBG_MAX) + dm_value = DM_DBG_OFF; + dm_digtable.dbg_mode = (u8)dm_value; + } + else if (dm_type == DIG_TYPE_RSSI) + { + if(dm_value > 100) + dm_value = 30; + dm_digtable.rssi_val = (long)dm_value; + } + else if (dm_type == DIG_TYPE_ALGORITHM) + { + if (dm_value >= DIG_ALGO_MAX) + dm_value = DIG_ALGO_BY_FALSE_ALARM; + if(dm_digtable.dig_algorithm != (u8)dm_value) + dm_digtable.dig_algorithm_switch = 1; + dm_digtable.dig_algorithm = (u8)dm_value; + } + else if (dm_type == DIG_TYPE_BACKOFF) + { + if(dm_value > 30) + dm_value = 30; + dm_digtable.backoff_val = (u8)dm_value; + } + else if(dm_type == DIG_TYPE_RX_GAIN_MIN) + { + if(dm_value == 0) + dm_value = 0x1; + dm_digtable.rx_gain_range_min = (u8)dm_value; + } + else if(dm_type == DIG_TYPE_RX_GAIN_MAX) + { + if(dm_value > 0x50) + dm_value = 0x50; + dm_digtable.rx_gain_range_max = (u8)dm_value; + } +} /* DM_ChangeDynamicInitGainThresh */ +extern void +dm_change_fsync_setting( + struct net_device *dev, + s32 DM_Type, + s32 DM_Value) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if (DM_Type == 0) // monitor 0xc38 register + { + if(DM_Value > 1) + DM_Value = 1; + priv->framesyncMonitor = (u8)DM_Value; + //DbgPrint("pHalData->framesyncMonitor = %d", pHalData->framesyncMonitor); + } +} + +extern void +dm_change_rxpath_selection_setting( + struct net_device *dev, + s32 DM_Type, + s32 DM_Value) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + prate_adaptive pRA = (prate_adaptive)&(priv->rate_adaptive); + + + if(DM_Type == 0) + { + if(DM_Value > 1) + DM_Value = 1; + DM_RxPathSelTable.Enable = (u8)DM_Value; + } + else if(DM_Type == 1) + { + if(DM_Value > 1) + DM_Value = 1; + DM_RxPathSelTable.DbgMode = (u8)DM_Value; + } + else if(DM_Type == 2) + { + if(DM_Value > 40) + DM_Value = 40; + DM_RxPathSelTable.SS_TH_low = (u8)DM_Value; + } + else if(DM_Type == 3) + { + if(DM_Value > 25) + DM_Value = 25; + DM_RxPathSelTable.diff_TH = (u8)DM_Value; + } + else if(DM_Type == 4) + { + if(DM_Value >= CCK_Rx_Version_MAX) + DM_Value = CCK_Rx_Version_1; + DM_RxPathSelTable.cck_method= (u8)DM_Value; + } + else if(DM_Type == 10) + { + if(DM_Value > 100) + DM_Value = 50; + DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value; + } + else if(DM_Type == 11) + { + if(DM_Value > 100) + DM_Value = 50; + DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value; + } + else if(DM_Type == 12) + { + if(DM_Value > 100) + DM_Value = 50; + DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value; + } + else if(DM_Type == 13) + { + if(DM_Value > 100) + DM_Value = 50; + DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value; + } + else if(DM_Type == 20) + { + if(DM_Value > 1) + DM_Value = 1; + pRA->ping_rssi_enable = (u8)DM_Value; + } + else if(DM_Type == 21) + { + if(DM_Value > 30) + DM_Value = 30; + pRA->ping_rssi_thresh_for_ra = DM_Value; + } +} + +#if 0 +extern void dm_force_tx_fw_info(struct net_device *dev, + u32 force_type, + u32 force_value) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if (force_type == 0) // don't force TxSC + { + //DbgPrint("Set Force SubCarrier Off\n"); + priv->tx_fwinfo_force_subcarriermode = 0; + } + else if(force_type == 1) //force + { + //DbgPrint("Set Force SubCarrier On\n"); + priv->tx_fwinfo_force_subcarriermode = 1; + if(force_value > 3) + force_value = 3; + priv->tx_fwinfo_force_subcarrierval = (u8)force_value; + } +} +#endif + +/*----------------------------------------------------------------------------- + * Function: dm_dig_init() + * + * Overview: Set DIG scheme init value. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/15/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void dm_dig_init(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + /* 2007/10/05 MH Disable DIG scheme now. Not tested. */ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; + dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig + dm_digtable.dig_algorithm_switch = 0; + + /* 2007/10/04 MH Define init gain threshol. */ + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; + dm_digtable.initialgain_lowerbound_state = false; + + dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; + + dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; + dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; + + dm_digtable.rssi_val = 50; //for new dig debug rssi value + dm_digtable.backoff_val = DM_DIG_BACKOFF; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + if(priv->CustomerID == RT_CID_819x_Netcore) + dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; + else + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + +} /* dm_dig_init */ + + +/*----------------------------------------------------------------------------- + * Function: dm_ctrl_initgain_byrssi() + * + * Overview: Driver must monitor RSSI and notify firmware to change initial + * gain according to different threshold. BB team provide the + * suggested solution. + * + * Input: struct net_device *dev + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/27/2008 amy Create Version 0 porting from windows code. + *---------------------------------------------------------------------------*/ +static void dm_ctrl_initgain_byrssi(struct net_device *dev) +{ + + if (dm_digtable.dig_enable_flag == false) + return; + + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) + dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); + else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + dm_ctrl_initgain_byrssi_by_driverrssi(dev); + else + return; +} + + +static void dm_ctrl_initgain_byrssi_by_driverrssi( + struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 i; + static u8 fw_dig=0; + + if (dm_digtable.dig_enable_flag == false) + return; + + //DbgPrint("Dig by Sw Rssi \n"); + if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig. + fw_dig = 0; + if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled + {// FW DIG Off + for(i=0; i<3; i++) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + fw_dig++; + dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off. + } + + if(priv->ieee80211->state == IEEE80211_LINKED) + dm_digtable.cur_connect_state = DIG_CONNECT; + else + dm_digtable.cur_connect_state = DIG_DISCONNECT; + + //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n", + //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState); + + if(dm_digtable.dbg_mode == DM_DBG_OFF) + dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; + //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val); + dm_initial_gain(dev); + dm_pd_th(dev); + dm_cs_ratio(dev); + if(dm_digtable.dig_algorithm_switch) + dm_digtable.dig_algorithm_switch = 0; + dm_digtable.pre_connect_state = dm_digtable.cur_connect_state; + +} /* dm_CtrlInitGainByRssi */ + +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( + struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u32 reset_cnt = 0; + u8 i; + + if (dm_digtable.dig_enable_flag == false) + return; + + if(dm_digtable.dig_algorithm_switch) + { + dm_digtable.dig_state = DM_STA_DIG_MAX; + // Fw DIG On. + for(i=0; i<3; i++) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. + dm_digtable.dig_algorithm_switch = 0; + } + + if (priv->ieee80211->state != IEEE80211_LINKED) + return; + + // For smooth, we can not change DIG state. + if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && + (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) + { + return; + } + //DbgPrint("Dig by Fw False Alarm\n"); + //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF) + /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d", + pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, + DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ + /* 1. When RSSI decrease, We have to judge if it is smaller than a treshold + and then execute below step. */ + if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) + { + /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters + will be reset to init value. We must prevent the condition. */ + if (dm_digtable.dig_state == DM_STA_DIG_OFF && + (priv->reset_count == reset_cnt)) + { + return; + } + else + { + reset_cnt = priv->reset_count; + } + + // If DIG is off, DIG high power state must reset. + dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; + dm_digtable.dig_state = DM_STA_DIG_OFF; + + // 1.1 DIG Off. + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + + // 1.2 Set initial gain. + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17); + + // 1.3 Lower PD_TH for OFDM. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ + // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + #endif + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40); + */ + //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) + + + //else + //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40); + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + + // 1.4 Lower CS ratio for CCK. + write_nic_byte(dev, 0xa0a, 0x08); + + // 1.5 Higher EDCCA. + //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325); + return; + + } + + /* 2. When RSSI increase, We have to judge if it is larger than a treshold + and then execute below step. */ + if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) ) + { + u8 reset_flag = 0; + + if (dm_digtable.dig_state == DM_STA_DIG_ON && + (priv->reset_count == reset_cnt)) + { + dm_ctrl_initgain_byrssi_highpwr(dev); + return; + } + else + { + if (priv->reset_count != reset_cnt) + reset_flag = 1; + + reset_cnt = priv->reset_count; + } + + dm_digtable.dig_state = DM_STA_DIG_ON; + //DbgPrint("DIG ON\n\r"); + + // 2.1 Set initial gain. + // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. + if (reset_flag == 1) + { + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c); + } + else + { + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20); + } + + // 2.2 Higher PD_TH for OFDM. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ + // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + #endif + /* + else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + */ + //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) + + //else + //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42); + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + + // 2.3 Higher CS ratio for CCK. + write_nic_byte(dev, 0xa0a, 0xcd); + + // 2.4 Lower EDCCA. + /* 2008/01/11 MH 90/92 series are the same. */ + //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346); + + // 2.5 DIG On. + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. + + } + + dm_ctrl_initgain_byrssi_highpwr(dev); + +} /* dm_CtrlInitGainByRssi */ + + +/*----------------------------------------------------------------------------- + * Function: dm_ctrl_initgain_byrssi_highpwr() + * + * Overview: + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/28/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void dm_ctrl_initgain_byrssi_highpwr( + struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u32 reset_cnt_highpwr = 0; + + // For smooth, we can not change high power DIG state in the range. + if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && + (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) + { + return; + } + + /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if + it is larger than a treshold and then execute below step. */ + // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. + if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) + { + if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && + (priv->reset_count == reset_cnt_highpwr)) + return; + else + dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; + + // 3.1 Higher PD_TH for OFDM for high power state. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + #endif + + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + */ + + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + } + else + { + if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&& + (priv->reset_count == reset_cnt_highpwr)) + return; + else + dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; + + if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && + priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) + { + // 3.2 Recover PD_TH for OFDM for normal power region. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + #endif + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + */ + + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + } + } + + reset_cnt_highpwr = priv->reset_count; + +} /* dm_CtrlInitGainByRssiHighPwr */ + + +static void dm_initial_gain( + struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 initial_gain=0; + static u8 initialized=0, force_write=0; + static u32 reset_cnt=0; + + if(dm_digtable.dig_algorithm_switch) + { + initialized = 0; + reset_cnt = 0; + } + + if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) + { + if(dm_digtable.cur_connect_state == DIG_CONNECT) + { + if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max) + dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max; + else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; + } + else //current state is disconnected + { + if(dm_digtable.cur_ig_value == 0) + dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; + else + dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; + } + } + else // disconnected -> connected or connected -> disconnected + { + dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; + dm_digtable.pre_ig_value = 0; + } + //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue); + + // if silent reset happened, we should rewrite the values back + if(priv->reset_count != reset_cnt) + { + force_write = 1; + reset_cnt = priv->reset_count; + } + + if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1)) + force_write = 1; + + { + if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) + || !initialized || force_write) + { + initial_gain = (u8)dm_digtable.cur_ig_value; + //DbgPrint("Write initial gain = 0x%x\n", initial_gain); + // Set initial gain. + write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; + initialized = 1; + force_write = 0; + } + } +} + +static void dm_pd_th( + struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u8 initialized=0, force_write=0; + static u32 reset_cnt = 0; + + if(dm_digtable.dig_algorithm_switch) + { + initialized = 0; + reset_cnt = 0; + } + + if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) + { + if(dm_digtable.cur_connect_state == DIG_CONNECT) + { + if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) + dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; + else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && + (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) + dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; + else + dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; + } + else + { + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + } + } + else // disconnected -> connected or connected -> disconnected + { + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + } + + // if silent reset happened, we should rewrite the values back + if(priv->reset_count != reset_cnt) + { + force_write = 1; + reset_cnt = priv->reset_count; + } + + { + if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || + (initialized<=3) || force_write) + { + //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState); + if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) + { + // Lower PD_TH for OFDM. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ + // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + #endif + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); + */ + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + } + else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) + { + // Higher PD_TH for OFDM. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ + // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + #endif + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + */ + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + } + else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) + { + // Higher PD_TH for OFDM for high power state. + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + { + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + #else + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + #endif + /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) + write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + */ + } + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + } + dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; + if(initialized <= 3) + initialized++; + force_write = 0; + } + } +} + +static void dm_cs_ratio( + struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + static u8 initialized=0,force_write=0; + static u32 reset_cnt = 0; + + if(dm_digtable.dig_algorithm_switch) + { + initialized = 0; + reset_cnt = 0; + } + + if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) + { + if(dm_digtable.cur_connect_state == DIG_CONNECT) + { + if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) ) + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; + else + dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; + } + else + { + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + } + } + else // disconnected -> connected or connected -> disconnected + { + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + } + + // if silent reset happened, we should rewrite the values back + if(priv->reset_count != reset_cnt) + { + force_write = 1; + reset_cnt = priv->reset_count; + } + + + { + if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || + !initialized || force_write) + { + //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState); + if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) + { + // Lower CS ratio for CCK. + write_nic_byte(dev, 0xa0a, 0x08); + } + else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) + { + // Higher CS ratio for CCK. + write_nic_byte(dev, 0xa0a, 0xcd); + } + dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; + initialized = 1; + force_write = 0; + } + } +} + +extern void dm_init_edca_turbo(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + priv->bcurrent_turbo_EDCA = false; + priv->ieee80211->bis_any_nonbepkts = false; + priv->bis_cur_rdlstate = false; +} // dm_init_edca_turbo + +#if 1 +static void dm_check_edca_turbo( + struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; + //PSTA_QOS pStaQos = pMgntInfo->pStaQos; + + // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. + static unsigned long lastTxOkCnt = 0; + static unsigned long lastRxOkCnt = 0; + unsigned long curTxOkCnt = 0; + unsigned long curRxOkCnt = 0; + + // + // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters + // should follow the settings from QAP. By Bruce, 2007-12-07. + // + #if 1 + if(priv->ieee80211->state != IEEE80211_LINKED) + goto dm_CheckEdcaTurbo_EXIT; + #endif + // We do not turn on EDCA turbo mode for some AP that has IOT issue + if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) + goto dm_CheckEdcaTurbo_EXIT; + +// printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts); + // Check the status for current condition. + if(!priv->ieee80211->bis_any_nonbepkts) + { + curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; + curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; + // For RT-AP, we needs to turn it on when Rx>Tx + if(curRxOkCnt > 4*curTxOkCnt) + { + //printk("%s():curRxOkCnt > 4*curTxOkCnt\n"); + if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) + { + write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = true; + } + } + else + { + + //printk("%s():curRxOkCnt < 4*curTxOkCnt\n"); + if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) + { + write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = false; + } + + } + + priv->bcurrent_turbo_EDCA = true; + } + else + { + // + // Turn Off EDCA turbo here. + // Restore original EDCA according to the declaration of AP. + // + if(priv->bcurrent_turbo_EDCA) + { + + { + u8 u1bAIFS; + u32 u4bAcParam; + struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; + u8 mode = priv->ieee80211->mode; + + // For Each time updating EDCA parameter, reset EDCA turbo mode status. + dm_init_edca_turbo(dev); + u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; + u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| + (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)| + (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)| + ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); + printk("===>u4bAcParam:%x, ", u4bAcParam); + //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); + write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); + + // Check ACM bit. + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. + { + // TODO: Modified this part and try to set acm control in only 1 IO processing!! + + PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]); + u8 AcmCtrl = read_nic_byte( dev, AcmHwCtrl ); + if( pAciAifsn->f.ACM ) + { // ACM bit is 1. + AcmCtrl |= AcmHw_BeqEn; + } + else + { // ACM bit is 0. + AcmCtrl &= (~AcmHw_BeqEn); + } + + RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ; + write_nic_byte(dev, AcmHwCtrl, AcmCtrl ); + } + } + priv->bcurrent_turbo_EDCA = false; + } + } + + +dm_CheckEdcaTurbo_EXIT: + // Set variables for next time. + priv->ieee80211->bis_any_nonbepkts = false; + lastTxOkCnt = priv->stats.txbytesunicast; + lastRxOkCnt = priv->stats.rxbytesunicast; +} // dm_CheckEdcaTurbo +#endif + +extern void DM_CTSToSelfSetting(struct net_device * dev,u32 DM_Type, u32 DM_Value) +{ + struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); + + if (DM_Type == 0) // CTS to self disable/enable + { + if(DM_Value > 1) + DM_Value = 1; + priv->ieee80211->bCTSToSelfEnable = (bool)DM_Value; + //DbgPrint("pMgntInfo->bCTSToSelfEnable = %d\n", pMgntInfo->bCTSToSelfEnable); + } + else if(DM_Type == 1) //CTS to self Th + { + if(DM_Value >= 50) + DM_Value = 50; + priv->ieee80211->CTSToSelfTH = (u8)DM_Value; + //DbgPrint("pMgntInfo->CTSToSelfTH = %d\n", pMgntInfo->CTSToSelfTH); + } +} + +static void dm_init_ctstoself(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); + + priv->ieee80211->bCTSToSelfEnable = TRUE; + priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal; +} + +static void dm_ctstoself(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); + PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; + static unsigned long lastTxOkCnt = 0; + static unsigned long lastRxOkCnt = 0; + unsigned long curTxOkCnt = 0; + unsigned long curRxOkCnt = 0; + + if(priv->ieee80211->bCTSToSelfEnable != TRUE) + { + pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; + return; + } + /* + 1. Uplink + 2. Linksys350/Linksys300N + 3. <50 disable, >55 enable + */ + + if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) + { + curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; + curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; + if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self + { + pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; + //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n"); + } + else //uplink + { + #if 1 + pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; + #else + if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH) // disable CTS to self + { + pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; + //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n"); + } + else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5)) // enable CTS to self + { + pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; + //DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n"); + } + #endif + } + + lastTxOkCnt = priv->stats.txbytesunicast; + lastRxOkCnt = priv->stats.rxbytesunicast; + } +} + + +#if 0 +/*----------------------------------------------------------------------------- + * Function: dm_rf_operation_test_callback() + * + * Overview: Only for RF operation test now. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/29/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +extern void dm_rf_operation_test_callback(unsigned long dev) +{ +// struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); + u8 erfpath; + + + for(erfpath=0; erfpath<4; erfpath++) + { + //DbgPrint("Set RF-%d\n\r", eRFPath); + //PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); + udelay(100); + } + + { + //PlatformSetPeriodicTimer(Adapter, &pHalData->RfTest1Timer, 500); + } + + // For test + { + //u8 i; + //PlatformSetPeriodicTimer(Adapter, &pHalData->RfTest1Timer, 500); +#if 0 + for(i=0; i<50; i++) + { + // Write Test + PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + //delay_us(100); + PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + //delay_us(100); + PHY_SetRFReg(Adapter, RF90_PATH_C, 0x02, bMask12Bits, 0x4d); + //delay_us(100); + PHY_SetRFReg(Adapter, RF90_PATH_C, 0x02, bMask12Bits, 0x4f); + //delay_us(100); + +#if 0 + // Read test + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits); + //delay_us(100); + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits); + //delay_us(100); + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, bMask12Bits); + //delay_us(100); + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, bMask12Bits); + //delay_us(100); + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x21, bMask12Bits); + //delay_us(100); + PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x21, bMask12Bits); + //delay_us(100); +#endif + } +#endif + } + +} /* DM_RfOperationTestCallBack */ +#endif + +/*----------------------------------------------------------------------------- + * Function: dm_check_rfctrl_gpio() + * + * Overview: Copy 8187B template for 9xseries. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/28/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +#if 1 +static void dm_check_rfctrl_gpio(struct net_device * dev) +{ +#ifdef RTL8192E + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + + // Walk around for DTM test, we will not enable HW - radio on/off because r/w + // page 1 register before Lextra bus is enabled cause system fails when resuming + // from S4. 20080218, Emily + + // Stop to execute workitem to prevent S3/S4 bug. +#ifdef RTL8190P + return; +#endif +#ifdef RTL8192U + return; +#endif +#ifdef RTL8192E + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0); + #else + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->gpio_change_rf_wq); + #else + queue_work(priv->priv_wq,&priv->gpio_change_rf_wq); + #endif + #endif +#endif + +} /* dm_CheckRfCtrlGPIO */ + +#endif +/*----------------------------------------------------------------------------- + * Function: dm_check_pbc_gpio() + * + * Overview: Check if PBC button is pressed. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/28/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void dm_check_pbc_gpio(struct net_device *dev) +{ +#ifdef RTL8192U + struct r8192_priv *priv = ieee80211_priv(dev); + u8 tmp1byte; + + + tmp1byte = read_nic_byte(dev,GPI); + if(tmp1byte == 0xff) + return; + + if (tmp1byte&BIT6 || tmp1byte&BIT0) + { + // Here we only set bPbcPressed to TRUE + // After trigger PBC, the variable will be set to FALSE + RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); + priv->bpbc_pressed = true; + } +#endif + +} + +#ifdef RTL8192E + +/*----------------------------------------------------------------------------- + * Function: dm_GPIOChangeRF + * Overview: PCI will not support workitem call back HW radio on-off control. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 02/21/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_gpio_change_rf_callback(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq); + struct net_device *dev = priv->ieee80211->dev; +#else +extern void dm_gpio_change_rf_callback(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + u8 tmp1byte; + RT_RF_POWER_STATE eRfPowerStateToSet; + bool bActuallySet = false; + + bActuallySet=false; + + if(!priv->up) + { + RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n"); + } + else + { + // 0x108 GPIO input register is read only + //set 0x108 B1= 1: RF-ON; 0: RF-OFF. + tmp1byte = read_nic_byte(dev,GPI); + + eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; + + if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) + { + RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n"); + + priv->bHwRadioOff = false; + bActuallySet = true; + } + else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) + { + RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n"); + priv->bHwRadioOff = true; + bActuallySet = true; + } + + if(bActuallySet) + { + priv->bHwRfOffAction = 1; + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); + //DrvIFIndicateCurrentPhyStatus(pAdapter); + + } + else + { + msleep(2000); + } + + } + +} /* dm_GPIOChangeRF */ + +#endif +/*----------------------------------------------------------------------------- + * Function: DM_RFPathCheckWorkItemCallBack() + * + * Overview: Check if Current RF RX path is enabled + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/30/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work,struct delayed_work,work); + struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq); + struct net_device *dev =priv->ieee80211->dev; +#else +extern void dm_rf_pathcheck_workitemcallback(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + //bool bactually_set = false; + u8 rfpath = 0, i; + + + /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will + always be the same. We only read 0xc04 now. */ + rfpath = read_nic_byte(dev, 0xc04); + + // Check Bit 0-3, it means if RF A-D is enabled. + for (i = 0; i < RF90_PATH_MAX; i++) + { + if (rfpath & (0x01<brfpath_rxenable[i] = 1; + else + priv->brfpath_rxenable[i] = 0; + } + if(!DM_RxPathSelTable.Enable) + return; + + dm_rxpath_sel_byrssi(dev); +} /* DM_RFPathCheckWorkItemCallBack */ + +static void dm_init_rxpath_selection(struct net_device * dev) +{ + u8 i; + struct r8192_priv *priv = ieee80211_priv(dev); + DM_RxPathSelTable.Enable = 1; //default enabled + DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; + DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; + if(priv->CustomerID == RT_CID_819x_Netcore) + DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; + else + DM_RxPathSelTable.cck_method = CCK_Rx_Version_1; + DM_RxPathSelTable.DbgMode = DM_DBG_OFF; + DM_RxPathSelTable.disabledRF = 0; + for(i=0; i<4; i++) + { + DM_RxPathSelTable.rf_rssi[i] = 50; + DM_RxPathSelTable.cck_pwdb_sta[i] = -64; + DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; + } +} + +static void dm_rxpath_sel_byrssi(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0; + u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0; + u8 cck_default_Rx=0x2; //RF-C + u8 cck_optional_Rx=0x3;//RF-D + long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0; + u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0; + u8 cur_rf_rssi; + long cur_cck_pwdb; + static u8 disabled_rf_cnt=0, cck_Rx_Path_initialized=0; + u8 update_cck_rx_path; + + if(priv->rf_type != RF_2T4R) + return; + + if(!cck_Rx_Path_initialized) + { + DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf); + cck_Rx_Path_initialized = 1; + } + + DM_RxPathSelTable.disabledRF = 0xf; + DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04)); + + if(priv->ieee80211->mode == WIRELESS_MODE_B) + { + DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2 + //DbgPrint("Pure B mode, use cck rx version2 \n"); + } + + //decide max/sec/min rssi index + for (i=0; istats.rx_rssi_percentage[i]; + + if(priv->brfpath_rxenable[i]) + { + rf_num++; + cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; + + if(rf_num == 1) // find first enabled rf path and the rssi values + { //initialize, set all rssi index to the same one + max_rssi_index = min_rssi_index = sec_rssi_index = i; + tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; + } + else if(rf_num == 2) + { // we pick up the max index first, and let sec and min to be the same one + if(cur_rf_rssi >= tmp_max_rssi) + { + tmp_max_rssi = cur_rf_rssi; + max_rssi_index = i; + } + else + { + tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; + sec_rssi_index = min_rssi_index = i; + } + } + else + { + if(cur_rf_rssi > tmp_max_rssi) + { + tmp_sec_rssi = tmp_max_rssi; + sec_rssi_index = max_rssi_index; + tmp_max_rssi = cur_rf_rssi; + max_rssi_index = i; + } + else if(cur_rf_rssi == tmp_max_rssi) + { // let sec and min point to the different index + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } + else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi)) + { + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } + else if(cur_rf_rssi == tmp_sec_rssi) + { + if(tmp_sec_rssi == tmp_min_rssi) + { // let sec and min point to the different index + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } + else + { + // This case we don't need to set any index + } + } + else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) + { + // This case we don't need to set any index + } + else if(cur_rf_rssi == tmp_min_rssi) + { + if(tmp_sec_rssi == tmp_min_rssi) + { // let sec and min point to the different index + tmp_min_rssi = cur_rf_rssi; + min_rssi_index = i; + } + else + { + // This case we don't need to set any index + } + } + else if(cur_rf_rssi < tmp_min_rssi) + { + tmp_min_rssi = cur_rf_rssi; + min_rssi_index = i; + } + } + } + } + + rf_num = 0; + // decide max/sec/min cck pwdb index + if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) + { + for (i=0; ibrfpath_rxenable[i]) + { + rf_num++; + cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i]; + + if(rf_num == 1) // find first enabled rf path and the rssi values + { //initialize, set all rssi index to the same one + cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i; + tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb; + } + else if(rf_num == 2) + { // we pick up the max index first, and let sec and min to be the same one + if(cur_cck_pwdb >= tmp_cck_max_pwdb) + { + tmp_cck_max_pwdb = cur_cck_pwdb; + cck_rx_ver2_max_index = i; + } + else + { + tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i; + } + } + else + { + if(cur_cck_pwdb > tmp_cck_max_pwdb) + { + tmp_cck_sec_pwdb = tmp_cck_max_pwdb; + cck_rx_ver2_sec_index = cck_rx_ver2_max_index; + tmp_cck_max_pwdb = cur_cck_pwdb; + cck_rx_ver2_max_index = i; + } + else if(cur_cck_pwdb == tmp_cck_max_pwdb) + { // let sec and min point to the different index + tmp_cck_sec_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + } + else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb)) + { + tmp_cck_sec_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + } + else if(cur_cck_pwdb == tmp_cck_sec_pwdb) + { + if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb) + { // let sec and min point to the different index + tmp_cck_sec_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + } + else + { + // This case we don't need to set any index + } + } + else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) + { + // This case we don't need to set any index + } + else if(cur_cck_pwdb == tmp_cck_min_pwdb) + { + if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb) + { // let sec and min point to the different index + tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_min_index = i; + } + else + { + // This case we don't need to set any index + } + } + else if(cur_cck_pwdb < tmp_cck_min_pwdb) + { + tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_min_index = i; + } + } + + } + } + } + + + // Set CCK Rx path + // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path. + update_cck_rx_path = 0; + if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) + { + cck_default_Rx = cck_rx_ver2_max_index; + cck_optional_Rx = cck_rx_ver2_sec_index; + if(tmp_cck_max_pwdb != -64) + update_cck_rx_path = 1; + } + + if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) + { + if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) + { + //record the enabled rssi threshold + DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5; + //disable the BB Rx path, OFDM + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<>i) & 0x1) //disabled rf + { + if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) + { + //enable the BB Rx path + //DbgPrint("RF-%d is enabled. \n", 0x1<= KERNEL_VERSION(2,6,20) + queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0); +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + schedule_task(&priv->rfpath_check_wq); +#else + queue_work(priv->priv_wq,&priv->rfpath_check_wq); +#endif +#endif +} /* dm_CheckRxRFPath */ + + +static void dm_init_fsync (struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + priv->ieee80211->fsync_time_interval = 500; + priv->ieee80211->fsync_rate_bitmap = 0x0f000800; + priv->ieee80211->fsync_rssi_threshold = 30; +#ifdef RTL8190P + priv->ieee80211->bfsync_enable = true; +#else + priv->ieee80211->bfsync_enable = false; +#endif + priv->ieee80211->fsync_multiple_timeinterval = 3; + priv->ieee80211->fsync_firstdiff_ratethreshold= 100; + priv->ieee80211->fsync_seconddiff_ratethreshold= 200; + priv->ieee80211->fsync_state = Default_Fsync; + priv->framesyncMonitor = 1; // current default 0xc38 monitor on + + init_timer(&priv->fsync_timer); + priv->fsync_timer.data = (unsigned long)dev; + priv->fsync_timer.function = dm_fsync_timer_callback; +} + + +static void dm_deInit_fsync(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + del_timer_sync(&priv->fsync_timer); +} + +extern void dm_fsync_timer_callback(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct r8192_priv *priv = ieee80211_priv((struct net_device *)data); + u32 rate_index, rate_count = 0, rate_count_diff=0; + bool bSwitchFromCountDiff = false; + bool bDoubleTimeInterval = false; + + if( priv->ieee80211->state == IEEE80211_LINKED && + priv->ieee80211->bfsync_enable && + (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) + { + // Count rate 54, MCS [7], [12, 13, 14, 15] + u32 rate_bitmap; + for(rate_index = 0; rate_index <= 27; rate_index++) + { + rate_bitmap = 1 << rate_index; + if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap) + rate_count+= priv->stats.received_rate_histogram[1][rate_index]; + } + + if(rate_count < priv->rate_record) + rate_count_diff = 0xffffffff - rate_count + priv->rate_record; + else + rate_count_diff = rate_count - priv->rate_record; + if(rate_count_diff < priv->rateCountDiffRecord) + { + + u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; + // Contiune count + if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) + priv->ContiuneDiffCount++; + else + priv->ContiuneDiffCount = 0; + + // Contiune count over + if(priv->ContiuneDiffCount >=2) + { + bSwitchFromCountDiff = true; + priv->ContiuneDiffCount = 0; + } + } + else + { + // Stop contiune count + priv->ContiuneDiffCount = 0; + } + + //If Count diff <= FsyncRateCountThreshold + if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) + { + bSwitchFromCountDiff = true; + priv->ContiuneDiffCount = 0; + } + priv->rate_record = rate_count; + priv->rateCountDiffRecord = rate_count_diff; + RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); + // if we never receive those mcs rate and rssi > 30 % then switch fsyn + if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) + { + bDoubleTimeInterval = true; + priv->bswitch_fsync = !priv->bswitch_fsync; + if(priv->bswitch_fsync) + { + #ifdef RTL8190P + write_nic_byte(dev,0xC36, 0x00); + #else + write_nic_byte(dev,0xC36, 0x1c); + #endif + write_nic_byte(dev, 0xC3e, 0x90); + } + else + { + #ifdef RTL8190P + write_nic_byte(dev, 0xC36, 0x40); + #else + write_nic_byte(dev, 0xC36, 0x5c); + #endif + write_nic_byte(dev, 0xC3e, 0x96); + } + } + else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) + { + if(priv->bswitch_fsync) + { + priv->bswitch_fsync = false; + #ifdef RTL8190P + write_nic_byte(dev, 0xC36, 0x40); + #else + write_nic_byte(dev, 0xC36, 0x5c); + #endif + write_nic_byte(dev, 0xC3e, 0x96); + } + } + if(bDoubleTimeInterval){ + if(timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval); + add_timer(&priv->fsync_timer); + } + else{ + if(timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); + add_timer(&priv->fsync_timer); + } + } + else + { + // Let Register return to default value; + if(priv->bswitch_fsync) + { + priv->bswitch_fsync = false; + #ifdef RTL8190P + write_nic_byte(dev, 0xC36, 0x40); + #else + write_nic_byte(dev, 0xC36, 0x5c); + #endif + write_nic_byte(dev, 0xC3e, 0x96); + } + priv->ContiuneDiffCount = 0; + #ifdef RTL8190P + write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd); + #else + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + #endif + } + RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); +} + +static void dm_StartHWFsync(struct net_device *dev) +{ + RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf); + write_nic_byte(dev, 0xc3b, 0x41); +} + +static void dm_EndSWFsync(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); + del_timer_sync(&(priv->fsync_timer)); + + // Let Register return to default value; + if(priv->bswitch_fsync) + { + priv->bswitch_fsync = false; + + #ifdef RTL8190P + write_nic_byte(dev, 0xC36, 0x40); + #else + write_nic_byte(dev, 0xC36, 0x5c); +#endif + + write_nic_byte(dev, 0xC3e, 0x96); + } + + priv->ContiuneDiffCount = 0; +#ifndef RTL8190P + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); +#endif + +} + +static void dm_StartSWFsync(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 rateIndex; + u32 rateBitmap; + + RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); + // Initial rate record to zero, start to record. + priv->rate_record = 0; + // Initial contiune diff count to zero, start to record. + priv->ContiuneDiffCount = 0; + priv->rateCountDiffRecord = 0; + priv->bswitch_fsync = false; + + if(priv->ieee80211->mode == WIRELESS_MODE_N_24G) + { + priv->ieee80211->fsync_firstdiff_ratethreshold= 600; + priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff; + } + else + { + priv->ieee80211->fsync_firstdiff_ratethreshold= 200; + priv->ieee80211->fsync_seconddiff_ratethreshold = 200; + } + for(rateIndex = 0; rateIndex <= 27; rateIndex++) + { + rateBitmap = 1 << rateIndex; + if(priv->ieee80211->fsync_rate_bitmap & rateBitmap) + priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex]; + } + if(timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); + add_timer(&priv->fsync_timer); + +#ifndef RTL8190P + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); +#endif + +} + +static void dm_EndHWFsync(struct net_device *dev) +{ + RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + write_nic_byte(dev, 0xc3b, 0x49); + +} + +void dm_check_fsync(struct net_device *dev) +{ +#define RegC38_Default 0 +#define RegC38_NonFsync_Other_AP 1 +#define RegC38_Fsync_AP_BCM 2 + struct r8192_priv *priv = ieee80211_priv(dev); + //u32 framesyncC34; + static u8 reg_c38_State=RegC38_Default; + static u32 reset_cnt=0; + + RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval); + RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold); + + if( priv->ieee80211->state == IEEE80211_LINKED && + (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) + { + if(priv->ieee80211->bfsync_enable == 0) + { + switch(priv->ieee80211->fsync_state) + { + case Default_Fsync: + dm_StartHWFsync(dev); + priv->ieee80211->fsync_state = HW_Fsync; + break; + case SW_Fsync: + dm_EndSWFsync(dev); + dm_StartHWFsync(dev); + priv->ieee80211->fsync_state = HW_Fsync; + break; + case HW_Fsync: + default: + break; + } + } + else + { + switch(priv->ieee80211->fsync_state) + { + case Default_Fsync: + dm_StartSWFsync(dev); + priv->ieee80211->fsync_state = SW_Fsync; + break; + case HW_Fsync: + dm_EndHWFsync(dev); + dm_StartSWFsync(dev); + priv->ieee80211->fsync_state = SW_Fsync; + break; + case SW_Fsync: + default: + break; + + } + } + if(priv->framesyncMonitor) + { + if(reg_c38_State != RegC38_Fsync_AP_BCM) + { //For broadcom AP we write different default value + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector3, 0x15); + #else + write_nic_byte(dev, rOFDM0_RxDetector3, 0x95); + #endif + + reg_c38_State = RegC38_Fsync_AP_BCM; + } + } + } + else + { + switch(priv->ieee80211->fsync_state) + { + case HW_Fsync: + dm_EndHWFsync(dev); + priv->ieee80211->fsync_state = Default_Fsync; + break; + case SW_Fsync: + dm_EndSWFsync(dev); + priv->ieee80211->fsync_state = Default_Fsync; + break; + case Default_Fsync: + default: + break; + } + + if(priv->framesyncMonitor) + { + if(priv->ieee80211->state == IEEE80211_LINKED) + { + if(priv->undecorated_smoothed_pwdb <= RegC38_TH) + { + if(reg_c38_State != RegC38_NonFsync_Other_AP) + { + #ifdef RTL8190P + write_nic_byte(dev, rOFDM0_RxDetector3, 0x10); + #else + write_nic_byte(dev, rOFDM0_RxDetector3, 0x90); + #endif + + reg_c38_State = RegC38_NonFsync_Other_AP; + #if 0//cosa + if (Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) + DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10); + else + DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90); + #endif + } + } + else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) + { + if(reg_c38_State) + { + write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + reg_c38_State = RegC38_Default; + //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync); + } + } + } + else + { + if(reg_c38_State) + { + write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + reg_c38_State = RegC38_Default; + //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync); + } + } + } + } + if(priv->framesyncMonitor) + { + if(priv->reset_count != reset_cnt) + { //After silent reset, the reg_c38_State will be returned to default value + write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + reg_c38_State = RegC38_Default; + reset_cnt = priv->reset_count; + //DbgPrint("reg_c38_State = 0 for silent reset. \n"); + } + } + else + { + if(reg_c38_State) + { + write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + reg_c38_State = RegC38_Default; + //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync); + } + } +} + +#if 0 +/*----------------------------------------------------------------------------- + * Function: DM_CheckLBusStatus() + * + * Overview: For 9x series, we must make sure LBUS is active for IO. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 02/22/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +extern s1Byte DM_CheckLBusStatus(IN PADAPTER Adapter) +{ + PMGNT_INFO pMgntInfo=&Adapter->MgntInfo; + +#if (HAL_CODE_BASE & RTL819X) + +#if (HAL_CODE_BASE == RTL8192) + +#if( DEV_BUS_TYPE==PCI_INTERFACE) + //return (pMgntInfo->bLbusEnable); // For debug only + return TRUE; +#endif + +#if( DEV_BUS_TYPE==USB_INTERFACE) + return TRUE; +#endif + +#endif // #if (HAL_CODE_BASE == RTL8192) + +#if (HAL_CODE_BASE == RTL8190) + return TRUE; +#endif // #if (HAL_CODE_BASE == RTL8190) + +#endif // #if (HAL_CODE_BASE & RTL819X) +} /* DM_CheckLBusStatus */ + +#endif + +/*----------------------------------------------------------------------------- + * Function: dm_shadow_init() + * + * Overview: Store all NIC MAC/BB register content. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/29/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +extern void dm_shadow_init(struct net_device *dev) +{ + u8 page; + u16 offset; + + for (page = 0; page < 5; page++) + for (offset = 0; offset < 256; offset++) + { + dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256); + //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]); + } + + for (page = 8; page < 11; page++) + for (offset = 0; offset < 256; offset++) + dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256); + + for (page = 12; page < 15; page++) + for (offset = 0; offset < 256; offset++) + dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256); + +} /* dm_shadow_init */ + +/*---------------------------Define function prototype------------------------*/ +/*----------------------------------------------------------------------------- + * Function: DM_DynamicTxPower() + * + * Overview: Detect Signal strength to control TX Registry + Tx Power Control For Near/Far Range + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 03/06/2008 Jacken Create Version 0. + * + *---------------------------------------------------------------------------*/ +static void dm_init_dynamic_txpower(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. + priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control + priv->bLastDTPFlag_High = false; + priv->bLastDTPFlag_Low = false; + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; +} + +static void dm_dynamic_txpower(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + unsigned int txhipower_threshhold=0; + unsigned int txlowpower_threshold=0; + if(priv->ieee80211->bdynamic_txpower_enable != true) + { + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; + return; + } + //printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist); + if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){ + txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; + txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; + } + else + { + txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH; + txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; + } + +// printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold); + + RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb); + + if(priv->ieee80211->state == IEEE80211_LINKED) + { + if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold) + { + priv->bDynamicTxHighPower = true; + priv->bDynamicTxLowPower = false; + } + else + { + // high power state check + if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true) + { + priv->bDynamicTxHighPower = false; + } + // low power state check + if(priv->undecorated_smoothed_pwdb < 35) + { + priv->bDynamicTxLowPower = true; + } + else if(priv->undecorated_smoothed_pwdb >= 40) + { + priv->bDynamicTxLowPower = false; + } + } + } + else + { + //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange; + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; + } + + if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) || + (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) ) + { + RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190() channel = %d \n" , priv->ieee80211->current_network.channel); + + + rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); + + } + priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; + priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; + +} /* dm_dynamic_txpower */ + +//added by vivi, for read tx rate and retrycount +static void dm_check_txrateandretrycount(struct net_device * dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + //for 11n tx rate +// priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg); + ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg); + //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate); + //for initial tx rate +// priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg); + ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg); + //for tx tx retry count +// priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); + ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); +} + +static void dm_send_rssi_tofw(struct net_device *dev) +{ + DCMD_TXCMD_T tx_cmd; + struct r8192_priv *priv = ieee80211_priv(dev); + + // If we test chariot, we should stop the TX command ? + // Because 92E will always silent reset when we send tx command. We use register + // 0x1e0(byte) to botify driver. + write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); + return; +#if 1 + tx_cmd.Op = TXCMD_SET_RX_RSSI; + tx_cmd.Length = 4; + tx_cmd.Value = priv->undecorated_smoothed_pwdb; + + cmpk_message_handle_tx(dev, (u8*)&tx_cmd, + DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); +#endif +} + +/*---------------------------Define function prototype------------------------*/ + diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h new file mode 100644 index 00000000000..ef452a22fa5 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -0,0 +1,320 @@ +/***************************************************************************** + * Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved. + * + * Module: Hal819xUsbDM.h (RTL8192 Header H File) + * + * + * Note: For dynamic control definition constant structure. + * + * + * Export: + * + * Abbrev: + * + * History: + * Data Who Remark + * 10/04/2007 MHC Create initial version. + * + *****************************************************************************/ + /* Check to see if the file has been included already. */ +#ifndef __R8192UDM_H__ +#define __R8192UDM_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define OFDM_Table_Length 19 +#define CCK_Table_length 12 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 +#define DM_DIG_HIGH_PWR_THRESH_LOW 70 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_check_fsync_time_interval 500 + + +#define DM_DIG_BACKOFF 12 +#define DM_DIG_MAX 0x36 +#define DM_DIG_MIN 0x1c +#define DM_DIG_MIN_Netcore 0x12 + +#define RxPathSelection_SS_TH_low 30 +#define RxPathSelection_diff_TH 18 + +#define RateAdaptiveTH_High 50 +#define RateAdaptiveTH_Low_20M 30 +#define RateAdaptiveTH_Low_40M 10 +#define VeryLowRSSI 15 +#define CTSToSelfTHVal 35 + +//defined by vivi, for tx power track +#define E_FOR_TX_POWER_TRACK 300 +//Dynamic Tx Power Control Threshold +#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68 +#define TX_POWER_NEAR_FIELD_THRESH_LOW 62 +//added by amy for atheros AP +#define TX_POWER_ATHEROAP_THRESH_HIGH 78 +#define TX_POWER_ATHEROAP_THRESH_LOW 72 + +//defined by vivi, for showing on UI. Newer firmware has changed to 0x1e0 +#define Current_Tx_Rate_Reg 0x1e0//0x1b8 +#define Initial_Tx_Rate_Reg 0x1e1 //0x1b9 +#define Tx_Retry_Count_Reg 0x1ac +#define RegC38_TH 20 +#if 0 +//---------------------------------------------------------------------------- +// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte) +//---------------------------------------------------------------------------- + +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\ + |RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11| \ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 +#endif +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ +/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */ +typedef struct _dynamic_initial_gain_threshold_ +{ + u8 dig_enable_flag; + u8 dig_algorithm; + u8 dbg_mode; + u8 dig_algorithm_switch; + + long rssi_low_thresh; + long rssi_high_thresh; + + long rssi_high_power_lowthresh; + long rssi_high_power_highthresh; + + u8 dig_state; + u8 dig_highpwr_state; + u8 cur_connect_state; + u8 pre_connect_state; + + u8 curpd_thstate; + u8 prepd_thstate; + u8 curcs_ratio_state; + u8 precs_ratio_state; + + u32 pre_ig_value; + u32 cur_ig_value; + + u8 backoff_val; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + bool initialgain_lowerbound_state; + + long rssi_val; +}dig_t; + +typedef enum tag_dynamic_init_gain_state_definition +{ + DM_STA_DIG_OFF = 0, + DM_STA_DIG_ON, + DM_STA_DIG_MAX +}dm_dig_sta_e; + + +/* 2007/10/08 MH Define RATR state. */ +typedef enum tag_dynamic_ratr_state_definition +{ + DM_RATR_STA_HIGH = 0, + DM_RATR_STA_MIDDLE = 1, + DM_RATR_STA_LOW = 2, + DM_RATR_STA_MAX +}dm_ratr_sta_e; + +/* 2007/10/11 MH Define DIG operation type. */ +typedef enum tag_dynamic_init_gain_operation_type_definition +{ + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_THRESH_HIGHPWR_HIGH = 2, + DIG_TYPE_THRESH_HIGHPWR_LOW = 3, + DIG_TYPE_DBG_MODE = 4, + DIG_TYPE_RSSI = 5, + DIG_TYPE_ALGORITHM = 6, + DIG_TYPE_BACKOFF = 7, + DIG_TYPE_PWDB_FACTOR = 8, + DIG_TYPE_RX_GAIN_MIN = 9, + DIG_TYPE_RX_GAIN_MAX = 10, + DIG_TYPE_ENABLE = 20, + DIG_TYPE_DISABLE = 30, + DIG_OP_TYPE_MAX +}dm_dig_op_e; + +typedef enum tag_dig_algorithm_definition +{ + DIG_ALGO_BY_FALSE_ALARM = 0, + DIG_ALGO_BY_RSSI = 1, + DIG_ALGO_MAX +}dm_dig_alg_e; + +typedef enum tag_dig_dbgmode_definition +{ + DIG_DBG_OFF = 0, + DIG_DBG_ON = 1, + DIG_DBG_MAX +}dm_dig_dbg_e; + +typedef enum tag_dig_connect_definition +{ + DIG_DISCONNECT = 0, + DIG_CONNECT = 1, + DIG_CONNECT_MAX +}dm_dig_connect_e; + +typedef enum tag_dig_packetdetection_threshold_definition +{ + DIG_PD_AT_LOW_POWER = 0, + DIG_PD_AT_NORMAL_POWER = 1, + DIG_PD_AT_HIGH_POWER = 2, + DIG_PD_MAX +}dm_dig_pd_th_e; + +typedef enum tag_dig_cck_cs_ratio_state_definition +{ + DIG_CS_RATIO_LOWER = 0, + DIG_CS_RATIO_HIGHER = 1, + DIG_CS_MAX +}dm_dig_cs_ratio_e; +typedef struct _Dynamic_Rx_Path_Selection_ +{ + u8 Enable; + u8 DbgMode; + u8 cck_method; + u8 cck_Rx_path; + + u8 SS_TH_low; + u8 diff_TH; + u8 disabledRF; + u8 reserved; + + u8 rf_rssi[4]; + u8 rf_enable_rssi_th[4]; + long cck_pwdb_sta[4]; +}DRxPathSel; + +typedef enum tag_CCK_Rx_Path_Method_Definition +{ + CCK_Rx_Version_1 = 0, + CCK_Rx_Version_2= 1, + CCK_Rx_Version_MAX +}DM_CCK_Rx_Path_Method; + +typedef enum tag_DM_DbgMode_Definition +{ + DM_DBG_OFF = 0, + DM_DBG_ON = 1, + DM_DBG_MAX +}DM_DBG_E; + +typedef struct tag_Tx_Config_Cmd_Format +{ + u32 Op; /* Command packet type. */ + u32 Length; /* Command packet length. */ + u32 Value; +}DCMD_TXCMD_T, *PDCMD_TXCMD_T; +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +extern dig_t dm_digtable; +extern u8 dm_shadow[16][256]; +extern DRxPathSel DM_RxPathSelTable; +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ + +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +/*--------------------------Exported Function prototype---------------------*/ +extern void init_hal_dm(struct net_device *dev); +extern void deinit_hal_dm(struct net_device *dev); + +extern void hal_dm_watchdog(struct net_device *dev); + + +extern void init_rate_adaptive(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_txpower_trackingcallback(struct work_struct *work); +#else +extern void dm_txpower_trackingcallback(struct net_device *dev); +#endif + +extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); +extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); +extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); +extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, + u32 dm_value); +extern void DM_ChangeFsyncSetting(struct net_device *dev, + s32 DM_Type, + s32 DM_Value); +extern void dm_force_tx_fw_info(struct net_device *dev, + u32 force_type, + u32 force_value); +extern void dm_init_edca_turbo(struct net_device *dev); +extern void dm_rf_operation_test_callback(unsigned long data); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work); +#else +extern void dm_rf_pathcheck_workitemcallback(struct net_device *dev); +#endif +extern void dm_fsync_timer_callback(unsigned long data); +#if 0 +extern bool dm_check_lbus_status(struct net_device *dev); +#endif +extern void dm_check_fsync(struct net_device *dev); +extern void dm_shadow_init(struct net_device *dev); +extern void dm_initialize_txpower_tracking(struct net_device *dev); + + +#endif /*__R8192UDM_H__ */ + + +/* End of r8192U_dm.h */ diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h new file mode 100644 index 00000000000..388908fc8d2 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_hw.h @@ -0,0 +1,811 @@ +/* + This is part of rtl8187 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official Realtek driver. + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + Parts of this driver are based on the Intel Pro Wireless + 2100 GPL driver. + + We want to tanks the Authors of those projects + and the Ndiswrapper project Authors. +*/ + +/* Mariusz Matuszek added full registers definition with Realtek's name */ + +/* this file contains register definitions for the rtl8187 MAC controller */ +#ifndef R8180_HW +#define R8180_HW + +typedef enum _VERSION_8190{ + // RTL8190 + VERSION_8190_BD=0x3, + VERSION_8190_BE +}VERSION_8190,*PVERSION_8190; +//added for different RF type +typedef enum _RT_RF_TYPE_DEF +{ + RF_1T2R = 0, + RF_2T4R, + + RF_819X_MAX_TYPE +}RT_RF_TYPE_DEF; + +typedef enum _BaseBand_Config_Type{ + BaseBand_Config_PHY_REG = 0, //Radio Path A + BaseBand_Config_AGC_TAB = 1, //Radio Path B +}BaseBand_Config_Type, *PBaseBand_Config_Type; +#if 0 +typedef enum _RT_RF_TYPE_819xU{ + RF_TYPE_MIN = 0, + RF_8225, + RF_8256, + RF_8258, + RF_PSEUDO_11N = 4, +}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU; +#endif +#define RTL8187_REQT_READ 0xc0 +#define RTL8187_REQT_WRITE 0x40 +#define RTL8187_REQ_GET_REGS 0x05 +#define RTL8187_REQ_SET_REGS 0x05 + +#define R8180_MAX_RETRY 255 +#define MAX_TX_URB 5 +#define MAX_RX_URB 16 +//#define MAX_RX_NORMAL_URB 3 +//#define MAX_RX_COMMAND_URB 2 +#define RX_URB_SIZE 9100 + +#define BB_ANTATTEN_CHAN14 0x0c +#define BB_ANTENNA_B 0x40 + +#define BB_HOST_BANG (1<<30) +#define BB_HOST_BANG_EN (1<<2) +#define BB_HOST_BANG_CLK (1<<1) +#define BB_HOST_BANG_RW (1<<3) +#define BB_HOST_BANG_DATA 1 + +//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920) +#define RTL8190_EEPROM_ID 0x8129 +#define EEPROM_VID 0x02 +#define EEPROM_DID 0x04 +#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C + +#define EEPROM_TxPowerDiff 0x1F + + +#define EEPROM_PwDiff 0x21 //0x21 +#define EEPROM_CrystalCap 0x22 //0x22 + + + +#define EEPROM_TxPwIndex_CCK_V1 0x29 //0x29~0x2B +#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C //0x2C~0x2E +#define EEPROM_TxPwIndex_Ver 0x27 //0x27 + +#define EEPROM_Default_TxPowerDiff 0x0 +#define EEPROM_Default_ThermalMeter 0x77 +#define EEPROM_Default_AntTxPowerDiff 0x0 +#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 +#define EEPROM_Default_PwDiff 0x4 +#define EEPROM_Default_CrystalCap 0x5 +#define EEPROM_Default_TxPower 0x1010 +#define EEPROM_ICVersion_ChannelPlan 0x7C //0x7C:ChannelPlan, 0x7D:IC_Version +#define EEPROM_Customer_ID 0x7B //0x7B:CustomerID +#ifdef RTL8190P +#define EEPROM_RFInd_PowerDiff 0x14 +#define EEPROM_ThermalMeter 0x15 +#define EEPROM_TxPwDiff_CrystalCap 0x16 +#define EEPROM_TxPwIndex_CCK 0x18 //0x18~0x25 +#define EEPROM_TxPwIndex_OFDM_24G 0x26 //0x26~0x33 +#define EEPROM_TxPwIndex_OFDM_5G 0x34 //0x34~0x7B +#define EEPROM_C56_CrystalCap 0x17 //0x17 +#define EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex 0x80 //0x80 +#define EEPROM_C56_RfA_HT_OFDM_TxPwIndex 0x81 //0x81~0x83 +#define EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex 0xbc //0xb8 +#define EEPROM_C56_RfC_HT_OFDM_TxPwIndex 0xb9 //0xb9~0xbb +#else +#ifdef RTL8192E +#define EEPROM_RFInd_PowerDiff 0x28 +#define EEPROM_ThermalMeter 0x29 +#define EEPROM_TxPwDiff_CrystalCap 0x2A //0x2A~0x2B +#define EEPROM_TxPwIndex_CCK 0x2C //0x23 +#define EEPROM_TxPwIndex_OFDM_24G 0x3A //0x24~0x26 +#endif +#endif +#define EEPROM_Default_TxPowerLevel 0x10 +//#define EEPROM_ChannelPlan 0x7c //0x7C +#define EEPROM_IC_VER 0x7d //0x7D +#define EEPROM_CRC 0x7e //0x7E~0x7F + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_CAMEO 0x1 +#define EEPROM_CID_RUNTOP 0x2 +#define EEPROM_CID_Senao 0x3 +#define EEPROM_CID_TOSHIBA 0x4 // Toshiba setting, Merge by Jacken, 2008/01/31 +#define EEPROM_CID_NetCore 0x5 +#define EEPROM_CID_Nettronix 0x6 +#define EEPROM_CID_Pronet 0x7 +#define EEPROM_CID_DLINK 0x8 +#define EEPROM_CID_WHQL 0xFE //added by sherry for dtm, 20080728 +//#endif +enum _RTL8192Pci_HW { + MAC0 = 0x000, + MAC1 = 0x001, + MAC2 = 0x002, + MAC3 = 0x003, + MAC4 = 0x004, + MAC5 = 0x005, + PCIF = 0x009, // PCI Function Register 0x0009h~0x000bh +//---------------------------------------------------------------------------- +// 8190 PCIF bits (Offset 0x009-000b, 24bit) +//---------------------------------------------------------------------------- +#define MXDMA2_16bytes 0x000 +#define MXDMA2_32bytes 0x001 +#define MXDMA2_64bytes 0x010 +#define MXDMA2_128bytes 0x011 +#define MXDMA2_256bytes 0x100 +#define MXDMA2_512bytes 0x101 +#define MXDMA2_1024bytes 0x110 +#define MXDMA2_NoLimit 0x7 + +#define MULRW_SHIFT 3 +#define MXDMA2_RX_SHIFT 4 +#define MXDMA2_TX_SHIFT 0 + PMR = 0x00c, // Power management register + EPROM_CMD = 0x00e, +#define EPROM_CMD_RESERVED_MASK BIT5 +#define EPROM_CMD_9356SEL BIT4 +#define EPROM_CMD_OPERATING_MODE_SHIFT 6 +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_NORMAL 0 +#define EPROM_CMD_LOAD 1 +#define EPROM_CMD_PROGRAM 2 +#define EPROM_CS_SHIFT 3 +#define EPROM_CK_SHIFT 2 +#define EPROM_W_SHIFT 1 +#define EPROM_R_SHIFT 0 + + AFR = 0x010, +#define AFR_CardBEn (1<<0) +#define AFR_CLKRUN_SEL (1<<1) +#define AFR_FuncRegEn (1<<2) + + ANAPAR = 0x17, +#define BB_GLOBAL_RESET_BIT 0x1 + BB_GLOBAL_RESET = 0x020, // BasebandGlobal Reset Register + BSSIDR = 0x02E, // BSSID Register + CMDR = 0x037, // Command register +#define CR_RST 0x10 +#define CR_RE 0x08 +#define CR_TE 0x04 +#define CR_MulRW 0x01 + SIFS = 0x03E, // SIFS register + TCR = 0x040, // Transmit Configuration Register + RCR = 0x044, // Receive Configuration Register +//---------------------------------------------------------------------------- +//// 8190 (RCR) Receive Configuration Register (Offset 0x44~47, 32 bit) +////---------------------------------------------------------------------------- +#define RCR_FILTER_MASK (BIT0|BIT1|BIT2|BIT3|BIT5|BIT12|BIT18|BIT19|BIT20|BIT21|BIT22|BIT23) +#define RCR_ONLYERLPKT BIT31 // Early Receiving based on Packet Size. +#define RCR_ENCS2 BIT30 // Enable Carrier Sense Detection Method 2 +#define RCR_ENCS1 BIT29 // Enable Carrier Sense Detection Method 1 +#define RCR_ENMBID BIT27 // Enable Multiple BssId. +#define RCR_ACKTXBW (BIT24|BIT25) // TXBW Setting of ACK frames +#define RCR_CBSSID BIT23 // Accept BSSID match packet +#define RCR_APWRMGT BIT22 // Accept power management packet +#define RCR_ADD3 BIT21 // Accept address 3 match packet +#define RCR_AMF BIT20 // Accept management type frame +#define RCR_ACF BIT19 // Accept control type frame +#define RCR_ADF BIT18 // Accept data type frame +#define RCR_RXFTH BIT13 // Rx FIFO Threshold +#define RCR_AICV BIT12 // Accept ICV error packet +#define RCR_ACRC32 BIT5 // Accept CRC32 error packet +#define RCR_AB BIT3 // Accept broadcast packet +#define RCR_AM BIT2 // Accept multicast packet +#define RCR_APM BIT1 // Accept physical match packet +#define RCR_AAP BIT0 // Accept all unicast packet +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + SLOT_TIME = 0x049, // Slot Time Register + ACK_TIMEOUT = 0x04c, // Ack Timeout Register + PIFS_TIME = 0x04d, // PIFS time + USTIME = 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock. + EDCAPARA_BE = 0x050, // EDCA Parameter of AC BE + EDCAPARA_BK = 0x054, // EDCA Parameter of AC BK + EDCAPARA_VO = 0x058, // EDCA Parameter of AC VO + EDCAPARA_VI = 0x05C, // EDCA Parameter of AC VI +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + RFPC = 0x05F, // Rx FIFO Packet Count + CWRR = 0x060, // Contention Window Report Register + BCN_TCFG = 0x062, // Beacon Time Configuration +#define BCN_TCFG_CW_SHIFT 8 +#define BCN_TCFG_IFS 0 + BCN_INTERVAL = 0x070, // Beacon Interval (TU) + ATIMWND = 0x072, // ATIM Window Size (TU) + BCN_DRV_EARLY_INT = 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT +#define BCN_DRV_EARLY_INT_SWBCN_SHIFT 8 +#define BCN_DRV_EARLY_INT_TIME_SHIFT 0 + BCN_DMATIME = 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA + BCN_ERR_THRESH = 0x078, // Beacon Error Threshold + RWCAM = 0x0A0, //IN 8190 Data Sheet is called CAMcmd + //---------------------------------------------------------------------------- + //// 8190 CAM Command Register (offset 0xA0, 4 byte) + ////---------------------------------------------------------------------------- +#define CAM_CM_SecCAMPolling BIT31 //Security CAM Polling +#define CAM_CM_SecCAMClr BIT30 //Clear all bits in CAM +#define CAM_CM_SecCAMWE BIT16 //Security CAM enable +#define CAM_VALID BIT15 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT5 + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 + +#define CAM_CONFIG_USEDK true +#define CAM_CONFIG_NO_USEDK false +#define CAM_WRITE BIT16 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT31 +#define SCR_UseDK 0x01 + WCAMI = 0x0A4, // Software write CAM input content + RCAMO = 0x0A8, // Software read/write CAM config + SECR = 0x0B0, //Security Configuration Register +#define SCR_TxUseDK BIT0 //Force Tx Use Default Key +#define SCR_RxUseDK BIT1 //Force Rx Use Default Key +#define SCR_TxEncEnable BIT2 //Enable Tx Encryption +#define SCR_RxDecEnable BIT3 //Enable Rx Decryption +#define SCR_SKByA2 BIT4 //Search kEY BY A2 +#define SCR_NoSKMC BIT5 //No Key Search for Multicast + SWREGULATOR = 0x0BD, // Switching Regulator + INTA_MASK = 0x0f4, +//---------------------------------------------------------------------------- +// 8190 IMR/ISR bits (offset 0xfd, 8bits) +//---------------------------------------------------------------------------- +#define IMR8190_DISABLED 0x0 +#define IMR_ATIMEND BIT28 // ATIM Window End Interrupt +#define IMR_TBDOK BIT27 // Transmit Beacon OK Interrupt +#define IMR_TBDER BIT26 // Transmit Beacon Error Interrupt +#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow +#define IMR_TIMEOUT0 BIT14 // TimeOut0 +#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 +#define IMR_RXFOVW BIT12 // Receive FIFO Overflow +#define IMR_RDU BIT11 // Receive Descriptor Unavailable +#define IMR_RXCMDOK BIT10 // Receive Command Packet OK +#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup +#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt +#define IMR_COMDOK BIT7 // Command Queue DMA OK Interrupt +#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define IMR_HCCADOK BIT5 // HCCA Queue DMA OK Interrupt +#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt +#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt +#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt +#define IMR_VODOK BIT1 // AC_VO DMA Interrupt +#define IMR_ROK BIT0 // Receive DMA OK Interrupt + ISR = 0x0f8, // Interrupt Status Register + TPPoll = 0x0fd, // Transmit priority polling register +#define TPPoll_BKQ BIT0 // BK queue polling +#define TPPoll_BEQ BIT1 // BE queue polling +#define TPPoll_VIQ BIT2 // VI queue polling +#define TPPoll_VOQ BIT3 // VO queue polling +#define TPPoll_BQ BIT4 // Beacon queue polling +#define TPPoll_CQ BIT5 // Command queue polling +#define TPPoll_MQ BIT6 // Management queue polling +#define TPPoll_HQ BIT7 // High queue polling +#define TPPoll_HCCAQ BIT8 // HCCA queue polling +#define TPPoll_StopBK BIT9 // Stop BK queue +#define TPPoll_StopBE BIT10 // Stop BE queue +#define TPPoll_StopVI BIT11 // Stop VI queue +#define TPPoll_StopVO BIT12 // Stop VO queue +#define TPPoll_StopMgt BIT13 // Stop Mgnt queue +#define TPPoll_StopHigh BIT14 // Stop High queue +#define TPPoll_StopHCCA BIT15 // Stop HCCA queue +#define TPPoll_SHIFT 8 // Queue ID mapping + + PSR = 0x0ff, // Page Select Register +#define PSR_GEN 0x0 // Page 0 register general MAC Control +#define PSR_CPU 0x1 // Page 1 register for CPU + CPU_GEN = 0x100, // CPU Reset Register + BB_RESET = 0x101, // Baseband Reset +//---------------------------------------------------------------------------- +// 8190 CPU General Register (offset 0x100, 4 byte) +//---------------------------------------------------------------------------- +#define CPU_CCK_LOOPBACK 0x00030000 +#define CPU_GEN_SYSTEM_RESET 0x00000001 +#define CPU_GEN_FIRMWARE_RESET 0x00000008 +#define CPU_GEN_BOOT_RDY 0x00000010 +#define CPU_GEN_FIRM_RDY 0x00000020 +#define CPU_GEN_PUT_CODE_OK 0x00000080 +#define CPU_GEN_BB_RST 0x00000100 +#define CPU_GEN_PWR_STB_CPU 0x00000004 +#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19 +#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1 +#define CPU_GEN_GPIO_UART 0x00007000 + + LED1Cfg = 0x154,// LED1 Configuration Register + LED0Cfg = 0x155,// LED0 Configuration Register + + AcmAvg = 0x170, // ACM Average Period Register + AcmHwCtrl = 0x171, // ACM Hardware Control Register +//---------------------------------------------------------------------------- +// +// 8190 AcmHwCtrl bits (offset 0x171, 1 byte) +//---------------------------------------------------------------------------- +#define AcmHw_HwEn BIT0 +#define AcmHw_BeqEn BIT1 +#define AcmHw_ViqEn BIT2 +#define AcmHw_VoqEn BIT3 +#define AcmHw_BeqStatus BIT4 +#define AcmHw_ViqStatus BIT5 +#define AcmHw_VoqStatus BIT6 + AcmFwCtrl = 0x172, // ACM Firmware Control Register +#define AcmFw_BeqStatus BIT0 +#define AcmFw_ViqStatus BIT1 +#define AcmFw_VoqStatus BIT2 + VOAdmTime = 0x174, // VO Queue Admitted Time Register + VIAdmTime = 0x178, // VI Queue Admitted Time Register + BEAdmTime = 0x17C, // BE Queue Admitted Time Register + RQPN1 = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk + RQPN2 = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High + RQPN3 = 0x188, // Reserved Queue Page Number, Bcn, Public, + QPRR = 0x1E0, // Queue Page Report per TID + QPNR = 0x1F0, // Queue Packet Number report per TID +/* there's 9 tx descriptor base address available */ + BQDA = 0x200, // Beacon Queue Descriptor Address + HQDA = 0x204, // High Priority Queue Descriptor Address + CQDA = 0x208, // Command Queue Descriptor Address + MQDA = 0x20C, // Management Queue Descriptor Address + HCCAQDA = 0x210, // HCCA Queue Descriptor Address + VOQDA = 0x214, // VO Queue Descriptor Address + VIQDA = 0x218, // VI Queue Descriptor Address + BEQDA = 0x21C, // BE Queue Descriptor Address + BKQDA = 0x220, // BK Queue Descriptor Address +/* there's 2 rx descriptor base address availalbe */ + RCQDA = 0x224, // Receive command Queue Descriptor Address + RDQDA = 0x228, // Receive Queue Descriptor Start Address + + MAR0 = 0x240, // Multicast filter. + MAR4 = 0x244, + + CCX_PERIOD = 0x250, // CCX Measurement Period Register, in unit of TU. + CLM_RESULT = 0x251, // CCA Busy fraction register. + NHM_PERIOD = 0x252, // NHM Measurement Period register, in unit of TU. + + NHM_THRESHOLD0 = 0x253, // Noise Histogram Meashorement0. + NHM_THRESHOLD1 = 0x254, // Noise Histogram Meashorement1. + NHM_THRESHOLD2 = 0x255, // Noise Histogram Meashorement2. + NHM_THRESHOLD3 = 0x256, // Noise Histogram Meashorement3. + NHM_THRESHOLD4 = 0x257, // Noise Histogram Meashorement4. + NHM_THRESHOLD5 = 0x258, // Noise Histogram Meashorement5. + NHM_THRESHOLD6 = 0x259, // Noise Histogram Meashorement6 + + MCTRL = 0x25A, // Measurement Control + + NHM_RPI_COUNTER0 = 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0. + NHM_RPI_COUNTER1 = 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1]. + NHM_RPI_COUNTER2 = 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2]. + NHM_RPI_COUNTER3 = 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3]. + NHM_RPI_COUNTER4 = 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4]. + NHM_RPI_COUNTER5 = 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5]. + NHM_RPI_COUNTER6 = 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6]. + NHM_RPI_COUNTER7 = 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7]. + WFCRC0 = 0x2f0, + WFCRC1 = 0x2f4, + WFCRC2 = 0x2f8, + + BW_OPMODE = 0x300, // Bandwidth operation mode +#define BW_OPMODE_11J BIT0 +#define BW_OPMODE_5G BIT1 +#define BW_OPMODE_20MHZ BIT2 + IC_VERRSION = 0x301, //IC_VERSION + MSR = 0x303, // Media Status register +#define MSR_LINK_MASK ((1<<0)|(1<<1)) +#define MSR_LINK_MANAGED 2 +#define MSR_LINK_NONE 0 +#define MSR_LINK_SHIFT 0 +#define MSR_LINK_ADHOC 1 +#define MSR_LINK_MASTER 3 +#define MSR_LINK_ENEDCA (1<<4) + RETRY_LIMIT = 0x304, // Retry Limit [15:8]-short, [7:0]-long +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + TSFR = 0x308, + RRSR = 0x310, // Response Rate Set +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_DUPLICATE 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 +#define BRSR_AckShortPmb BIT23 // CCK ACK: use Short Preamble or not + UFWP = 0x318, + RATR0 = 0x320, // Rate Adaptive Table register1 +//---------------------------------------------------------------------------- +// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte) +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11| \ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + + + DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI + MCS_TXAGC = 0x340, // MCS AGC + CCK_TXAGC = 0x348, // CCK AGC +// IMR = 0x354, // Interrupt Mask Register +// IMR_POLL = 0x360, + MacBlkCtrl = 0x403, // Mac block on/off control register + + //Cmd9346CR = 0x00e, +//#define Cmd9346CR_9356SEL (1<<4) +#if 0 +/* 0x0006 - 0x0007 - reserved */ + RXFIFOCOUNT = 0x010, + TXFIFOCOUNT = 0x012, + BQREQ = 0x013, +/* 0x0010 - 0x0017 - reserved */ + TSFTR = 0x018, + TLPDA = 0x020, + TNPDA = 0x024, + THPDA = 0x028, + BSSID = 0x02E, + RESP_RATE = 0x034, + CMD = 0x037, +#define CMD_RST_SHIFT 4 +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7)) +#define CMD_RX_ENABLE_SHIFT 3 +#define CMD_TX_ENABLE_SHIFT 2 +#define CR_RST ((1<< 4)) +#define CR_RE ((1<< 3)) +#define CR_TE ((1<< 2)) +#define CR_MulRW ((1<< 0)) + + INTA = 0x03e, +#endif + +/////////////////// +////////////////// +#if 0 + TX_CONF = 0x040, +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30 +#define TX_LOOPBACK_SHIFT 17 +#define TX_LOOPBACK_MAC 1 +#define TX_LOOPBACK_BASEBAND 2 +#define TX_LOOPBACK_NONE 0 +#define TX_LOOPBACK_CONTINUE 3 +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18)) +#define TX_LRLRETRY_SHIFT 0 +#define TX_SRLRETRY_SHIFT 8 +#define TX_NOICV_SHIFT 19 +#define TX_NOCRC_SHIFT 16 +#define TCR_DurProcMode ((1<<30)) +#define TCR_DISReqQsize ((1<<28)) +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25)) +#define TCR_HWVERID_SHIFT 25 +#define TCR_SWPLCPLEN ((1<<24)) +#define TCR_PLCP_LEN TCR_SAT // rtl8180 +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21)) +#define TCR_MXDMA_1024 6 +#define TCR_MXDMA_2048 7 +#define TCR_MXDMA_SHIFT 21 +#define TCR_DISCW ((1<<20)) +#define TCR_ICV ((1<<19)) +#define TCR_LBK ((1<<18)|(1<<17)) +#define TCR_LBK1 ((1<<18)) +#define TCR_LBK0 ((1<<17)) +#define TCR_CRC ((1<<16)) +#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185 + + RX_CONF = 0x044, +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \ +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23)) +#define RX_CHECK_BSSID_SHIFT 23 +#define ACCEPT_PWR_FRAME_SHIFT 22 +#define ACCEPT_MNG_FRAME_SHIFT 20 +#define ACCEPT_CTL_FRAME_SHIFT 19 +#define ACCEPT_DATA_FRAME_SHIFT 18 +#define ACCEPT_ICVERR_FRAME_SHIFT 12 +#define ACCEPT_CRCERR_FRAME_SHIFT 5 +#define ACCEPT_BCAST_FRAME_SHIFT 3 +#define ACCEPT_MCAST_FRAME_SHIFT 2 +#define ACCEPT_ALLMAC_FRAME_SHIFT 0 +#define ACCEPT_NICMAC_FRAME_SHIFT 1 +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15)) +#define RX_FIFO_THRESHOLD_SHIFT 13 +#define RX_FIFO_THRESHOLD_128 3 +#define RX_FIFO_THRESHOLD_256 4 +#define RX_FIFO_THRESHOLD_512 5 +#define RX_FIFO_THRESHOLD_1024 6 +#define RX_FIFO_THRESHOLD_NONE 7 +#define RX_AUTORESETPHY_SHIFT 28 +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10)) +#define MAX_RX_DMA_2048 7 +#define MAX_RX_DMA_1024 6 +#define MAX_RX_DMA_SHIFT 10 +#define RCR_ONLYERLPKT ((1<<31)) +#define RCR_CS_SHIFT 29 +#define RCR_CS_MASK ((1<<30) | (1<<29)) +#define RCR_ENMARP ((1<<28)) +#define RCR_CBSSID ((1<<23)) +#define RCR_APWRMGT ((1<<22)) +#define RCR_ADD3 ((1<<21)) +#define RCR_AMF ((1<<20)) +#define RCR_ACF ((1<<19)) +#define RCR_ADF ((1<<18)) +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13)) +#define RCR_RXFTH2 ((1<<15)) +#define RCR_RXFTH1 ((1<<14)) +#define RCR_RXFTH0 ((1<<13)) +#define RCR_AICV ((1<<12)) +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8)) +#define RCR_MXDMA2 ((1<<10)) +#define RCR_MXDMA1 ((1<< 9)) +#define RCR_MXDMA0 ((1<< 8)) +#define RCR_9356SEL ((1<< 6)) +#define RCR_ACRC32 ((1<< 5)) +#define RCR_AB ((1<< 3)) +#define RCR_AM ((1<< 2)) +#define RCR_APM ((1<< 1)) +#define RCR_AAP ((1<< 0)) + + INT_TIMEOUT = 0x048, + + TX_BEACON_RING_ADDR = 0x04c, + +#endif +#if 0 + CONFIG0 = 0x051, +#define CONFIG0_WEP104 ((1<<6)) +#define CONFIG0_LEDGPO_En ((1<<4)) +#define CONFIG0_Aux_Status ((1<<3)) +#define CONFIG0_GL ((1<<1)|(1<<0)) +#define CONFIG0_GL1 ((1<<1)) +#define CONFIG0_GL0 ((1<<0)) + CONFIG1 = 0x052, +#define CONFIG1_LEDS ((1<<7)|(1<<6)) +#define CONFIG1_LEDS1 ((1<<7)) +#define CONFIG1_LEDS0 ((1<<6)) +#define CONFIG1_LWACT ((1<<4)) +#define CONFIG1_MEMMAP ((1<<3)) +#define CONFIG1_IOMAP ((1<<2)) +#define CONFIG1_VPD ((1<<1)) +#define CONFIG1_PMEn ((1<<0)) + CONFIG2 = 0x053, +#define CONFIG2_LCK ((1<<7)) +#define CONFIG2_ANT ((1<<6)) +#define CONFIG2_DPS ((1<<3)) +#define CONFIG2_PAPE_sign ((1<<2)) +#define CONFIG2_PAPE_time ((1<<1)|(1<<0)) +#define CONFIG2_PAPE_time1 ((1<<1)) +#define CONFIG2_PAPE_time0 ((1<<0)) + ANA_PARAM = 0x054, + CONFIG3 = 0x059, +#define CONFIG3_GNTSel ((1<<7)) +#define CONFIG3_PARM_En ((1<<6)) +#define CONFIG3_Magic ((1<<5)) +#define CONFIG3_CardB_En ((1<<3)) +#define CONFIG3_CLKRUN_En ((1<<2)) +#define CONFIG3_FuncRegEn ((1<<1)) +#define CONFIG3_FBtbEn ((1<<0)) +#define CONFIG3_CLKRUN_SHIFT 2 +#define CONFIG3_ANAPARAM_W_SHIFT 6 + CONFIG4 = 0x05a, +#define CONFIG4_VCOPDN ((1<<7)) +#define CONFIG4_PWROFF ((1<<6)) +#define CONFIG4_PWRMGT ((1<<5)) +#define CONFIG4_LWPME ((1<<4)) +#define CONFIG4_LWPTN ((1<<2)) +#define CONFIG4_RFTYPE ((1<<1)|(1<<0)) +#define CONFIG4_RFTYPE1 ((1<<1)) +#define CONFIG4_RFTYPE0 ((1<<0)) + TESTR = 0x05b, +#define TFPC_AC 0x05C + +#define SCR 0x05F + PGSELECT = 0x05e, +#define PGSELECT_PG_SHIFT 0 + SECURITY = 0x05f, +#define SECURITY_WEP_TX_ENABLE_SHIFT 1 +#define SECURITY_WEP_RX_ENABLE_SHIFT 0 +#define SECURITY_ENCRYP_104 1 +#define SECURITY_ENCRYP_SHIFT 4 +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5)) + + ANA_PARAM2 = 0x060, + BEACON_INTERVAL = 0x070, +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \ +(1<<6)|(1<<7)|(1<<8)|(1<<9)) + + ATIM_WND = 0x072, +#define ATIM_WND_MASK (0x01FF) + + BCN_INTR_ITV = 0x074, +#define BCN_INTR_ITV_MASK (0x01FF) + + ATIM_INTR_ITV = 0x076, +#define ATIM_INTR_ITV_MASK (0x01FF) + + AckTimeOutReg = 0x079, //ACK timeout register, in unit of 4 us. + PHY_ADR = 0x07c, + PHY_READ = 0x07e, + RFPinsOutput = 0x080, + RFPinsEnable = 0x082, +//Page 0 + RFPinsSelect = 0x084, +#define SW_CONTROL_GPIO 0x400 + RFPinsInput = 0x086, + RF_PARA = 0x088, + RF_TIMING = 0x08c, + GP_ENABLE = 0x090, + GPIO = 0x091, + TX_AGC_CTL = 0x09c, +#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01 +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0 +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1 +#define TX_AGC_CTL_FEEDBACK_ANT 2 +#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02 + OFDM_TXAGC = 0x09e, + ANTSEL = 0x09f, + + + + SIFS = 0x0b4, + DIFS = 0x0b5, + SLOT = 0x0b6, + CW_CONF = 0x0bc, +#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02 +#define CW_CONF_PERPACKET_CW 0x01 +#define CW_CONF_PERPACKET_RETRY_SHIFT 1 +#define CW_CONF_PERPACKET_CW_SHIFT 0 + CW_VAL = 0x0bd, + RATE_FALLBACK = 0x0be, +#define MAX_RESP_RATE_SHIFT 4 +#define MIN_RESP_RATE_SHIFT 0 +#define RATE_FALLBACK_CTL_ENABLE 0x80 +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00 + ACM_CONTROL = 0x0BF, // ACM Control Registe +//---------------------------------------------------------------------------- +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte) +//---------------------------------------------------------------------------- +#define VOQ_ACM_EN (0x01 << 7) //BIT7 +#define VIQ_ACM_EN (0x01 << 6) //BIT6 +#define BEQ_ACM_EN (0x01 << 5) //BIT5 +#define ACM_HW_EN (0x01 << 4) //BIT4 +#define TXOPSEL (0x01 << 3) //BIT3 +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time + CONFIG5 = 0x0D8, +#define CONFIG5_TX_FIFO_OK ((1<<7)) +#define CONFIG5_RX_FIFO_OK ((1<<6)) +#define CONFIG5_CALON ((1<<5)) +#define CONFIG5_EACPI ((1<<2)) +#define CONFIG5_LANWake ((1<<1)) +#define CONFIG5_PME_STS ((1<<0)) + TX_DMA_POLLING = 0x0fd, +#define TX_DMA_POLLING_BEACON_SHIFT 7 +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6 +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5 +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4 +#define TX_DMA_STOP_BEACON_SHIFT 3 +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2 +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1 +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0 + CWR = 0x0DC, + RetryCTR = 0x0DE, + INT_MIG = 0x0E2, // Interrupt Migration (0xE2 ~ 0xE3) + TID_AC_MAP = 0x0E8, // TID to AC Mapping Register + ANA_PARAM3 = 0x0EE, + + +//page 1 + Wakeup0 = 0x084, + Wakeup1 = 0x08C, + Wakeup2LD = 0x094, + Wakeup2HD = 0x09C, + Wakeup3LD = 0x0A4, + Wakeup3HD = 0x0AC, + Wakeup4LD = 0x0B4, + Wakeup4HD = 0x0BC, + CRC0 = 0x0C4, + CRC1 = 0x0C6, + CRC2 = 0x0C8, + CRC3 = 0x0CA, + CRC4 = 0x0CC, +/* 0x00CE - 0x00D3 - reserved */ + + RFSW_CTRL = 0x272, // 0x272-0x273. + +/**************************************************************************/ + FER = 0x0F0, + FEMR = 0x0F4, + FPSR = 0x0F8, + FFER = 0x0FC, + + AC_VO_PARAM = 0x0F0, // AC_VO Parameters Record + AC_VI_PARAM = 0x0F4, // AC_VI Parameters Record + AC_BE_PARAM = 0x0F8, // AC_BE Parameters Record + AC_BK_PARAM = 0x0FC, // AC_BK Parameters Record + TALLY_SEL = 0x0fc, +#endif +} +; +//---------------------------------------------------------------------------- +// 818xB AnaParm & AnaParm2 Register +//---------------------------------------------------------------------------- +//#define ANAPARM_ASIC_ON 0x45090658 +//#define ANAPARM2_ASIC_ON 0x727f3f52 + +#define GPI 0x108 +#define GPO 0x109 +#define GPE 0x10a +#endif diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c new file mode 100644 index 00000000000..497be2f2665 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -0,0 +1,1408 @@ +/* + This file contains wireless extension handlers. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004-2005 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part + of the official realtek driver. + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon. + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + + We want to tanks the Authors of those projects and the Ndiswrapper + project Authors. +*/ + +#include +#include "r8192E.h" +#include "r8192E_hw.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif + +#define RATE_COUNT 12 +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000, + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; + + +#ifndef ENETDOWN +#define ENETDOWN 1 +#endif +static int r8192_wx_get_freq(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b); +} + + +#if 0 + +static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa, + union iwreq_data *wrqu, char *b) +{ + int *parms = (int *)b; + int bi = parms[0]; + + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + DMESG("setting beacon interval to %x",bi); + + priv->ieee80211->beacon_interval=bi; + rtl8180_commit(dev); + up(&priv->wx_sem); + + return 0; +} + + +static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv=ieee80211_priv(dev); + int *parms = (int *)extra; + + priv->ieee80211->force_associate = (parms[0] > 0); + + + return 0; +} + +#endif +static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv=ieee80211_priv(dev); + + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b); +} + + + +static int r8192_wx_get_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra); +} + + + +static int r8192_wx_set_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); + + up(&priv->wx_sem); + + return ret; +} + + +static int r8192_wx_set_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_get_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra); +} + +static int r8192_wx_set_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_get_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra); +} + +#ifdef JOHN_IOCTL +u16 read_rtl8225(struct net_device *dev, u8 addr); +void write_rtl8225(struct net_device *dev, u8 adr, u16 data); +u32 john_read_rtl8225(struct net_device *dev, u8 adr); +void _write_rtl8225(struct net_device *dev, u8 adr, u16 data); + +static int r8192_wx_read_regs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 addr; + u16 data1; + + down(&priv->wx_sem); + + + get_user(addr,(u8*)wrqu->data.pointer); + data1 = read_rtl8225(dev, addr); + wrqu->data.length = data1; + + up(&priv->wx_sem); + return 0; + +} + +static int r8192_wx_write_regs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 addr; + + down(&priv->wx_sem); + + get_user(addr, (u8*)wrqu->data.pointer); + write_rtl8225(dev, addr, wrqu->data.length); + + up(&priv->wx_sem); + return 0; + +} + +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data); + +static int r8192_wx_read_bb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 databb; +#if 0 + int i; + for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) ); +#endif + + down(&priv->wx_sem); + + databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000); + wrqu->data.length = databb; + + up(&priv->wx_sem); + return 0; +} + +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data); +static int r8192_wx_write_bb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 databb; + + down(&priv->wx_sem); + + get_user(databb, (u8*)wrqu->data.pointer); + rtl8187_write_phy(dev, wrqu->data.length, databb); + + up(&priv->wx_sem); + return 0; + +} + + +static int r8192_wx_write_nicb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 addr; + + down(&priv->wx_sem); + + get_user(addr, (u32*)wrqu->data.pointer); + write_nic_byte(dev, addr, wrqu->data.length); + + up(&priv->wx_sem); + return 0; + +} +static int r8192_wx_read_nicb(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 addr; + u16 data1; + + down(&priv->wx_sem); + + get_user(addr,(u32*)wrqu->data.pointer); + data1 = read_nic_byte(dev, addr); + wrqu->data.length = data1; + + up(&priv->wx_sem); + return 0; +} + +static int r8192_wx_get_ap_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; + struct ieee80211_network *target; + int name_len; + + down(&priv->wx_sem); + + //count the length of input ssid + for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++); + + //search for the correspoding info which is received + list_for_each_entry(target, &ieee->network_list, list) { + if ( (target->ssid_len == name_len) && + (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){ + if(target->wpa_ie_len>0 || target->rsn_ie_len>0 ) + //set flags=1 to indicate this ap is WPA + wrqu->data.flags = 1; + else wrqu->data.flags = 0; + + + break; + } + } + + up(&priv->wx_sem); + return 0; +} + + + +#endif + +static int r8192_wx_set_rawtx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int ret; + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; + +} + +static int r8192_wx_force_reset(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra); + priv->force_reset = *extra; + up(&priv->wx_sem); + return 0; + +} + + +static int r8192_wx_set_crcmon(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int *parms = (int *)extra; + int enable = (parms[0] > 0); + short prev = priv->crcmon; + + down(&priv->wx_sem); + + if(enable) + priv->crcmon=1; + else + priv->crcmon=0; + + DMESG("bad CRC in monitor mode are %s", + priv->crcmon ? "accepted" : "rejected"); + + if(prev != priv->crcmon && priv->up){ + //rtl8180_down(dev); + //rtl8180_up(dev); + } + + up(&priv->wx_sem); + + return 0; +} + +static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + int ret; + + rtState = priv->ieee80211->eRFPowerState; + down(&priv->wx_sem); +#ifdef ENABLE_IPS + if(wrqu->mode == IW_MODE_ADHOC){ + + if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if(rtState == eRfOff){ + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); + up(&priv->wx_sem); + return -1; + } + else{ + printk("=========>%s(): IPSLeave\n",__FUNCTION__); + IPSLeave(dev); + } + } + } + } +#endif + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b); + + //rtl8187_set_rxconf(dev); + + up(&priv->wx_sem); + return ret; +} + +struct iw_range_with_scan_capa +{ + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Scan capabilities */ + __u8 scan_capa; +}; +static int rtl8180_wx_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; + struct r8192_priv *priv = ieee80211_priv(dev); + u16 val; + int i; + + wrqu->data.length = sizeof(*range); + memset(range, 0, sizeof(*range)); + + /* Let's try to keep this struct in the same order as in + * linux/include/wireless.h + */ + + /* TODO: See what values we can set, and remove the ones we can't + * set, or fill them with some default data. + */ + + /* ~5 Mb/s real (802.11b) */ + range->throughput = 5 * 1000 * 1000; + + // TODO: Not used in 802.11b? +// range->min_nwid; /* Minimal NWID we are able to set */ + // TODO: Not used in 802.11b? +// range->max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ +// range->old_num_channels; +// range->old_num_frequency; +// range->old_freq[6]; /* Filler to keep "version" at the same offset */ + if(priv->rf_set_sens != NULL) + range->sensitivity = priv->max_sens; /* signal level threshold range */ + + range->max_qual.qual = 100; + /* TODO: Find real max RSSI and stick here */ + range->max_qual.level = 0; + range->max_qual.noise = -98; + range->max_qual.updated = 7; /* Updated all three */ + + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + range->avg_qual.level = 20 + -98; + range->avg_qual.noise = 0; + range->avg_qual.updated = 7; /* Updated all three */ + + range->num_bitrates = RATE_COUNT; + + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { + range->bitrate[i] = rtl8180_rates[i]; + } + + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + range->min_pmp=0; + range->max_pmp = 5000000; + range->min_pmt = 0; + range->max_pmt = 65535*1000; + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 16; + +// range->retry_capa; /* What retry options are supported */ +// range->retry_flags; /* How to decode max/min retry limit */ +// range->r_time_flags; /* How to decode max/min retry life */ +// range->min_retry; /* Minimal number of retries */ +// range->max_retry; /* Maximal number of retries */ +// range->min_r_time; /* Minimal retry lifetime */ +// range->max_r_time; /* Maximal retry lifetime */ + + + for (i = 0, val = 0; i < 14; i++) { + + // Include only legal frequencies for some countries +#ifdef ENABLE_DOT11D + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { +#else + if ((priv->ieee80211->channel_map)[i+1]) { +#endif + range->freq[val].i = i + 1; + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; + range->freq[val].e = 1; + val++; + } else { + // FIXME: do we need to set anything for channels + // we don't use ? + } + + if (val == IW_MAX_FREQUENCIES) + break; + } + range->num_frequency = val; + range->num_channels = val; +#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| + IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; +#endif + tmp->scan_capa = 0x01; + return 0; +} + + +static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + RT_RF_POWER_STATE rtState; + int ret; + rtState = priv->ieee80211->eRFPowerState; + if(!priv->up) return -ENETDOWN; + if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) + return -EAGAIN; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) + { + struct iw_scan_req* req = (struct iw_scan_req*)b; + if (req->essid_len) + { + //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid); + ieee->current_network.ssid_len = req->essid_len; + memcpy(ieee->current_network.ssid, req->essid, req->essid_len); + //printk("=====>network ssid:%s\n", ieee->current_network.ssid); + } + } + + down(&priv->wx_sem); +#ifdef ENABLE_IPS + priv->ieee80211->actscanning = true; + if(priv->ieee80211->state != IEEE80211_LINKED){ + if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if(rtState == eRfOff){ + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); + up(&priv->wx_sem); + return -1; + } + else{ + printk("=========>%s(): IPSLeave\n",__FUNCTION__); + IPSLeave(dev); + } + } + } + priv->ieee80211->scanning = 0; + ieee80211_softmac_scan_syncro(priv->ieee80211); + ret = 0; + } + else +#else + + if(priv->ieee80211->state != IEEE80211_LINKED){ + priv->ieee80211->scanning = 0; + ieee80211_softmac_scan_syncro(priv->ieee80211); + ret = 0; + } + else +#endif + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b); + + up(&priv->wx_sem); + return ret; +} + + +static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + if(!priv->up) return -ENETDOWN; + + down(&priv->wx_sem); + + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_set_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RT_RF_POWER_STATE rtState; + int ret; + + rtState = priv->ieee80211->eRFPowerState; + down(&priv->wx_sem); +#ifdef ENABLE_IPS + if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if(rtState == eRfOff){ + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); + up(&priv->wx_sem); + return -1; + } + else{ + printk("=========>%s(): IPSLeave\n",__FUNCTION__); + IPSLeave(dev); + } + } + } +#endif + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); + + up(&priv->wx_sem); + + return ret; +} + + + + +static int r8192_wx_get_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); + + up(&priv->wx_sem); + + return ret; +} + + +static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); + + up(&priv->wx_sem); + return ret; +} + +static int r8192_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); +} + + +static int r8192_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if (wrqu->frag.disabled) + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; + else { + if (wrqu->frag.value < MIN_FRAG_THRESHOLD || + wrqu->frag.value > MAX_FRAG_THRESHOLD) + return -EINVAL; + + priv->ieee80211->fts = wrqu->frag.value & ~0x1; + } + + return 0; +} + + +static int r8192_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + wrqu->frag.value = priv->ieee80211->fts; + wrqu->frag.fixed = 0; /* no auto select */ + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); + + return 0; +} + + +static int r8192_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + + int ret; + struct r8192_priv *priv = ieee80211_priv(dev); +// struct sockaddr *temp = (struct sockaddr *)awrq; + + down(&priv->wx_sem); + + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); + + up(&priv->wx_sem); + + return ret; + +} + + +static int r8192_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra); +} + + +static int r8192_wx_get_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); +} + +static int r8192_wx_set_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int ret; + + struct ieee80211_device *ieee = priv->ieee80211; + //u32 TargetContent; + u32 hwkey[4]={0,0,0,0}; + u8 mask=0xff; + u32 key_idx=0; + u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x01}, + {0x00,0x00,0x00,0x00,0x00,0x02}, + {0x00,0x00,0x00,0x00,0x00,0x03} }; + int i; + + if(!priv->up) return -ENETDOWN; + + down(&priv->wx_sem); + + RT_TRACE(COMP_SEC, "Setting SW wep key"); + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key); + + up(&priv->wx_sem); + + + //sometimes, the length is zero while we do not type key value + if(wrqu->encoding.length!=0){ + + for(i=0 ; i<4 ; i++){ + hwkey[i] |= key[4*i+0]&mask; + if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00; + if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00; + hwkey[i] |= (key[4*i+1]&mask)<<8; + hwkey[i] |= (key[4*i+2]&mask)<<16; + hwkey[i] |= (key[4*i+3]&mask)<<24; + } + + #define CONF_WEP40 0x4 + #define CONF_WEP104 0x14 + + switch(wrqu->encoding.flags & IW_ENCODE_INDEX){ + case 0: key_idx = ieee->tx_keyidx; break; + case 1: key_idx = 0; break; + case 2: key_idx = 1; break; + case 3: key_idx = 2; break; + case 4: key_idx = 3; break; + default: break; + } + + //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags); + if(wrqu->encoding.length==0x5){ + ieee->pairwise_key_type = KEY_TYPE_WEP40; + EnableHWSecurityConfig8192(dev); + setKey( dev, + key_idx, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP40, //KeyType + zero_addr[key_idx], + 0, //DefaultKey + hwkey); //KeyContent + +#if 0 + if(key_idx == 0){ + + //write_nic_byte(dev, SECR, 7); + setKey( dev, + 4, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP40, //KeyType + broadcast_addr, //addr + 0, //DefaultKey + hwkey); //KeyContent + } +#endif + } + + else if(wrqu->encoding.length==0xd){ + ieee->pairwise_key_type = KEY_TYPE_WEP104; + EnableHWSecurityConfig8192(dev); + setKey( dev, + key_idx, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP104, //KeyType + zero_addr[key_idx], + 0, //DefaultKey + hwkey); //KeyContent +#if 0 + if(key_idx == 0){ + + //write_nic_byte(dev, SECR, 7); + setKey( dev, + 4, //EntryNo + key_idx, //KeyIndex + KEY_TYPE_WEP104, //KeyType + broadcast_addr, //addr + 0, //DefaultKey + hwkey); //KeyContent + } +#endif + } + else printk("wrong type in WEP, not WEP40 and WEP104\n"); + + + } + +#if 0 + //consider the setting different key index situation + //wrqu->encoding.flags = 801 means that we set key with index "1" + if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){ + printk("===>1\n"); + //write_nic_byte(dev, SECR, 7); + EnableHWSecurityConfig8192(dev); + //copy wpa config from default key(key0~key3) to broadcast key(key5) + // + key_idx = (wrqu->encoding.flags & 0xf)-1 ; + write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) ); + write_cam(dev, (4*6)+1, 0xffffffff); + write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) ); + write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) ); + write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) ); + write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) ); + } +#endif + + return ret; +} + + +static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union + iwreq_data *wrqu, char *p){ + + struct r8192_priv *priv = ieee80211_priv(dev); + int *parms=(int*)p; + int mode=parms[0]; + + priv->ieee80211->active_scan = mode; + + return 1; +} + + + +static int r8192_wx_set_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int err = 0; + + down(&priv->wx_sem); + + if (wrqu->retry.flags & IW_RETRY_LIFETIME || + wrqu->retry.disabled){ + err = -EINVAL; + goto exit; + } + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){ + err = -EINVAL; + goto exit; + } + + if(wrqu->retry.value > R8180_MAX_RETRY){ + err= -EINVAL; + goto exit; + } + if (wrqu->retry.flags & IW_RETRY_MAX) { + priv->retry_rts = wrqu->retry.value; + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); + + }else { + priv->retry_data = wrqu->retry.value; + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); + } + + /* FIXME ! + * We might try to write directly the TX config register + * or to restart just the (R)TX process. + * I'm unsure if whole reset is really needed + */ + + rtl8192_commit(dev); + /* + if(priv->up){ + rtl8180_rtx_disable(dev); + rtl8180_rx_enable(dev); + rtl8180_tx_enable(dev); + + } + */ +exit: + up(&priv->wx_sem); + + return err; +} + +static int r8192_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + + wrqu->retry.disabled = 0; /* can't be disabled */ + + if ((wrqu->retry.flags & IW_RETRY_TYPE) == + IW_RETRY_LIFETIME) + return -EINVAL; + + if (wrqu->retry.flags & IW_RETRY_MAX) { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; + wrqu->retry.value = priv->retry_rts; + } else { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; + wrqu->retry.value = priv->retry_data; + } + //DMESG("returning %d",wrqu->retry.value); + + + return 0; +} + +static int r8192_wx_get_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + if(priv->rf_set_sens == NULL) + return -1; /* we have not this support for this radio */ + wrqu->sens.value = priv->sens; + return 0; +} + + +static int r8192_wx_set_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + + short err = 0; + down(&priv->wx_sem); + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); + if(priv->rf_set_sens == NULL) { + err= -1; /* we have not this support for this radio */ + goto exit; + } + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0) + priv->sens = wrqu->sens.value; + else + err= -EINVAL; + +exit: + up(&priv->wx_sem); + + return err; +} + +#if (WIRELESS_EXT >= 18) +#if 0 +static int r8192_wx_get_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + int ret = 0; + ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra); + return ret; +} +#endif +static int r8192_wx_set_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret=0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + + down(&priv->wx_sem); + ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra); + + { + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 zero[6] = {0}; + u32 key[4] = {0}; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct iw_point *encoding = &wrqu->encoding; +#if 0 + static u8 CAM_CONST_ADDR[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; +#endif + u8 idx = 0, alg = 0, group = 0; + if ((encoding->flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01 + { + ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; + CamResetAllEntry(dev); + goto end_hw_sec; + } + alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) + idx --; + group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; + + if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) + { + if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) ) + alg = KEY_TYPE_WEP104; + ieee->pairwise_key_type = alg; + EnableHWSecurityConfig8192(dev); + } + memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1 + + if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) ) + { + if (ext->key_len == 13) + ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; + setKey( dev, + idx,//EntryNo + idx, //KeyIndex + alg, //KeyType + zero, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + else if (group) + { + ieee->group_key_type = alg; + setKey( dev, + idx,//EntryNo + idx, //KeyIndex + alg, //KeyType + broadcast_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + else //pairwise key + { + if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ + write_nic_byte(dev, 0x173, 1); //fix aes bug + } + setKey( dev, + 4,//EntryNo + idx, //KeyIndex + alg, //KeyType + (u8*)ieee->ap_mac_addr, //MacAddr + 0, //DefaultKey + key); //KeyContent + } + + + } + +end_hw_sec: + up(&priv->wx_sem); +#endif + return ret; + +} +static int r8192_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + int ret=0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + //printk("====>%s()\n", __FUNCTION__); + struct r8192_priv *priv = ieee80211_priv(dev); + down(&priv->wx_sem); + ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); + up(&priv->wx_sem); +#endif + return ret; +} + +static int r8192_wx_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //printk("====>%s()\n", __FUNCTION__); + + int ret=0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct r8192_priv *priv = ieee80211_priv(dev); + down(&priv->wx_sem); + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); + up(&priv->wx_sem); +#endif + return ret; +} +#endif +static int r8192_wx_set_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); + int ret=0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + struct r8192_priv *priv = ieee80211_priv(dev); + down(&priv->wx_sem); +#if 1 + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); +#endif + up(&priv->wx_sem); + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret); +#endif + return ret; + + +} + +static int dummy(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu,char *b) +{ + return -1; +} + + +static iw_handler r8192_wx_handlers[] = +{ + NULL, /* SIOCSIWCOMMIT */ + r8192_wx_get_name, /* SIOCGIWNAME */ + dummy, /* SIOCSIWNWID */ + dummy, /* SIOCGIWNWID */ + r8192_wx_set_freq, /* SIOCSIWFREQ */ + r8192_wx_get_freq, /* SIOCGIWFREQ */ + r8192_wx_set_mode, /* SIOCSIWMODE */ + r8192_wx_get_mode, /* SIOCGIWMODE */ + r8192_wx_set_sens, /* SIOCSIWSENS */ + r8192_wx_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + rtl8180_wx_get_range, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ + dummy, /* SIOCSIWSPY */ + dummy, /* SIOCGIWSPY */ + NULL, /* SIOCGIWTHRSPY */ + NULL, /* SIOCWIWTHRSPY */ + r8192_wx_set_wap, /* SIOCSIWAP */ + r8192_wx_get_wap, /* SIOCGIWAP */ +#if (WIRELESS_EXT >= 18) + r8192_wx_set_mlme, /* MLME-- */ +#else + NULL, +#endif + dummy, /* SIOCGIWAPLIST -- depricated */ + r8192_wx_set_scan, /* SIOCSIWSCAN */ + r8192_wx_get_scan, /* SIOCGIWSCAN */ + r8192_wx_set_essid, /* SIOCSIWESSID */ + r8192_wx_get_essid, /* SIOCGIWESSID */ + dummy, /* SIOCSIWNICKN */ + dummy, /* SIOCGIWNICKN */ + NULL, /* -- hole -- */ + NULL, /* -- hole -- */ + r8192_wx_set_rate, /* SIOCSIWRATE */ + r8192_wx_get_rate, /* SIOCGIWRATE */ + r8192_wx_set_rts, /* SIOCSIWRTS */ + r8192_wx_get_rts, /* SIOCGIWRTS */ + r8192_wx_set_frag, /* SIOCSIWFRAG */ + r8192_wx_get_frag, /* SIOCGIWFRAG */ + dummy, /* SIOCSIWTXPOW */ + dummy, /* SIOCGIWTXPOW */ + r8192_wx_set_retry, /* SIOCSIWRETRY */ + r8192_wx_get_retry, /* SIOCGIWRETRY */ + r8192_wx_set_enc, /* SIOCSIWENCODE */ + r8192_wx_get_enc, /* SIOCGIWENCODE */ + r8192_wx_set_power, /* SIOCSIWPOWER */ + r8192_wx_get_power, /* SIOCGIWPOWER */ + NULL, /*---hole---*/ + NULL, /*---hole---*/ + r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */ + NULL, /* SIOCSIWGENIE */ +#if (WIRELESS_EXT >= 18) + r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */ + NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */ + r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ +#else + NULL, + NULL, + NULL, +#endif + NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ + NULL, /* SIOCSIWPMKSA */ + NULL, /*---hole---*/ + +}; + + +static const struct iw_priv_args r8192_private_args[] = { + + { + SIOCIWFIRSTPRIV + 0x0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" + }, + + { + SIOCIWFIRSTPRIV + 0x1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" + + }, + { + SIOCIWFIRSTPRIV + 0x2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" + } +#ifdef JOHN_IOCTL + , + { + SIOCIWFIRSTPRIV + 0x3, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF" + } + , + { + SIOCIWFIRSTPRIV + 0x4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF" + } + , + { + SIOCIWFIRSTPRIV + 0x5, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB" + } + , + { + SIOCIWFIRSTPRIV + 0x6, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB" + } + , + { + SIOCIWFIRSTPRIV + 0x7, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb" + } + , + { + SIOCIWFIRSTPRIV + 0x8, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb" + } + , + { + SIOCIWFIRSTPRIV + 0x9, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" + } + +#endif + , + { + SIOCIWFIRSTPRIV + 0x3, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" + + } + +}; + + +static iw_handler r8192_private_handler[] = { +// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */ + r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ +// r8192_wx_set_forceassociate, +// r8192_wx_set_beaconinterval, +// r8192_wx_set_monitor_type, + r8192_wx_set_scan_type, + r8192_wx_set_rawtx, +#ifdef JOHN_IOCTL + r8192_wx_read_regs, + r8192_wx_write_regs, + r8192_wx_read_bb, + r8192_wx_write_bb, + r8192_wx_read_nicb, + r8192_wx_write_nicb, + r8192_wx_get_ap_status +#endif + r8192_wx_force_reset, +}; + +//#if WIRELESS_EXT >= 17 +struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + struct iw_statistics* wstats = &priv->wstats; + int tmp_level = 0; + int tmp_qual = 0; + int tmp_noise = 0; + if(ieee->state < IEEE80211_LINKED) + { + wstats->qual.qual = 0; + wstats->qual.level = 0; + wstats->qual.noise = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + wstats->qual.updated = 0x0f; +#endif + return wstats; + } + + tmp_level = (&ieee->current_network)->stats.rssi; + tmp_qual = (&ieee->current_network)->stats.signal; + tmp_noise = (&ieee->current_network)->stats.noise; + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); + + wstats->qual.level = tmp_level; + wstats->qual.qual = tmp_qual; + wstats->qual.noise = tmp_noise; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + wstats->qual.updated = 0x0f; +#endif + return wstats; +} +//#endif + + +struct iw_handler_def r8192_wx_handlers_def={ + .standard = r8192_wx_handlers, + .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), + .private = r8192_private_handler, + .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), +#if WIRELESS_EXT >= 17 + .get_wireless_stats = r8192_get_wireless_stats, +#endif + .private_args = (struct iw_priv_args *)r8192_private_args, +}; diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h new file mode 100644 index 00000000000..79ebdb698a4 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_wx.h @@ -0,0 +1,22 @@ +/* + This is part of rtl8180 OpenSource driver - v 0.3 + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the official realtek driver + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver + + We want to tanks the Authors of such projects and the Ndiswrapper project Authors. +*/ + +/* this file (will) contains wireless extension handlers*/ + +#ifndef R8180_WX_H +#define R8180_WX_H +//#include +//#include "ieee80211.h" +extern struct iw_handler_def r8192_wx_handlers_def; +/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */ +extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); +#endif diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c new file mode 100644 index 00000000000..d0f7c21bdf7 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -0,0 +1,181 @@ +/* + Power management interface routines. + Written by Mariusz Matuszek. + This code is currently just a placeholder for later work and + does not do anything useful. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) +*/ + +#ifdef CONFIG_PM_RTL + +#include "r8192E.h" +#include "r8192E_hw.h" +#include "r8192_pm.h" +#include "r8190_rtl8256.h" + +int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state) +{ + printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event); + return(-EAGAIN); +} + + +int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct r8192_priv *priv = ieee80211_priv(dev); + u8 ucRegRead; + u32 ulRegRead; + + RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n"); + if (!netif_running(dev)) + goto out_pci_suspend; + + dev->stop(dev); +#if 0 + + netif_carrier_off(dev); + + ieee80211_softmac_stop_protocol(priv->ieee80211); + + write_nic_byte(dev,MSR,(read_nic_byte(dev,MSR)&0xfc)|MSR_LINK_NONE); + if(!priv->ieee80211->bSupportRemoteWakeUp) { + /* disable tx/rx. In 8185 we write 0x10 (Reset bit), + * but here we make reference to WMAC and wirte 0x0. + * 2006.11.21 Emily + */ + write_nic_byte(dev, CMDR, 0); + } + //disable interrupt + write_nic_dword(dev,INTA_MASK,0); + priv->irq_enabled = 0; + write_nic_dword(dev,ISR,read_nic_dword(dev, ISR)); + + /* need to free DM related functions */ +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20) + cancel_work_sync(&priv->reset_wq); +#else +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&priv->reset_wq); +#endif +#endif + del_timer_sync(&priv->fsync_timer); + del_timer_sync(&priv->watch_dog_timer); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&priv->watch_dog_wq); + cancel_delayed_work(&priv->update_beacon_wq); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + cancel_work_sync(&priv->qos_activate); +#else +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + cancel_delayed_work(&priv->qos_activate); +#endif +#endif + + /* TODO +#if ((DEV_BUS_TYPE == PCI_INTERFACE) && (HAL_CODE_BASE == RTL8192)) +pHalData->bHwRfOffAction = 2; +#endif +*/ +#endif + // Call MgntActSet_RF_State instead to prevent RF config race condition. + // By Bruce, 2008-01-17. + // + if(!priv->ieee80211->bSupportRemoteWakeUp) { + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); + // 2006.11.30. System reset bit + ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead|=CPU_GEN_SYSTEM_RESET; + write_nic_dword(dev, CPU_GEN, ulRegRead); + } else { + //2008.06.03 for WOL + write_nic_dword(dev, WFCRC0, 0xffffffff); + write_nic_dword(dev, WFCRC1, 0xffffffff); + write_nic_dword(dev, WFCRC2, 0xffffffff); +#ifdef RTL8190P + //GPIO 0 = TRUE + ucRegRead = read_nic_byte(dev, GPO); + ucRegRead |= BIT0; + write_nic_byte(dev, GPO, ucRegRead); +#endif + //Write PMR register + write_nic_byte(dev, PMR, 0x5); + //Disable tx, enanble rx + write_nic_byte(dev, MacBlkCtrl, 0xa); + } + +out_pci_suspend: + RT_TRACE(COMP_POWER, "r8192E support WOL call??????????????????????\n"); + if(priv->ieee80211->bSupportRemoteWakeUp) { + RT_TRACE(COMP_POWER, "r8192E support WOL call!!!!!!!!!!!!!!!!!!.\n"); + } + netif_device_detach(dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev,state),\ + priv->ieee80211->bSupportRemoteWakeUp?1:0); + pci_set_power_state(pdev,pci_choose_state(pdev,state)); + + return 0; +} + +int rtl8192E_resume (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + //struct r8192_priv *priv = ieee80211_priv(dev); + //union iwreq_data wrqu; + int err; + u32 val; + + RT_TRACE(COMP_POWER, "================>r8192E resume call."); + + pci_set_power_state(pdev, PCI_D0); + + err = pci_enable_device(pdev); + if(err) { + printk(KERN_ERR "%s: pci_enable_device failed on resume\n", + dev->name); + return err; + } + + pci_restore_state(pdev); + + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries + * from interfering with C3 CPU state. pci_restore_state won't help + * here since it only restores the first 64 bytes pci config header. + */ + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) { + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + } + + + + pci_enable_wake(pdev, PCI_D0, 0); + + if(!netif_running(dev)) + goto out; + + netif_device_attach(dev); + + dev->open(dev); +out: + RT_TRACE(COMP_POWER, "<================r8192E resume call.\n"); + return 0; +} + + +int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable) +{ + printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n", + state.event, enable); + return(-EAGAIN); +} + +#endif //CONFIG_PM_RTL diff --git a/drivers/staging/rtl8192e/r8192_pm.h b/drivers/staging/rtl8192e/r8192_pm.h new file mode 100644 index 00000000000..68d292b1d86 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192_pm.h @@ -0,0 +1,28 @@ +/* + Power management interface routines. + Written by Mariusz Matuszek. + This code is currently just a placeholder for later work and + does not do anything useful. + + This is part of rtl8180 OpenSource driver. + Copyright (C) Andrea Merello 2004 + Released under the terms of GPL (General Public Licence) + +*/ + +#ifdef CONFIG_PM_RTL + +#ifndef R8192E_PM_H +#define R8192E_PM_H + +#include +#include + +int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state); +int rtl8192E_suspend (struct pci_dev *dev, pm_message_t state); +int rtl8192E_resume (struct pci_dev *dev); +int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable); + +#endif //R8192E_PM_H + +#endif // CONFIG_PM_RTL diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c new file mode 100644 index 00000000000..5f6c869e190 --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -0,0 +1,826 @@ +/****************************************************************************** + + (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. + + Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File) + + Note: The module is responsible for handling TX and RX command packet. + 1. TX : Send set and query configuration command packet. + 2. RX : Receive tx feedback, beacon state, query configuration + command packet. + + Function: + + Export: + + Abbrev: + + History: + Data Who Remark + + 05/06/2008 amy Create initial version porting from windows driver. + +******************************************************************************/ +#include "r8192E.h" +#include "r8192E_hw.h" +#include "r819xE_cmdpkt.h" +/*---------------------------Define Local Constant---------------------------*/ +/* Debug constant*/ +#define CMPK_DEBOUNCE_CNT 1 +/* 2007/10/24 MH Add for printing a range of data. */ +#define CMPK_PRINT(Address)\ +{\ + unsigned char i;\ + u32 temp[10];\ + \ + memcpy(temp, Address, 40);\ + for (i = 0; i <40; i+=4)\ + printk("\r\n %08x", temp[i]);\ +}\ + +/*---------------------------Define functions---------------------------------*/ +/*----------------------------------------------------------------------------- + * Function: cmpk_message_handle_tx() + * + * Overview: Driver internal module can call the API to send message to + * firmware side. For example, you can send a debug command packet. + * Or you can send a request for FW to modify RLX4181 LBUS HW bank. + * Otherwise, you can change MAC/PHT/RF register by firmware at + * run time. We do not support message more than one segment now. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/06/2008 amy porting from windows code. + * + *---------------------------------------------------------------------------*/ + extern RT_STATUS cmpk_message_handle_tx( + struct net_device *dev, + u8* code_virtual_address, + u32 packettype, + u32 buffer_len) +{ + + RT_STATUS rt_status = RT_STATUS_SUCCESS; +#ifdef RTL8192U + return rt_status; +#else + struct r8192_priv *priv = ieee80211_priv(dev); + u16 frag_threshold; + u16 frag_length = 0, frag_offset = 0; + rt_firmware *pfirmware = priv->pFirmware; + struct sk_buff *skb; + unsigned char *seg_ptr; + cb_desc *tcb_desc; + u8 bLastIniPkt; + + PTX_FWINFO_8190PCI pTxFwInfo = NULL; + int i; + + //spin_lock_irqsave(&priv->tx_lock,flags); + RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len); + firmware_init_param(dev); + //Fragmentation might be required + frag_threshold = pfirmware->cmdpacket_frag_thresold; + do { + if((buffer_len - frag_offset) > frag_threshold) { + frag_length = frag_threshold ; + bLastIniPkt = 0; + + } else { + frag_length =(u16)(buffer_len - frag_offset); + bLastIniPkt = 1; + + } + + /* Allocate skb buffer to contain firmware info and tx descriptor info + * add 4 to avoid packet appending overflow. + * */ +#ifdef RTL8192U + skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); +#else + skb = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4); +#endif + if(skb == NULL) { + rt_status = RT_STATUS_FAILURE; + goto Failed; + } + + memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); + tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = packettype; + tcb_desc->bLastIniPkt = bLastIniPkt; + tcb_desc->pkt_size = frag_length; + +#ifdef RTL8192U + skb_reserve(skb, USB_HWDESC_HEADER_LEN); +#endif + + //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom); + seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom); + + pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr; + memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI)); + memset(pTxFwInfo,0x12,8); + + seg_ptr +=sizeof(TX_FWINFO_8190PCI); + + /* + * Transform from little endian to big endian + * and pending zero + */ + seg_ptr = skb->tail; + for(i=0 ; i < frag_length; i+=4) { + *seg_ptr++ = ((i+0)ieee80211->softmac_hard_start_xmit(skb,dev); + + code_virtual_address += frag_length; + frag_offset += frag_length; + +#if 0 + { + int k; + printk("------------tx cmd------------\n"); + for(k = 0; ktx_lock,flags); + return rt_status; + + +#endif +} /* CMPK_Message_Handle_Tx */ + +/*----------------------------------------------------------------------------- + * Function: cmpk_counttxstatistic() + * + * Overview: + * + * Input: PADAPTER pAdapter - . + * CMPK_TXFB_T *psTx_FB - . + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_count_txstatistic( + struct net_device *dev, + cmpk_txfb_t *pstx_fb) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef ENABLE_PS + RT_RF_POWER_STATE rtState; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + + // When RF is off, we should not count the packet for hw/sw synchronize + // reason, ie. there may be a duration while sw switch is changed and hw + // switch is being changed. 2006.12.04, by shien chang. + if (rtState == eRfOff) + { + return; + } +#endif + +#ifdef TODO + if(pAdapter->bInHctTest) + return; +#endif + /* We can not know the packet length and transmit type: broadcast or uni + or multicast. So the relative statistics must be collected in tx + feedback info. */ + if (pstx_fb->tok) + { + priv->stats.txfeedbackok++; + priv->stats.txoktotal++; + priv->stats.txokbytestotal += pstx_fb->pkt_length; + priv->stats.txokinperiod++; + + /* We can not make sure broadcast/multicast or unicast mode. */ + if (pstx_fb->pkt_type == PACKET_MULTICAST) + { + priv->stats.txmulticast++; + priv->stats.txbytesmulticast += pstx_fb->pkt_length; + } + else if (pstx_fb->pkt_type == PACKET_BROADCAST) + { + priv->stats.txbroadcast++; + priv->stats.txbytesbroadcast += pstx_fb->pkt_length; + } + else + { + priv->stats.txunicast++; + priv->stats.txbytesunicast += pstx_fb->pkt_length; + } + } + else + { + priv->stats.txfeedbackfail++; + priv->stats.txerrtotal++; + priv->stats.txerrbytestotal += pstx_fb->pkt_length; + + /* We can not make sure broadcast/multicast or unicast mode. */ + if (pstx_fb->pkt_type == PACKET_MULTICAST) + { + priv->stats.txerrmulticast++; + } + else if (pstx_fb->pkt_type == PACKET_BROADCAST) + { + priv->stats.txerrbroadcast++; + } + else + { + priv->stats.txerrunicast++; + } + } + + priv->stats.txretrycount += pstx_fb->retry_cnt; + priv->stats.txfeedbackretry += pstx_fb->retry_cnt; + +} /* cmpk_CountTxStatistic */ + + + +/*----------------------------------------------------------------------------- + * Function: cmpk_handle_tx_feedback() + * + * Overview: The function is responsible for extract the message inside TX + * feedbck message from firmware. It will contain dedicated info in + * ws-06-0063-rtl8190-command-packet-specification. Please + * refer to chapter "TX Feedback Element". We have to read 20 bytes + * in the command packet. + * + * Input: struct net_device * dev + * u8 * pmsg - Msg Ptr of the command packet. + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/08/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_handle_tx_feedback( + struct net_device *dev, + u8 * pmsg) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + cmpk_txfb_t rx_tx_fb; /* */ + + priv->stats.txfeedback++; + + /* 0. Display received message. */ + //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg); + + /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + /* It seems that FW use big endian(MIPS) and DRV use little endian in + windows OS. So we have to read the content byte by byte or transfer + endian type before copy the message copy. */ +#if 0 // The TX FEEDBACK packet element address + //rx_tx_fb.Element_ID = pMsg[0]; + //rx_tx_fb.Length = pMsg[1]; + rx_tx_fb.TOK = pMsg[2]>>7; + rx_tx_fb.Fail_Reason = (pMsg[2] & 0x70) >> 4; + rx_tx_fb.TID = (pMsg[2] & 0x0F); + rx_tx_fb.Qos_Pkt = pMsg[3] >> 7; + rx_tx_fb.Bandwidth = (pMsg[3] & 0x40) >> 6; + rx_tx_fb.Retry_Cnt = pMsg[5]; + rx_tx_fb.Pkt_ID = (pMsg[6] << 8) | pMsg[7]; + rx_tx_fb.Seq_Num = (pMsg[8] << 8) | pMsg[9]; + rx_tx_fb.S_Rate = pMsg[10]; + rx_tx_fb.F_Rate = pMsg[11]; + rx_tx_fb.S_RTS_Rate = pMsg[12]; + rx_tx_fb.F_RTS_Rate = pMsg[13]; + rx_tx_fb.pkt_length = (pMsg[14] << 8) | pMsg[15]; +#endif + /* 2007/07/05 MH Use pointer to transfer structure memory. */ + //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T)); + memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); + /* 2. Use tx feedback info to count TX statistics. */ + cmpk_count_txstatistic(dev, &rx_tx_fb); +#if 0 + /* 2007/07/11 MH Assign current operate rate. */ + if (pAdapter->RegWirelessMode == WIRELESS_MODE_A || + pAdapter->RegWirelessMode == WIRELESS_MODE_B || + pAdapter->RegWirelessMode == WIRELESS_MODE_G) + { + pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F); + } + else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G || + pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G) + { + pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F); + } +#endif + /* 2007/01/17 MH Comment previous method for TX statistic function. */ + /* Collect info TX feedback packet to fill TCB. */ + /* We can not know the packet length and transmit type: broadcast or uni + or multicast. */ + //CountTxStatistics( pAdapter, &tcb ); + +} /* cmpk_Handle_Tx_Feedback */ + +void +cmdpkt_beacontimerinterrupt_819xusb( + struct net_device *dev +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u16 tx_rate; + { + // + // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn. + // + if((priv->ieee80211->current_network.mode == IEEE_A) || + (priv->ieee80211->current_network.mode == IEEE_N_5G) || + ((priv->ieee80211->current_network.mode == IEEE_N_24G) && (!priv->ieee80211->pHTInfo->bCurSuppCCK))) + { + tx_rate = 60; + DMESG("send beacon frame tx rate is 6Mbpm\n"); + } + else + { + tx_rate =10; + DMESG("send beacon frame tx rate is 1Mbpm\n"); + } + + //rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon + + } + +} + + + + +/*----------------------------------------------------------------------------- + * Function: cmpk_handle_interrupt_status() + * + * Overview: The function is responsible for extract the message from + * firmware. It will contain dedicated info in + * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. + * Please refer to chapter "Interrupt Status Element". + * + * Input: struct net_device *dev, + * u8* pmsg - Message Pointer of the command packet. + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Add this for rtl8192 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_handle_interrupt_status( + struct net_device *dev, + u8* pmsg) +{ + cmpk_intr_sta_t rx_intr_status; /* */ + struct r8192_priv *priv = ieee80211_priv(dev); + + DMESG("---> cmpk_Handle_Interrupt_Status()\n"); + + /* 0. Display received message. */ + //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); + + /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + /* It seems that FW use big endian(MIPS) and DRV use little endian in + windows OS. So we have to read the content byte by byte or transfer + endian type before copy the message copy. */ + //rx_bcn_state.Element_ID = pMsg[0]; + //rx_bcn_state.Length = pMsg[1]; + rx_intr_status.length = pmsg[1]; + if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) + { + DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); + return; + } + + + // Statistics of beacon for ad-hoc mode. + if( priv->ieee80211->iw_mode == IW_MODE_ADHOC) + { + //2 maybe need endian transform? + rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); + //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4))); + + DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); + + if (rx_intr_status.interrupt_status & ISR_TxBcnOk) + { + priv->ieee80211->bibsscoordinator = true; + priv->stats.txbeaconokint++; + } + else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) + { + priv->ieee80211->bibsscoordinator = false; + priv->stats.txbeaconerr++; + } + + if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) + { + cmdpkt_beacontimerinterrupt_819xusb(dev); + } + + } + + // Other informations in interrupt status we need? + + + DMESG("<---- cmpk_handle_interrupt_status()\n"); + +} /* cmpk_handle_interrupt_status */ + + +/*----------------------------------------------------------------------------- + * Function: cmpk_handle_query_config_rx() + * + * Overview: The function is responsible for extract the message from + * firmware. It will contain dedicated info in + * ws-06-0063-rtl8190-command-packet-specification. Please + * refer to chapter "Beacon State Element". + * + * Input: u8 * pmsg - Message Pointer of the command packet. + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_handle_query_config_rx( + struct net_device *dev, + u8* pmsg) +{ + cmpk_query_cfg_t rx_query_cfg; /* */ + + /* 0. Display received message. */ + //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); + + /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + /* It seems that FW use big endian(MIPS) and DRV use little endian in + windows OS. So we have to read the content byte by byte or transfer + endian type before copy the message copy. */ + //rx_query_cfg.Element_ID = pMsg[0]; + //rx_query_cfg.Length = pMsg[1]; + rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; + rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; + rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; + rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; + rx_query_cfg.cfg_offset = pmsg[7]; + rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | + (pmsg[10] << 8) | (pmsg[11] << 0); + rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | + (pmsg[14] << 8) | (pmsg[15] << 0); + +} /* cmpk_Handle_Query_Config_Rx */ + + +/*----------------------------------------------------------------------------- + * Function: cmpk_count_tx_status() + * + * Overview: Count aggregated tx status from firmwar of one type rx command + * packet element id = RX_TX_STATUS. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void cmpk_count_tx_status( struct net_device *dev, + cmpk_tx_status_t *pstx_status) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + +#ifdef ENABLE_PS + + RT_RF_POWER_STATE rtstate; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + + // When RF is off, we should not count the packet for hw/sw synchronize + // reason, ie. there may be a duration while sw switch is changed and hw + // switch is being changed. 2006.12.04, by shien chang. + if (rtState == eRfOff) + { + return; + } +#endif + + priv->stats.txfeedbackok += pstx_status->txok; + priv->stats.txoktotal += pstx_status->txok; + + priv->stats.txfeedbackfail += pstx_status->txfail; + priv->stats.txerrtotal += pstx_status->txfail; + + priv->stats.txretrycount += pstx_status->txretry; + priv->stats.txfeedbackretry += pstx_status->txretry; + + //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length; + //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length; + //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++; + + priv->stats.txmulticast += pstx_status->txmcok; + priv->stats.txbroadcast += pstx_status->txbcok; + priv->stats.txunicast += pstx_status->txucok; + + priv->stats.txerrmulticast += pstx_status->txmcfail; + priv->stats.txerrbroadcast += pstx_status->txbcfail; + priv->stats.txerrunicast += pstx_status->txucfail; + + priv->stats.txbytesmulticast += pstx_status->txmclength; + priv->stats.txbytesbroadcast += pstx_status->txbclength; + priv->stats.txbytesunicast += pstx_status->txuclength; + + priv->stats.last_packet_rate = pstx_status->rate; +} /* cmpk_CountTxStatus */ + + + +/*----------------------------------------------------------------------------- + * Function: cmpk_handle_tx_status() + * + * Overview: Firmware add a new tx feedback status to reduce rx command + * packet buffer operation load. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_handle_tx_status( + struct net_device *dev, + u8* pmsg) +{ + cmpk_tx_status_t rx_tx_sts; /* */ + + memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t)); + /* 2. Use tx feedback info to count TX statistics. */ + cmpk_count_tx_status(dev, &rx_tx_sts); + +} /* cmpk_Handle_Tx_Status */ + + +/*----------------------------------------------------------------------------- + * Function: cmpk_handle_tx_rate_history() + * + * Overview: Firmware add a new tx rate history + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/12/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +static void +cmpk_handle_tx_rate_history( + struct net_device *dev, + u8* pmsg) +{ + cmpk_tx_rahis_t *ptxrate; +// RT_RF_POWER_STATE rtState; + u8 i, j; + u16 length = sizeof(cmpk_tx_rahis_t); + u32 *ptemp; + struct r8192_priv *priv = ieee80211_priv(dev); + + +#ifdef ENABLE_PS + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + + // When RF is off, we should not count the packet for hw/sw synchronize + // reason, ie. there may be a duration while sw switch is changed and hw + // switch is being changed. 2006.12.04, by shien chang. + if (rtState == eRfOff) + { + return; + } +#endif + + ptemp = (u32 *)pmsg; + + // + // Do endian transfer to word alignment(16 bits) for windows system. + // You must do different endian transfer for linux and MAC OS + // + for (i = 0; i < (length/4); i++) + { + u16 temp1, temp2; + + temp1 = ptemp[i]&0x0000FFFF; + temp2 = ptemp[i]>>16; + ptemp[i] = (temp1<<16)|temp2; + } + + ptxrate = (cmpk_tx_rahis_t *)pmsg; + + if (ptxrate == NULL ) + { + return; + } + + for (i = 0; i < 16; i++) + { + // Collect CCK rate packet num + if (i < 4) + priv->stats.txrate.cck[i] += ptxrate->cck[i]; + + // Collect OFDM rate packet num + if (i< 8) + priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; + + for (j = 0; j < 4; j++) + priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; + } + +} /* cmpk_Handle_Tx_Rate_History */ + + +/*----------------------------------------------------------------------------- + * Function: cmpk_message_handle_rx() + * + * Overview: In the function, we will capture different RX command packet + * info. Every RX command packet element has different message + * length and meaning in content. We only support three type of RX + * command packet now. Please refer to document + * ws-06-0063-rtl8190-command-packet-specification. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/06/2008 amy Create Version 0 porting from windows code. + * + *---------------------------------------------------------------------------*/ +extern u32 +cmpk_message_handle_rx( + struct net_device *dev, + struct ieee80211_rx_stats *pstats) +{ +// u32 debug_level = DBG_LOUD; + struct r8192_priv *priv = ieee80211_priv(dev); + int total_length; + u8 cmd_length, exe_cnt = 0; + u8 element_id; + u8 *pcmd_buff; + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n"); + + /* 0. Check inpt arguments. If is is a command queue message or pointer is + null. */ + if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL)) + { + /* Print error message. */ + /*RT_TRACE(COMP_SEND, DebugLevel, + ("\n\r[CMPK]-->Err queue id or pointer"));*/ + return 0; /* This is not a command packet. */ + } + + /* 1. Read received command packet message length from RFD. */ + total_length = pstats->Length; + + /* 2. Read virtual address from RFD. */ + pcmd_buff = pstats->virtual_address; + + /* 3. Read command pakcet element id and length. */ + element_id = pcmd_buff[0]; + /*RT_TRACE(COMP_SEND, DebugLevel, + ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ + + /* 4. Check every received command packet conent according to different + element type. Because FW may aggregate RX command packet to minimize + transmit time between DRV and FW.*/ + // Add a counter to prevent to locked in the loop too long + while (total_length > 0 || exe_cnt++ >100) + { + /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ + element_id = pcmd_buff[0]; + + switch(element_id) + { + case RX_TX_FEEDBACK: + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n"); + cmpk_handle_tx_feedback (dev, pcmd_buff); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + + case RX_INTERRUPT_STATUS: + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n"); + cmpk_handle_interrupt_status(dev, pcmd_buff); + cmd_length = sizeof(cmpk_intr_sta_t); + break; + + case BOTH_QUERY_CONFIG: + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n"); + cmpk_handle_query_config_rx(dev, pcmd_buff); + cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; + break; + + case RX_TX_STATUS: + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n"); + cmpk_handle_tx_status(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_STS_SIZE; + break; + + case RX_TX_PER_PKT_FEEDBACK: + // You must at lease add a switch case element here, + // Otherwise, we will jump to default case. + //DbgPrint("CCX Test\r\n"); + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n"); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + + case RX_TX_RATE_HISTORY: + //DbgPrint(" rx tx rate history\r\n"); + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n"); + cmpk_handle_tx_rate_history(dev, pcmd_buff); + cmd_length = CMPK_TX_RAHIS_SIZE; + break; + + default: + + RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknow CMD Element\n"); + return 1; /* This is a command packet. */ + } + // 2007/01/22 MH Display received rx command packet info. + //cmpk_Display_Message(cmd_length, pcmd_buff); + + // 2007/01/22 MH Add to display tx statistic. + //cmpk_DisplayTxStatistic(pAdapter); + + /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ + priv->stats.rxcmdpkt[element_id]++; + + total_length -= cmd_length; + pcmd_buff += cmd_length; + } /* while (total_length > 0) */ + return 1; /* This is a command packet. */ + + RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n"); +} /* CMPK_Message_Handle_Rx */ diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.h b/drivers/staging/rtl8192e/r819xE_cmdpkt.h new file mode 100644 index 00000000000..8fe2b9e949e --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.h @@ -0,0 +1,207 @@ +#ifndef R819XUSB_CMDPKT_H +#define R819XUSB_CMDPKT_H +/* Different command packet have dedicated message length and definition. */ +#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) //20 +#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 +#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 +#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)// +#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)// +#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) + +/* 2008/05/08 amy For USB constant. */ +#define ISR_TxBcnOk BIT27 // Transmit Beacon OK +#define ISR_TxBcnErr BIT26 // Transmit Beacon Error +#define ISR_BcnTimerIntr BIT13 // Beacon Timer Interrupt + +#if 0 +/* Define packet type. */ +typedef enum tag_packet_type +{ + PACKET_BROADCAST, + PACKET_MULTICAST, + PACKET_UNICAST, + PACKET_TYPE_MAX +}cmpk_pkt_type_e; +#endif + +/* Define element ID of command packet. */ + +/*------------------------------Define structure----------------------------*/ +/* Define different command packet structure. */ +/* 1. RX side: TX feedback packet. */ +typedef struct tag_cmd_pkt_tx_feedback +{ + // DWORD 0 + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + /* 2007/07/05 MH Change tx feedback info field. */ + /*------TX Feedback Info Field */ + u8 TID:4; /* */ + u8 fail_reason:3; /* */ + u8 tok:1; /* Transmit ok. */ + u8 reserve1:4; /* */ + u8 pkt_type:2; /* */ + u8 bandwidth:1; /* */ + u8 qos_pkt:1; /* */ + + // DWORD 1 + u8 reserve2; /* */ + /*------TX Feedback Info Field */ + u8 retry_cnt; /* */ + u16 pkt_id; /* */ + + // DWORD 3 + u16 seq_num; /* */ + u8 s_rate; /* Start rate. */ + u8 f_rate; /* Final rate. */ + + // DWORD 4 + u8 s_rts_rate; /* */ + u8 f_rts_rate; /* */ + u16 pkt_length; /* */ + + // DWORD 5 + u16 reserve3; /* */ + u16 duration; /* */ +}cmpk_txfb_t; + +/* 2. RX side: Interrupt status packet. It includes Beacon State, + Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */ +typedef struct tag_cmd_pkt_interrupt_status +{ + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + u16 reserve; + u32 interrupt_status; /* Interrupt Status. */ +}cmpk_intr_sta_t; + + +/* 3. TX side: Set configuration packet. */ +typedef struct tag_cmd_pkt_set_configuration +{ + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + u16 reserve1; /* */ + u8 cfg_reserve1:3; + u8 cfg_size:2; /* Configuration info. */ + u8 cfg_type:2; /* Configuration info. */ + u8 cfg_action:1; /* Configuration info. */ + u8 cfg_reserve2; /* Configuration info. */ + u8 cfg_page:4; /* Configuration info. */ + u8 cfg_reserve3:4; /* Configuration info. */ + u8 cfg_offset; /* Configuration info. */ + u32 value; /* */ + u32 mask; /* */ +}cmpk_set_cfg_t; + +/* 4. Both side : TX/RX query configuraton packet. The query structure is the + same as set configuration. */ +#define cmpk_query_cfg_t cmpk_set_cfg_t + +/* 5. Multi packet feedback status. */ +typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007 +{ + // For endian transfer --> Driver will not the same as firmware structure. + // DW 0 + u16 reserve1; + u8 length; // Command packet length + u8 element_id; // Command packet type + + // DW 1 + u16 txfail; // Tx Fail count + u16 txok; // Tx ok count + + // DW 2 + u16 txmcok; // tx multicast + u16 txretry; // Tx Retry count + + // DW 3 + u16 txucok; // tx unicast + u16 txbcok; // tx broadcast + + // DW 4 + u16 txbcfail; // + u16 txmcfail; // + + // DW 5 + u16 reserve2; // + u16 txucfail; // + + // DW 6-8 + u32 txmclength; + u32 txbclength; + u32 txuclength; + + // DW 9 + u16 reserve3_23; + u8 reserve3_1; + u8 rate; +}__attribute__((packed)) cmpk_tx_status_t; + +/* 6. Debug feedback message. */ +/* 2007/10/23 MH Define RX debug message */ +typedef struct tag_rx_debug_message_feedback +{ + // For endian transfer --> for driver + // DW 0 + u16 reserve1; + u8 length; // Command packet length + u8 element_id; // Command packet type + + // DW 1-?? + // Variable debug message. + +}cmpk_rx_dbginfo_t; + +/* 2008/03/20 MH Define transmit rate history. For big endian format. */ +typedef struct tag_tx_rate_history +{ + // For endian transfer --> for driver + // DW 0 + u8 element_id; // Command packet type + u8 length; // Command packet length + u16 reserved1; + + // DW 1-2 CCK rate counter + u16 cck[4]; + + // DW 3-6 + u16 ofdm[8]; + + // DW 7-14 + //UINT16 MCS_BW0_SG0[16]; + + // DW 15-22 + //UINT16 MCS_BW1_SG0[16]; + + // DW 23-30 + //UINT16 MCS_BW0_SG1[16]; + + // DW 31-38 + //UINT16 MCS_BW1_SG1[16]; + + // DW 7-14 BW=0 SG=0 + // DW 15-22 BW=1 SG=0 + // DW 23-30 BW=0 SG=1 + // DW 31-38 BW=1 SG=1 + u16 ht_mcs[4][16]; + +}__attribute__((packed)) cmpk_tx_rahis_t; + +typedef enum tag_command_packet_directories +{ + RX_TX_FEEDBACK = 0, + RX_INTERRUPT_STATUS = 1, + TX_SET_CONFIG = 2, + BOTH_QUERY_CONFIG = 3, + RX_TX_STATUS = 4, + RX_DBGINFO_FEEDBACK = 5, + RX_TX_PER_PKT_FEEDBACK = 6, + RX_TX_RATE_HISTORY = 7, + RX_CMD_ELE_MAX +}cmpk_element_e; + +extern u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats); + + +#endif diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c new file mode 100644 index 00000000000..8046d1b53a0 --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -0,0 +1,668 @@ +/************************************************************************************************** + * Procedure: Init boot code/firmware code/data session + * + * Description: This routine will intialize firmware. If any error occurs during the initialization + * process, the routine shall terminate immediately and return fail. + * NIC driver should call NdisOpenFile only from MiniportInitialize. + * + * Arguments: The pointer of the adapter + + * Returns: + * NDIS_STATUS_FAILURE - the following initialization process should be terminated + * NDIS_STATUS_SUCCESS - if firmware initialization process success +**************************************************************************************************/ +//#include "ieee80211.h" +#include "r8192E.h" +#include "r8192E_hw.h" +#ifdef RTL8190P +#include "r819xP_firmware_img.h" +#else +#include "r819xE_firmware_img.h" +#endif +#include "r819xE_firmware.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +#include +#endif + +extern void firmware_init_param(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + rt_firmware *pfirmware = priv->pFirmware; + + pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE); +} + +/* + * segment the img and use the ptr and length to remember info on each segment + * + */ +bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + bool rt_status = true; + u16 frag_threshold; + u16 frag_length, frag_offset = 0; + //u16 total_size; + int i; + + rt_firmware *pfirmware = priv->pFirmware; + struct sk_buff *skb; + unsigned char *seg_ptr; + cb_desc *tcb_desc; + u8 bLastIniPkt; + + firmware_init_param(dev); + //Fragmentation might be required + frag_threshold = pfirmware->cmdpacket_frag_thresold; + do { + if((buffer_len - frag_offset) > frag_threshold) { + frag_length = frag_threshold ; + bLastIniPkt = 0; + + } else { + frag_length = buffer_len - frag_offset; + bLastIniPkt = 1; + + } + + /* Allocate skb buffer to contain firmware info and tx descriptor info + * add 4 to avoid packet appending overflow. + * */ + //skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); + skb = dev_alloc_skb(frag_length + 4); + memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); + tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; + tcb_desc->bLastIniPkt = bLastIniPkt; + + //skb_reserve(skb, USB_HWDESC_HEADER_LEN); + seg_ptr = skb->data; + /* + * Transform from little endian to big endian + * and pending zero + */ + for(i=0 ; i < frag_length; i+=4) { + *seg_ptr++ = ((i+0)txbuf_size= (u16)i; + skb_put(skb, i); + priv->ieee80211->softmac_hard_start_xmit(skb,dev); + + code_virtual_address += frag_length; + frag_offset += frag_length; + + }while(frag_offset < buffer_len); + + return rt_status; + +#if 0 +cmdsend_downloadcode_fail: + rt_status = false; + RT_TRACE(COMP_ERR, "CmdSendDownloadCode fail !!\n"); + return rt_status; +#endif +} + +bool +fwSendNullPacket( + struct net_device *dev, + u32 Length +) +{ + bool rtStatus = true; + struct r8192_priv *priv = ieee80211_priv(dev); + struct sk_buff *skb; + cb_desc *tcb_desc; + unsigned char *ptr_buf; + bool bLastInitPacket = false; + + //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + skb = dev_alloc_skb(Length+ 4); + memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); + tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; + tcb_desc->bLastIniPkt = bLastInitPacket; + ptr_buf = skb_put(skb, Length); + memset(ptr_buf,0,Length); + tcb_desc->txbuf_size= (u16)Length; + + if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ + (priv->ieee80211->queue_stop) ) { + RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n"); + skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); + } else { + priv->ieee80211->softmac_hard_start_xmit(skb,dev); + } + + //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + return rtStatus; +} + +//----------------------------------------------------------------------------- +// Procedure: Check whether main code is download OK. If OK, turn on CPU +// +// Description: CPU register locates in different page against general register. +// Switch to CPU register in the begin and switch back before return +// +// +// Arguments: The pointer of the adapter +// +// Returns: +// NDIS_STATUS_FAILURE - the following initialization process should be terminated +// NDIS_STATUS_SUCCESS - if firmware initialization process success +//----------------------------------------------------------------------------- +bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) +{ + bool rt_status = true; + int check_putcodeOK_time = 200000, check_bootOk_time = 200000; + u32 CPU_status = 0; + + /* Check whether put code OK */ + do { + CPU_status = read_nic_dword(dev, CPU_GEN); + + if(CPU_status&CPU_GEN_PUT_CODE_OK) + break; + + }while(check_putcodeOK_time--); + + if(!(CPU_status&CPU_GEN_PUT_CODE_OK)) { + RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n"); + goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; + } else { + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n"); + } + + /* Turn On CPU */ + CPU_status = read_nic_dword(dev, CPU_GEN); + write_nic_byte(dev, CPU_GEN, (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff)); + mdelay(1); + + /* Check whether CPU boot OK */ + do { + CPU_status = read_nic_dword(dev, CPU_GEN); + + if(CPU_status&CPU_GEN_BOOT_RDY) + break; + }while(check_bootOk_time--); + + if(!(CPU_status&CPU_GEN_BOOT_RDY)) { + goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; + } else { + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); + } + + return rt_status; + +CPUCheckMainCodeOKAndTurnOnCPU_Fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__); + rt_status = FALSE; + return rt_status; +} + +bool CPUcheck_firmware_ready(struct net_device *dev) +{ + + bool rt_status = true; + int check_time = 200000; + u32 CPU_status = 0; + + /* Check Firmware Ready */ + do { + CPU_status = read_nic_dword(dev, CPU_GEN); + + if(CPU_status&CPU_GEN_FIRM_RDY) + break; + + }while(check_time--); + + if(!(CPU_status&CPU_GEN_FIRM_RDY)) + goto CPUCheckFirmwareReady_Fail; + else + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n"); + + return rt_status; + +CPUCheckFirmwareReady_Fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__); + rt_status = false; + return rt_status; + +} + +bool init_firmware(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + bool rt_status = TRUE; + +#ifdef RTL8190P + u8 *firmware_img_buf[3] = { &rtl8190_fwboot_array[0], + &rtl8190_fwmain_array[0], + &rtl8190_fwdata_array[0]}; + + u32 firmware_img_len[3] = { sizeof(rtl8190_fwboot_array), + sizeof(rtl8190_fwmain_array), + sizeof(rtl8190_fwdata_array)}; +#else + u8 *firmware_img_buf[3] = { &rtl8192e_fwboot_array[0], + &rtl8192e_fwmain_array[0], + &rtl8192e_fwdata_array[0]}; + + u32 firmware_img_len[3] = { sizeof(rtl8192e_fwboot_array), + sizeof(rtl8192e_fwmain_array), + sizeof(rtl8192e_fwdata_array)}; +#endif + u32 file_length = 0; + u8 *mapped_file = NULL; + u32 init_step = 0; + opt_rst_type_e rst_opt = OPT_SYSTEM_RESET; + firmware_init_step_e starting_state = FW_INIT_STEP0_BOOT; + + rt_firmware *pfirmware = priv->pFirmware; + const struct firmware *fw_entry; +#ifdef RTL8190P + const char *fw_name[3] = { "RTL8190P/boot.img", + "RTL8190P/main.img", + "RTL8190P/data.img"}; +#endif +#ifdef RTL8192E + const char *fw_name[3] = { "RTL8192E/boot.img", + "RTL8192E/main.img", + "RTL8192E/data.img"}; +#endif + int rc; + + RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n"); + + if (pfirmware->firmware_status == FW_STATUS_0_INIT ) { + /* it is called by reset */ + rst_opt = OPT_SYSTEM_RESET; + starting_state = FW_INIT_STEP0_BOOT; + // TODO: system reset + + }else if(pfirmware->firmware_status == FW_STATUS_5_READY) { + /* it is called by Initialize */ + rst_opt = OPT_FIRMWARE_RESET; + starting_state = FW_INIT_STEP2_DATA; + }else { + RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n"); + } + + /* + * Download boot, main, and data image for System reset. + * Download data image for firmware reseta + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + priv->firmware_source = FW_SOURCE_HEADER_FILE; +#else + priv->firmware_source = FW_SOURCE_IMG_FILE; +#endif + for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { + /* + * Open Image file, and map file to contineous memory if open file success. + * or read image file from array. Default load from IMG file + */ + if(rst_opt == OPT_SYSTEM_RESET) { + switch(priv->firmware_source) { + case FW_SOURCE_IMG_FILE: + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + if(pfirmware->firmware_buf_size[init_step] == 0) { + rc = request_firmware(&fw_entry, fw_name[init_step],&priv->pdev->dev); + if(rc < 0 ) { + RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n"); + goto download_firmware_fail; + } + + if(fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) { + RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n"); + goto download_firmware_fail; + } + + if(init_step != FW_INIT_STEP1_MAIN) { + memcpy(pfirmware->firmware_buf[init_step],fw_entry->data,fw_entry->size); + pfirmware->firmware_buf_size[init_step] = fw_entry->size; + + } else { +#ifdef RTL8190P + memcpy(pfirmware->firmware_buf[init_step],fw_entry->data,fw_entry->size); + pfirmware->firmware_buf_size[init_step] = fw_entry->size; + +#else + memset(pfirmware->firmware_buf[init_step],0,128); + memcpy(&pfirmware->firmware_buf[init_step][128],fw_entry->data,fw_entry->size); + //mapped_file = pfirmware->firmware_buf[init_step]; + pfirmware->firmware_buf_size[init_step] = fw_entry->size+128; + //file_length = fw_entry->size + 128; +#endif + } + //pfirmware->firmware_buf_size = file_length; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + if(rst_opt == OPT_SYSTEM_RESET) { + release_firmware(fw_entry); + } +#endif + } + mapped_file = pfirmware->firmware_buf[init_step]; + file_length = pfirmware->firmware_buf_size[init_step]; +#endif + break; + } + case FW_SOURCE_HEADER_FILE: + mapped_file = firmware_img_buf[init_step]; + file_length = firmware_img_len[init_step]; + if(init_step == FW_INIT_STEP2_DATA) { + memcpy(pfirmware->firmware_buf[init_step], mapped_file, file_length); + pfirmware->firmware_buf_size[init_step] = file_length; + } + break; + + default: + break; + } + + + }else if(rst_opt == OPT_FIRMWARE_RESET ) { + /* we only need to download data.img here */ + mapped_file = pfirmware->firmware_buf[init_step]; + file_length = pfirmware->firmware_buf_size[init_step]; + } + + /* Download image file */ + /* The firmware download process is just as following, + * 1. that is each packet will be segmented and inserted to the wait queue. + * 2. each packet segment will be put in the skb_buff packet. + * 3. each skb_buff packet data content will already include the firmware info + * and Tx descriptor info + * */ + rt_status = fw_download_code(dev,mapped_file,file_length); + if(rt_status != TRUE) { + goto download_firmware_fail; + } + + switch(init_step) { + case FW_INIT_STEP0_BOOT: + /* Download boot + * initialize command descriptor. + * will set polling bit when firmware code is also configured + */ + pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE; +#ifdef RTL8190P + // To initialize IMEM, CPU move code from 0x80000080, hence, we send 0x80 byte packet + rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET); + if(rt_status != true) + { + RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n"); + goto download_firmware_fail; + } +#endif + //mdelay(1000); + /* + * To initialize IMEM, CPU move code from 0x80000080, + * hence, we send 0x80 byte packet + */ + break; + + case FW_INIT_STEP1_MAIN: + /* Download firmware code. Wait until Boot Ready and Turn on CPU */ + pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE; + + /* Check Put Code OK and Turn On CPU */ + rt_status = CPUcheck_maincodeok_turnonCPU(dev); + if(rt_status != TRUE) { + RT_TRACE(COMP_FIRMWARE, "CPUcheck_maincodeok_turnonCPU fail!\n"); + goto download_firmware_fail; + } + + pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU; + break; + + case FW_INIT_STEP2_DATA: + /* download initial data code */ + pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE; + mdelay(1); + + rt_status = CPUcheck_firmware_ready(dev); + if(rt_status != TRUE) { + RT_TRACE(COMP_FIRMWARE, "CPUcheck_firmware_ready fail(%d)!\n",rt_status); + goto download_firmware_fail; + } + + /* wait until data code is initialized ready.*/ + pfirmware->firmware_status = FW_STATUS_5_READY; + break; + } + } + + RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n"); + //assert(pfirmware->firmware_status == FW_STATUS_5_READY, ("Firmware Download Fail\n")); + + return rt_status; + +download_firmware_fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__); + rt_status = FALSE; + return rt_status; + +} + +#if 0 +/* + * Procedure: (1) Transform firmware code from little endian to big endian if required. + * (2) Number of bytes in Firmware downloading should be multiple + * of 4 bytes. If length is not multiple of 4 bytes, appending of zeros is required + * + */ +void CmdAppendZeroAndEndianTransform( + u1Byte *pDst, + u1Byte *pSrc, + u2Byte *pLength) +{ + + u2Byte ulAppendBytes = 0, i; + u2Byte ulLength = *pLength; + +//test only + //memset(pDst, 0xcc, 12); + + + /* Transform from little endian to big endian */ +//#if DEV_BUS_TYPE==PCI_INTERFACE +#if 0 + for( i=0 ; i<(*pLength) ; i+=4) + { + if((i+3) < (*pLength)) pDst[i+0] = pSrc[i+3]; + if((i+2) < (*pLength)) pDst[i+1] = pSrc[i+2]; + if((i+1) < (*pLength)) pDst[i+2] = pSrc[i+1]; + if((i+0) < (*pLength)) pDst[i+3] = pSrc[i+0]; + } +#else + pDst += USB_HWDESC_HEADER_LEN; + ulLength -= USB_HWDESC_HEADER_LEN; + + for( i=0 ; i0) + { + ulAppendBytes = 4-((*pLength) % 4); + + for(i=0 ; iFragLength[0] = (u2Byte)pTcb->BufferList[0].Length; + + QueueID=pTcb->SpecifiedQueueID; +#if DEV_BUS_TYPE!=USB_INTERFACE + firstDesc=curDesc=Adapter->NextTxDescToFill[QueueID]; +#endif + +#if DEV_BUS_TYPE!=USB_INTERFACE + if(VacancyTxDescNum(Adapter, QueueID) > pTcb->BufferCount) +#else + if(PlatformIsTxQueueAvailable(Adapter, QueueID, pTcb->BufferCount) && + RTIsListEmpty(&Adapter->TcbWaitQueue[QueueID])) +#endif + { + pTcb->nDescUsed=0; + + for(i=0 ; iBufferCount ; i++) + { + Adapter->HalFunc.TxFillCmdDescHandler( + Adapter, + pTcb, + QueueID, //QueueIndex + curDesc, //index + FragBufferIndex==0, //bFirstSeg + FragBufferIndex==(pTcb->FragBufCount[FragIndex]-1), //bLastSeg + pTcb->BufferList[i].VirtualAddress, //VirtualAddress + pTcb->BufferList[i].PhysicalAddressLow, //PhyAddressLow + pTcb->BufferList[i].Length, //BufferLen + i!=0, //bSetOwnBit + (i==(pTcb->BufferCount-1)) && bLastInitPacket, //bLastInitPacket + PacketType, //DescPacketType + pTcb->FragLength[FragIndex] //PktLen + ); + + if(FragBufferIndex==(pTcb->FragBufCount[FragIndex]-1)) + { // Last segment of the fragment. + pTcb->nFragSent++; + } + + FragBufferIndex++; + if(FragBufferIndex==pTcb->FragBufCount[FragIndex]) + { + FragIndex++; + FragBufferIndex=0; + } + +#if DEV_BUS_TYPE!=USB_INTERFACE + curDesc=(curDesc+1)%Adapter->NumTxDesc[QueueID]; +#endif + pTcb->nDescUsed++; + } + +#if DEV_BUS_TYPE!=USB_INTERFACE + RTInsertTailList(&Adapter->TcbBusyQueue[QueueID], &pTcb->List); + IncrementTxDescToFill(Adapter, QueueID, pTcb->nDescUsed); + Adapter->HalFunc.SetTxDescOWNHandler(Adapter, QueueID, firstDesc); + // TODO: should call poll use QueueID + Adapter->HalFunc.TxPollingHandler(Adapter, TXCMD_QUEUE); +#endif + } + else +#if DEV_BUS_TYPE!=USB_INTERFACE + goto CmdSendPacket_Fail; +#else + { + pTcb->bLastInitPacket = bLastInitPacket; + RTInsertTailList(&Adapter->TcbWaitQueue[pTcb->SpecifiedQueueID], &pTcb->List); + } +#endif + + return rtStatus; + +#if DEV_BUS_TYPE!=USB_INTERFACE +CmdSendPacket_Fail: + rtStatus = RT_STATUS_FAILURE; + return rtStatus; +#endif + +} +#endif + + + + +#if 0 +RT_STATUS +FWSendNullPacket( + IN PADAPTER Adapter, + IN u4Byte Length +) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + + + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN bLastInitPacket = FALSE; + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + +#if DEV_BUS_TYPE==USB_INTERFACE + Length += USB_HWDESC_HEADER_LEN; +#endif + + //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + if(MgntGetBuffer(Adapter, &pTcb, &pBuf)) + { + PlatformZeroMemory(pBuf->Buffer.VirtualAddress, Length); + rtStatus = CmdSendPacket(Adapter, pTcb, pBuf, Length, DESC_PACKET_TYPE_INIT, bLastInitPacket); //0 : always set LastInitPacket to zero +//#if HAL_CODE_BASE != RTL8190HW +// // TODO: for test only +// ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS); +//#endif + if(rtStatus == RT_STATUS_FAILURE) + goto CmdSendNullPacket_Fail; + }else + goto CmdSendNullPacket_Fail; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + return rtStatus; + + +CmdSendNullPacket_Fail: + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + rtStatus = RT_STATUS_FAILURE; + RT_ASSERT(rtStatus == RT_STATUS_SUCCESS, ("CmdSendDownloadCode fail !!\n")); + return rtStatus; +} +#endif + + diff --git a/drivers/staging/rtl8192e/r819xE_firmware.h b/drivers/staging/rtl8192e/r819xE_firmware.h new file mode 100644 index 00000000000..f75e1fd514d --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_firmware.h @@ -0,0 +1,68 @@ +#ifndef __INC_FIRMWARE_H +#define __INC_FIRMWARE_H + +#define RTL8190_CPU_START_OFFSET 0x80 +/* TODO: this definition is TBD */ +//#define USB_HWDESC_HEADER_LEN 0 + +/* It should be double word alignment */ +//#if DEV_BUS_TYPE==PCI_INTERFACE +//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) 4*(v/4) - 8 +//#else +#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 ) +//#endif + +typedef enum _firmware_init_step{ + FW_INIT_STEP0_BOOT = 0, + FW_INIT_STEP1_MAIN = 1, + FW_INIT_STEP2_DATA = 2, +}firmware_init_step_e; + +typedef enum _opt_rst_type{ + OPT_SYSTEM_RESET = 0, + OPT_FIRMWARE_RESET = 1, +}opt_rst_type_e; + +#if 0 +/* CPU related */ +RT_STATUS +CPUCheckMainCodeOKAndTurnOnCPU( + IN PADAPTER Adapter + ); + +RT_STATUS +CPUCheckFirmwareReady( + IN PADAPTER Adapter + ); + +/* Firmware related */ +VOID +FWInitializeParameters( + IN PADAPTER Adapter + ); + +RT_STATUS +FWSendDownloadCode( + IN PADAPTER Adapter, + IN pu1Byte CodeVirtualAddrress, + IN u4Byte BufferLen + ); + +RT_STATUS +FWSendNullPacket( + IN PADAPTER Adapter, + IN u4Byte Length + ); + +RT_STATUS +CmdSendPacket( + PADAPTER Adapter, + PRT_TCB pTcb, + PRT_TX_LOCAL_BUFFER pBuf, + u4Byte BufferLen, + u4Byte PacketType, + BOOLEAN bLastInitPacket + ); +#endif +#endif + diff --git a/drivers/staging/rtl8192e/r819xE_firmware_img.h b/drivers/staging/rtl8192e/r819xE_firmware_img.h new file mode 100644 index 00000000000..6d352053ff0 --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_firmware_img.h @@ -0,0 +1,2778 @@ +#ifndef __INC_R819XE_FIRMWARE_IMG_H +#define __INC_R819XE_FIRMWARE_IMG_H + +/*Created on 2008/ 8/28, 11:46*/ +#include + +u8 rtl8192e_fwboot_array[] = { +0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08, +0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xa8,0x04,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff, +0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b, +0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00, +0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xa8,0x04,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0, +0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00, +0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00, +0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff, +0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01, +0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01, +0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24, +0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10, +0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10, +0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x94, +0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,}; + +u8 rtl8192e_fwmain_array[] = { +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, +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, +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, +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, +0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x98, +0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09, +0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24, +0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0, +0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x70,0x00,0x85,0x18,0x21, +0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00, +0x27,0x82,0x8b,0x7a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00, +0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x70, +0x24,0x02,0x00,0x0a,0x24,0x03,0x09,0xc4,0xa3,0x82,0x8b,0x72,0x24,0x02,0x00,0x04, +0x24,0x04,0x00,0x01,0x24,0x05,0x00,0x02,0xa7,0x83,0x8b,0x86,0xa3,0x82,0x8b,0x78, +0x24,0x03,0x04,0x00,0x24,0x02,0x02,0x00,0xaf,0x83,0x8b,0x8c,0xa3,0x85,0x8b,0x79, +0xa7,0x82,0x8b,0x7a,0xa7,0x84,0x8b,0x7c,0xaf,0x84,0x8b,0x88,0xa3,0x84,0x8b,0x71, +0xa3,0x80,0x8b,0x73,0xa3,0x80,0x8b,0x74,0xa3,0x80,0x8b,0x75,0xa3,0x84,0x8b,0x76, +0xa3,0x85,0x8b,0x77,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x7c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00, +0x27,0x84,0x8b,0x98,0x00,0x00,0x10,0x21,0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00, +0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc0, +0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00, +0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00, +0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03, +0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11, +0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07, +0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10, +0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b, +0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20, +0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x24, +0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54, +0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x94,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18, +0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,0x27,0x85,0x8b,0x90,0x8c,0xa3,0x00,0x00, +0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a, +0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01, +0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3, +0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40, +0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8b,0x98,0x00,0x0a,0x20,0x0b, +0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01, +0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x8b,0x98,0xa0,0x67,0x00,0x01, +0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07, +0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x90,0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x94, +0x27,0x82,0x8b,0x90,0x00,0xc5,0x28,0x21,0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00, +0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xb7,0xac,0xa0,0x00,0x00, +0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xac,0x08,0x00,0x00,0xa7, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xa0,0x08,0x00,0x00,0xa7,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x10, +0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00, +0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03, +0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2, +0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09, +0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x98, +0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04, +0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xb0,0x08,0x00,0x01,0x1f,0x00,0x43,0x10,0x21, +0x83,0x82,0x8b,0xa4,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x1f, +0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01, +0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xe4, +0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08, +0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xc0,0xa3,0x82,0x8b,0xd0,0xa7,0x80,0x8b,0xc4, +0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0xaf,0x80,0x8b,0xcc,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x05,0x24,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac, +0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21, +0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x05,0x5c,0x27,0xbd,0xff,0xe0, +0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0x8f,0x90,0x8b,0xc0,0x0c,0x00,0x02,0x98,0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a, +0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01, +0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xc4,0x97,0x82,0x8b,0xc6,0x3c,0x03,0xb0,0x02, +0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,0xa7,0x82,0x8b,0xc6,0xa4,0x82,0x00,0x00, +0x8f,0x84,0x8b,0xc8,0x8f,0x82,0x8b,0xc0,0x93,0x85,0x8b,0x72,0x24,0x84,0x00,0x01, +0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03, +0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xc0, +0xaf,0x84,0x8b,0xc8,0x10,0xa0,0x00,0x08,0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xcc, +0x8f,0x84,0x8b,0x8c,0x8c,0xc2,0x00,0x00,0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b, +0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00, +0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00, +0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x48,0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20, +0x8f,0x90,0x8b,0xc0,0xac,0x43,0x00,0x00,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21, +0x0c,0x00,0x02,0x98,0x00,0xc0,0x98,0x21,0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19, +0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24, +0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xc4, +0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00, +0x8f,0x84,0x8b,0xc0,0x3c,0x02,0xb0,0x02,0x97,0x85,0x8b,0xc6,0x00,0xc2,0x30,0x21, +0x8f,0x82,0x8b,0xc8,0x24,0x84,0x00,0x10,0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24, +0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xc6,0xaf,0x84,0x8b,0xc0,0xaf,0x82,0x8b,0xc8, +0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, +0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14, +0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc, +0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08, +0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01, +0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14, +0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0x84,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x49,0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00, +0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f,0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21, +0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09,0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x60, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x83,0x60,0x10,0x43,0x00,0x03, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01,0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x60, +0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xf9,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff, +0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x93, +0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40, +0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0, +0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0, +0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40, +0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00, +0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10, +0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21, +0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x80,0x14, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21, +0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,0xa3,0x82,0x83,0x9b,0xa3,0x83,0x83,0x9a, +0x27,0x8a,0x83,0x98,0x00,0x00,0x20,0x21,0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80, +0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01, +0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00, +0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80, +0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c, +0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18, +0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c, +0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00, +0xaf,0x86,0x8b,0xc0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xc0,0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08, +0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12, +0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21, +0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08, +0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xc6, +0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38, +0x93,0x82,0x8b,0xd0,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01, +0x8f,0x82,0x8b,0xc8,0x3c,0x05,0xb0,0x06,0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18, +0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xc4, +0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xcc, +0xa7,0x80,0x8b,0xc6,0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x8b,0xc8, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a, +0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,0x27,0x89,0x83,0x68,0x24,0xe2,0x00,0x01, +0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a, +0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f, +0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x6e,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x83,0x6e,0x90,0xa3,0x00,0x15,0x97,0x82,0x83,0x70,0x00,0x03,0x1e,0x00, +0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,0xa7,0x82,0x83,0x70,0x8c,0xa4,0x00,0x20, +0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54, +0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x74, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x74,0x84,0xa3,0x00,0x06, +0x8f,0x82,0x83,0x84,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x84, +0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,0xaf,0x82,0x8b,0xc8,0x10,0x60,0x00,0x09, +0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05, +0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,0xa3,0x83,0x83,0x6a,0xa3,0x82,0x83,0x6b, +0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x93,0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x7e,0xa3,0x83,0x83,0x8c,0x27,0x89,0x83,0x68, +0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a, +0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xc6, +0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x0c,0x00,0x02,0x36,0x00,0x00,0x00,0x00,0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe5, +0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x76,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x83,0x76,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x88,0x00,0x00,0x00,0x00, +0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x88,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01, +0x97,0x82,0x83,0x72,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x72, +0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xaf,0x82,0x83,0x80,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x6c, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x6c,0x08,0x00,0x02,0xc5, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20, +0x8f,0x8a,0x8b,0xc0,0x3c,0x02,0x00,0x10,0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21, +0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c, +0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42, +0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25, +0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a, +0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34, +0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18, +0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20, +0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff, +0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01, +0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00, +0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4, +0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06, +0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00, +0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24, +0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x8a,0x8b,0xc0,0x10,0xa2,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20, +0x24,0x42,0x0d,0xfc,0x3c,0x03,0xb0,0x00,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20, +0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21, +0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14, +0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08, +0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02, +0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76, +0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00, +0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2, +0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24, +0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04, +0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2, +0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02, +0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26, +0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02, +0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00, +0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00, +0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x92,0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa5, +0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07, +0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,0x27,0x83,0x8b,0x70,0x00,0x43,0x10,0x21, +0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40, +0x27,0x83,0x8b,0x78,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xcc, +0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x70,0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00, +0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21, +0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00, +0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e, +0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xcc, +0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00, +0x08,0x00,0x03,0xcb,0x30,0x67,0xff,0xff,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x03,0xcb,0x30,0x67,0x00,0xff,0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00, +0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x03,0xfd,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x02,0x3c,0x02,0xb0,0x0a, +0x08,0x00,0x04,0x06,0x3c,0x02,0xb0,0x0a,0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08, +0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02, +0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00, +0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24, +0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00, +0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24, +0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02, +0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02, +0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69, +0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15, +0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21, +0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24, +0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,0x08,0x00,0x03,0xa5,0x02,0x51,0x10,0x21, +0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24, +0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa5, +0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00, +0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0x08,0x00,0x03,0xa4,0xa0,0x62,0x00,0x00,0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21, +0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17, +0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x70, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27, +0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4, +0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x78,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21, +0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24, +0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4,0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x70, +0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5a, +0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f, +0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x47, +0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x50,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a, +0x08,0x00,0x04,0x7d,0x00,0x43,0x18,0x21,0x97,0x85,0x8b,0xc4,0x3c,0x07,0xb0,0x02, +0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20, +0x24,0x42,0x12,0x58,0x24,0x03,0xff,0x80,0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07, +0x97,0x82,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8, +0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08, +0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25, +0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xc0, +0xa7,0x82,0x8b,0xc4,0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07, +0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03, +0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14, +0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x04,0xe1,0xac,0x62,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07, +0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a, +0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10, +0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09, +0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24, +0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00, +0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x70,0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21, +0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x70,0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x78, +0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27, +0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00, +0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18, +0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25, +0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00, +0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00, +0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25, +0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xdc, +0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10, +0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,0xa7,0x80,0xbc,0x00,0x00,0x03,0x12,0x02, +0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,0xa3,0x83,0xbc,0x08,0xa7,0x85,0xbc,0x0c, +0xa7,0x82,0xbc,0x0a,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04,0xa7,0x80,0xbc,0x06, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25, +0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff, +0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08, +0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f, +0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x10, +0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,0xaf,0x83,0xbc,0x14,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x14, +0x08,0x00,0x05,0x67,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,0x24,0x42,0x15,0xb8,0x30,0x84,0x00,0xff, +0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24, +0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02, +0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c, +0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x38,0xa7,0x80,0xbc,0x00,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04, +0xa7,0x80,0xbc,0x06,0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00, +0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21, +0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0xbc,0x02, +0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,0x0c,0x00,0x06,0xd1,0x30,0x55,0xff,0xff, +0x00,0x40,0x80,0x21,0x97,0x84,0xbc,0x00,0x97,0x82,0xbc,0x02,0x97,0x83,0xbc,0x06, +0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,0x00,0x82,0x20,0x21,0x97,0x82,0xbc,0x04, +0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21, +0x93,0x82,0xbc,0x08,0x00,0x83,0x20,0x21,0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b, +0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0c,0x00,0x00,0x00,0x00, +0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0a, +0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21, +0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17, +0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25, +0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x58,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xbf, +0x00,0x00,0x00,0x00,0xa7,0x97,0xbc,0x00,0xa7,0x95,0xbc,0x02,0xa7,0x96,0xbc,0x04, +0xa7,0x94,0xbc,0x06,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24, +0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00, +0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24, +0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xc9, +0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f, +0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c, +0x0c,0x00,0x06,0xd1,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00, +0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11, +0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff, +0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf, +0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x08,0x00,0x05,0xd7,0x24,0x04,0x02,0x2c, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21, +0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee, +0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x13,0x3c,0x02,0xff,0xff, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82, +0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f, +0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x28, +0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f, +0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20, +0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcb, +0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0, +0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03, +0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff, +0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x42,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20, +0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80, +0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50, +0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xbf, +0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21, +0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20, +0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24, +0x08,0x00,0x06,0x19,0x34,0x52,0x80,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xd1, +0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25, +0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d, +0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24, +0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf,0x36,0x52,0x80,0x00, +0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x66, +0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0, +0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02, +0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08, +0x08,0x00,0x06,0x96,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08, +0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03, +0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xae,0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03, +0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21, +0x3c,0x06,0x00,0x01,0xac,0x85,0x00,0x00,0x24,0x07,0x00,0x01,0x00,0x00,0x28,0x21, +0x34,0xc6,0x86,0x9f,0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03, +0x00,0xc5,0x18,0x2b,0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x3c,0x02,0xb0,0x0a, +0x00,0x83,0x20,0x23,0x00,0x82,0x20,0x21,0x3c,0x06,0x00,0x01,0x24,0x02,0xff,0xff, +0xac,0x82,0x10,0x00,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x01,0x34,0xc6,0x86,0x9f, +0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03,0x00,0xc5,0x18,0x2b, +0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x94, +0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00, +0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, +0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09, +0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49, +0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00, +0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44, +0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c, +0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c, +0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00, +0x24,0x42,0x1c,0x28,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13, +0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e, +0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05, +0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05, +0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24, +0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00, +0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8, +0x00,0x07,0x60,0x80,0x27,0x82,0xb4,0x00,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c, +0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48, +0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30, +0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00, +0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xbc, +0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00, +0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x90,0x04,0x00,0x03,0x18,0x80, +0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03, +0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18, +0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07, +0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04, +0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71, +0xaf,0xa3,0x00,0x18,0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04, +0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46, +0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01, +0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03, +0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21, +0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x10,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00, +0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01, +0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xea, +0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0, +0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b, +0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b, +0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, +0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5, +0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01, +0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00, +0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00, +0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00, +0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01, +0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02, +0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18, +0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04, +0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b, +0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0, +0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00, +0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21, +0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29, +0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05, +0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28, +0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09, +0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01, +0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21, +0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21, +0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04, +0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21, +0x0c,0x00,0x00,0x70,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c, +0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03, +0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19, +0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05, +0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00, +0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe6,0x24,0x02,0x00,0x20, +0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe6, +0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, +0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80, +0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05, +0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28, +0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10, +0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14, +0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00, +0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe6, +0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb8,0x24,0x13,0x01,0x02, +0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c, +0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, +0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04, +0x08,0x00,0x07,0xa2,0x00,0x46,0x80,0x0a,0x27,0x82,0xb4,0x00,0x01,0x82,0x20,0x21, +0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x20,0x00,0xc2,0x10,0x21, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00, +0x90,0xe3,0x00,0x16,0x27,0x82,0x90,0x08,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20, +0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42, +0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f, +0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18, +0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xc2,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04, +0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f, +0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e, +0x27,0x83,0x90,0x18,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x78, +0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04, +0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25, +0x27,0x85,0xb4,0x00,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21, +0x27,0x83,0x90,0x10,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12, +0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16, +0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e, +0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f, +0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00, +0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xe0,0xa0,0x43,0x00,0x00, +0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x03,0xaf,0xaf,0x00,0x28, +0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xc2,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xbd, +0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00, +0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x79, +0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7f,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10, +0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83, +0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x59, +0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x59,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40, +0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00, +0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x8c, +0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42, +0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60, +0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24, +0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21, +0x08,0x00,0x08,0xfa,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x28,0x00,0x80,0x80,0x21, +0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10, +0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00, +0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00, +0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07, +0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00, +0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f, +0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07, +0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x50,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05, +0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21, +0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e, +0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10, +0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02, +0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21, +0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c, +0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07, +0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x28, +0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb4,0x00, +0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44, +0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28, +0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00, +0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20, +0x24,0x42,0x25,0x84,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12, +0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14, +0x27,0x83,0x90,0x00,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00, +0xaf,0xa4,0x00,0x48,0x27,0x82,0x90,0x04,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00, +0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21, +0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08, +0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42, +0x27,0x82,0x90,0x10,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21, +0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c, +0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47, +0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44, +0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xe9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c, +0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21, +0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21, +0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21, +0x0c,0x00,0x08,0xe3,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80, +0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x20,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00, +0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2, +0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24, +0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28, +0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x90,0x08, +0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04, +0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2f,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c, +0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18, +0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc6,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00, +0x08,0x00,0x09,0xb2,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24, +0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x27,0xa8,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38, +0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58, +0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20, +0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21, +0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb4,0x00,0x00,0x07,0x10,0x80, +0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21, +0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d, +0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03, +0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44, +0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c, +0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04, +0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14, +0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc, +0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48, +0x0c,0x00,0x07,0x0a,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x2c, +0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17, +0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed, +0x02,0x20,0x10,0x21,0x27,0x83,0xb4,0x00,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12, +0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21, +0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2f, +0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x2c,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a, +0x08,0x00,0x0a,0x3f,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08, +0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1e,0xf3,0x02,0x00,0x28,0x21, +0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1e,0xf3, +0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed, +0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14, +0x96,0x44,0x00,0x14,0x27,0x85,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08, +0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02, +0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02, +0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02, +0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a, +0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14, +0x27,0x82,0x90,0x04,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21, +0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42, +0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41, +0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00, +0x27,0x82,0xb5,0x78,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80, +0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05, +0x27,0x84,0xb4,0xa0,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b, +0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00, +0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1, +0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21, +0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21, +0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21, +0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b, +0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x6f, +0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00, +0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21, +0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xc2, +0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xaa,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, +0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xaa, +0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x10,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x0a,0xba,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21, +0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80, +0x00,0x40,0x50,0x21,0x27,0x82,0x90,0x04,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04, +0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01, +0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21, +0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x70, +0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00, +0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x10,0x00,0x85,0x10,0x21, +0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21, +0x27,0x82,0x90,0x18,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x78, +0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23, +0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0xa0, +0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c, +0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21, +0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1,0x14,0x80,0x00,0x06, +0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x10, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03, +0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c, +0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x6f, +0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16, +0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x62,0x00,0x16, +0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x31, +0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x19,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, +0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x19, +0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x0b,0x29,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x10,0x08,0x00,0x0b,0x45, +0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x7a, +0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7f, +0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, +0x24,0x42,0x2d,0x54,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24, +0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18, +0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21, +0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf, +0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12, +0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02, +0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05, +0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92, +0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02, +0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86, +0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01, +0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02, +0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58, +0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21, +0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x08,0x00,0x0b,0x9b,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24, +0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x24, +0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8, +0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03, +0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa2,0x00,0x14, +0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c, +0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x2c, +0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01, +0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14, +0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x57,0x24,0x04,0x00,0x01, +0x08,0x00,0x0b,0x85,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40,0xae,0x40,0x00,0x34, +0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00, +0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x7d,0x00,0x00,0x00,0x00, +0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x61,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x71, +0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a, +0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x48,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a, +0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x3c, +0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12, +0x8f,0x82,0xb4,0x44,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00, +0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x40, +0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b, +0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x31,0x08,0x3c,0x08,0xb0,0x03, +0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18, +0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a, +0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01, +0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21, +0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21, +0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21, +0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21, +0x08,0x00,0x0c,0x64,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28, +0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03, +0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x27,0x82,0x90,0x04,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00, +0x24,0x42,0x31,0xb8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x90,0x08, +0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01, +0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21, +0x0c,0x00,0x0c,0x42,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21, +0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xe3,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c, +0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06, +0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03, +0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80, +0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20, +0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21, +0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02, +0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08, +0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00, +0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00, +0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb6, +0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21, +0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, +0x27,0x82,0x90,0x04,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00, +0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x34,0x27,0x83,0x90,0x08,0xac,0xa2,0x00,0x00, +0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00, +0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10, +0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01, +0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21, +0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xe3,0x30,0x50,0x00,0xff, +0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x10,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0, +0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06, +0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00, +0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00, +0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10, +0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14, +0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09, +0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20, +0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24, +0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09, +0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff, +0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x18,0x8f,0xbf,0x00,0x1c, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09, +0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10, +0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xc0,0x00,0x05,0x2c,0x43, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05, +0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6, +0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21, +0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89, +0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03, +0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00, +0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11, +0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12, +0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14, +0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10, +0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12, +0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01, +0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12, +0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c, +0x27,0x84,0x90,0x10,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00, +0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04, +0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xd4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xcd, +0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x7d,0x00,0x07,0x16,0x00, +0x0c,0x00,0x0c,0x6e,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x90,0x08, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21, +0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13, +0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x95,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a, +0x08,0x00,0x0d,0x5e,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00, +0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a, +0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x04, +0x08,0x00,0x0d,0xaf,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05, +0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08, +0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c, +0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xbe,0xa2,0x20,0x00,0x0a, +0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07, +0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b, +0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xca, +0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09, +0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51, +0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10, +0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51,0xae,0x20,0x00,0x34, +0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51, +0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01, +0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a, +0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x07, +0x08,0x00,0x0d,0xf0,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x40,0xae,0x20,0x00,0x34, +0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x42, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xf4, +0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05, +0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xd4,0x00,0x00,0x00,0x00, +0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42, +0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c, +0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01, +0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, +0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8, +0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x84,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c, +0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb4,0x00, +0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00, +0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15, +0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12, +0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20,0x00,0x43,0x10,0x21, +0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf, +0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20, +0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45, +0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00, +0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17, +0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03, +0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05, +0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02, +0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08, +0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14, +0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x6c,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x58, +0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00, +0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21, +0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21, +0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24, +0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, +0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x58, +0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x8c, +0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05, +0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x52, +0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x52,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x52, +0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69, +0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b, +0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24, +0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x90,0x04,0x00,0xa3,0x18,0x21, +0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24, +0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66,0x02,0x00,0x20,0x21, +0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x49, +0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x90,0x00, +0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c, +0x08,0x00,0x0e,0xc9,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x10,0x27,0x82,0x90,0x18, +0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05, +0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa2,0x00,0x10, +0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xc3,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd, +0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f, +0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xb2,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c, +0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00, +0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09, +0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x90,0x04,0x00,0x02,0x10,0x80, +0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20, +0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x19, +0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20, +0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x49, +0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x49,0xa2,0x22,0x00,0x09, +0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x49, +0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21, +0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x64,0xf1,0x43,0x00,0x06, +0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00, +0x27,0x85,0x90,0x10,0x27,0x82,0x90,0x0f,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21, +0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21, +0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04, +0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x90,0x04,0xa3,0xa7,0x00,0x00, +0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b, +0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08, +0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x18, +0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff, +0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00, +0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d, +0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02, +0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40, +0x27,0x83,0xbb,0x1c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00, +0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02, +0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00, +0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e, +0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f, +0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x1c, +0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05, +0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0xa8,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06, +0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x7a,0xa1,0x82,0x00,0x00, +0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82, +0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21, +0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00, +0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0xa8,0x00,0x44,0x10,0x21, +0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33, +0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80, +0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x78,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24, +0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f, +0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x00,0x00,0x44,0x10,0x21, +0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04, +0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff, +0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40, +0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04, +0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, +0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad, +0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x67,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc8, +0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73, +0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x55,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x35, +0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x40,0x04,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0, +0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, +0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38, +0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x90,0x04, +0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20, +0x24,0x42,0x40,0x1c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x10, +0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00, +0x0c,0x00,0x0f,0x19,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42, +0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21, +0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21, +0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18, +0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06, +0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xe3,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21, +0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21, +0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x08,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04, +0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, +0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c, +0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43, +0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x0a,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x48, +0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, +0x34,0x63,0x00,0x20,0x24,0x42,0x41,0xa4,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00, +0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18, +0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00, +0x00,0x03,0x18,0x80,0x27,0x82,0xb4,0x00,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff, +0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02, +0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21, +0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14, +0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20, +0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x0c,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00, +0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03, +0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x20,0x00,0x03,0x18,0x80, +0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21, +0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x10,0x00,0x08,0x1d,0x02, +0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b, +0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02, +0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11, +0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff, +0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04, +0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00, +0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x10, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00, +0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00, +0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03, +0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00, +0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03, +0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c, +0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16, +0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x9c,0xa2,0x23,0x00,0x16, +0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05, +0x86,0x45,0x00,0x0c,0x0c,0x00,0x1e,0xea,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a, +0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff, +0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04, +0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01, +0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c, +0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x97, +0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x97,0xa6,0x22,0x00,0x14, +0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x11,0x26,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06, +0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0, +0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80, +0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00, +0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04, +0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b, +0x08,0x00,0x11,0x26,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b, +0x08,0x00,0x11,0x49,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02, +0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00, +0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x06, +0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80, +0x08,0x00,0x11,0x18,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x07,0x02,0x40,0x20,0x21, +0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00, +0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10, +0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01, +0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00, +0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80, +0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x90,0x04, +0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80, +0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21, +0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x71, +0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d, +0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66, +0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff, +0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b, +0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04, +0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x66,0x30,0x50,0x00,0x01, +0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17, +0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x30,0x42,0x00,0xc3, +0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xbd,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb8, +0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x90,0x00, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08, +0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24, +0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, +0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb8, +0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xdc, +0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12, +0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x00,0x00,0x20,0x21, +0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x9a,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x10, +0x27,0x82,0x90,0x18,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00, +0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0x9a, +0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x8d,0x00,0x07,0x1c,0x00, +0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x07, +0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x05, +0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x75,0x00,0xa2,0x10,0x07, +0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xd0,0x00,0xa2,0x10,0x07, +0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x19,0x00,0x00,0x00,0x00, +0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21, +0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b, +0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40, +0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00, +0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17, +0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00, +0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16, +0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16, +0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00, +0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00, +0x08,0x00,0x12,0x3f,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00, +0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x38,0xa2,0x20,0x00,0x17, +0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0, +0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80, +0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, +0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08, +0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02, +0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x38,0xa2,0x23,0x00,0x17, +0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x67,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03, +0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x07, +0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x05, +0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24, +0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01, +0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd, +0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x82,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff, +0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x10,0x00,0x03,0x18,0x80, +0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00, +0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41, +0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00, +0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20, +0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06, +0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff, +0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xe0,0x00,0x40,0x30,0x21, +0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02, +0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08, +0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb4,0x00,0x24,0x11,0x00,0x12, +0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00, +0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03, +0x0c,0x00,0x13,0x1c,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00, +0x8f,0x85,0x8f,0xe0,0x08,0x00,0x12,0xbe,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95, +0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03, +0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe5,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa8, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa8, +0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x94,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01, +0x25,0x29,0x03,0x50,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00, +0x25,0x4a,0x4b,0xbc,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06, +0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00, +0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01, +0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xf8, +0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x24,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01, +0x24,0x63,0x03,0x50,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00, +0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a, +0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x1c,0x00,0x00,0x00,0x00, +0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x70,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x50,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x24, +0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c, +0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00, +0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xb0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xe0,0x00,0x00,0x00,0x00, +0x27,0x9d,0x8f,0xc8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xd4,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00, +0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x62, +0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40, +0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff, +0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18, +0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x99,0x02,0x20,0x20,0x21, +0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8, +0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c, +0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21, +0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40, +0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01, +0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x99, +0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04, +0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a, +0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x87, +0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20, +0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21, +0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00, +0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09, +0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05, +0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28, +0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00, +0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01, +0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50, +0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14, +0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24, +0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31, +0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10, +0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c, +0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00, +0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80, +0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03, +0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67, +0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa, +0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23, +0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0, +0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00, +0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef, +0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00, +0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14, +0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04, +0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14, +0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09, +0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09, +0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00, +0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee, +0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28, +0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38, +0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00, +0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00, +0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00, +0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00, +0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x48,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34, +0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x04,0x00,0x80,0x28,0x21, +0x8c,0x86,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0xc2,0x00,0xf7,0x00,0x00,0x00,0x00, +0x8c,0xa2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x4f,0x24,0x02,0x00,0x06, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xdd,0xac,0xa2,0x00,0x2c,0x24,0x02,0x00,0x01, +0x10,0xc2,0x00,0xdc,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0xca, +0x00,0x00,0x00,0x00,0x8c,0xa7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc0, +0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09, +0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xa2,0x00,0x14, +0x24,0x02,0x00,0x01,0xac,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x14, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x61,0x00,0x19,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x12, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0c,0x3c,0x02,0xb0,0x03,0x80,0xa2,0x00,0x50, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08,0x3c,0x02,0xb0,0x03,0x14,0xc0,0x00,0x07, +0x34,0x42,0x00,0x3f,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0xa0,0xa3,0x00,0x50,0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00, +0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x7f,0x3c,0x03,0xb0,0x05,0x80,0xa2,0x00,0x31, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24, +0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x00, +0x8c,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2, +0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x8c,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xa3,0x00,0x10,0x3c,0x02,0xb0,0x03, +0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xa2,0x00,0x0c, +0x90,0xa3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xb2, +0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15, +0xa0,0xa4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02, +0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x8c,0xa2,0x00,0x0c,0xac,0xa3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xa2,0x00,0x10, +0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xa2,0x00,0x00, +0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xa3,0x00,0x10,0x03,0xe0,0x00,0x08, +0xac,0xa2,0x00,0x0c,0x8c,0xa3,0x00,0x38,0x24,0x04,0x00,0x01,0x10,0x64,0x00,0x2d, +0x24,0x02,0x00,0x02,0x10,0x60,0x00,0x19,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x10, +0x24,0x02,0x00,0x04,0x10,0x62,0x00,0x04,0x00,0x00,0x00,0x00,0xac,0xa0,0x00,0x38, +0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x00,0x10,0xe4,0x00,0x07,0x24,0x02,0x00,0x03, +0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x0b,0xac,0xa3,0x00,0x00, +0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x38,0x08,0x00,0x15,0x04,0xac,0xa2,0x00,0x00, +0x10,0xe4,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x0c,0xac,0xa2,0x00,0x00, +0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x38,0x10,0xe4,0x00,0x0e, +0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x06,0xac,0xa2,0x00,0x18,0x24,0x02,0x00,0x02, +0xac,0xa2,0x00,0x00,0xac,0xa0,0x00,0x18,0x08,0x00,0x15,0x0d,0x24,0x02,0x00,0x01, +0x08,0x00,0x15,0x1a,0xac,0xa0,0x00,0x00,0x24,0x02,0x00,0x03,0x08,0x00,0x15,0x1a, +0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x0b,0xac,0xa2,0x00,0x38,0x03,0xe0,0x00,0x08, +0xac,0xa3,0x00,0x00,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x7d,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0x78,0x00,0x00,0x00,0x00, +0x10,0xc0,0xff,0x81,0x24,0x02,0x00,0x0e,0x08,0x00,0x14,0xa7,0x00,0x00,0x00,0x00, +0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3e,0x24,0x02,0x00,0x04, +0x08,0x00,0x14,0xb2,0x00,0x00,0x00,0x00,0x84,0xa2,0x00,0x20,0x00,0x00,0x00,0x00, +0x10,0x40,0xff,0x75,0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x00,0x60,0x10,0x21,0x14,0x40,0xff,0x2b,0xa4,0xa3,0x00,0x20,0x08,0x00,0x14,0xb2, +0x24,0x02,0x00,0x06,0x8c,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x66, +0x24,0x02,0x00,0x05,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x1b,0xac,0xa2,0x00,0x1c, +0x08,0x00,0x14,0xb2,0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x56, +0x24,0x02,0x00,0x06,0x08,0x00,0x14,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a, +0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10, +0x27,0x90,0x86,0x58,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0x0c,0x00,0x29,0xd5,0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xe0,0x48,0x02,0x00,0x00, +0x0c,0x00,0x13,0xf0,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x1f,0x02,0x00,0x20,0x21, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0xa3,0x83,0x8f,0xe4,0x0c,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xfb, +0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x59,0x00,0x00,0x00,0x00, +0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18, +0x0c,0x00,0x06,0xe5,0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x39,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x4c, +0xaf,0x82,0x84,0x80,0x0c,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00, +0x34,0x84,0x01,0x68,0x34,0xa5,0x01,0x40,0x24,0x02,0xc8,0x80,0x24,0x03,0x00,0x0a, +0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00, +0x8f,0x85,0x84,0x40,0xaf,0x86,0x84,0x38,0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58,0x8c,0x43,0x00,0x00,0x2c,0xa4,0x00,0x11, +0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00,0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x00,0x05,0x10,0x80,0x24,0x63,0x02,0x00,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x98,0x0c,0x00,0x26,0x8e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40, +0x0c,0x00,0x14,0x52,0x00,0x00,0x00,0x00,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x40,0x8f,0x82,0x84,0x74, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9d, +0x3c,0x02,0xb0,0x03,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x0d,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x28,0xdd, +0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x71,0x8f,0x82,0x84,0x74,0xaf,0x80,0x84,0x40, +0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21, +0x27,0x84,0x86,0x58,0x0c,0x00,0x19,0x5b,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x44, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0x00,0x20, +0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x20, +0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x54,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x01, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x03, +0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x44,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb6, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, +0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c,0x14,0x40,0xff,0xf5,0x24,0x02,0x00,0x01, +0x08,0x00,0x15,0xe1,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x58,0x0c,0x00,0x1a,0xd1, +0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x70,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xec, +0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0xff,0xe4, +0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x48,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x12, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x04, +0x08,0x00,0x15,0xed,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf4,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xfc,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c, +0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c, +0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x1d,0x24,0x02,0x00,0x02, +0x27,0x84,0x89,0x18,0x0c,0x00,0x0b,0x55,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44, +0xaf,0x82,0x84,0x5c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,0xaf,0x83,0x84,0x44, +0x14,0x40,0xff,0xad,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x58,0xaf,0x80,0x84,0x40, +0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x48,0x93,0x82,0x89,0x66, +0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x6c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05, +0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00,0x00,0x64,0x18,0x24, +0x10,0x60,0xff,0x65,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa0, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x40,0x24,0x63,0x00,0x01, +0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08,0xaf,0x80,0x89,0x3c, +0xaf,0x80,0x89,0x44,0xaf,0x80,0x89,0x48,0xaf,0x80,0x89,0x54,0xaf,0x80,0x89,0x4c, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x5c,0x8f,0x85,0x84,0x5c, +0x27,0x84,0x89,0x18,0x0c,0x00,0x0d,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00, +0xa3,0x82,0x84,0x70,0xaf,0x80,0x84,0x5c,0x10,0x60,0xff,0x8e,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60, +0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xfd, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x06,0x27,0x84,0x84,0x40, +0x27,0x85,0x89,0x18,0x0c,0x00,0x0d,0xfd,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x64, +0xaf,0x80,0x84,0x6c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21,0x8f,0x82,0x84,0x68, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02,0x8f,0x83,0x84,0x48, +0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00,0x8f,0x83,0x84,0x44, +0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x06, +0xaf,0x85,0x84,0x40,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xb6, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,0xac,0x22,0x00,0x00, +0xaf,0x80,0x84,0x40,0x08,0x00,0x16,0x96,0x24,0x04,0x00,0x03,0x10,0x60,0x00,0x10, +0x00,0x00,0x00,0x00,0x27,0x85,0x89,0x18,0x27,0x84,0x84,0x40,0x0c,0x00,0x0e,0x21, +0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44,0x24,0x02,0x00,0x01,0xa3,0x80,0x84,0x70, +0xaf,0x80,0x84,0x48,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x04, +0xaf,0x85,0x84,0x40,0xaf,0x80,0x84,0x64,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44, +0xa3,0x80,0x84,0x70,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x68, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40,0x27,0x85,0x89,0x18, +0x0c,0x00,0x0e,0x21,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44,0xa3,0x80,0x84,0x70, +0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0xfe,0xeb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xc6, +0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x29,0x73,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xc5,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x05,0x00,0x00,0x00,0x00, +0x0c,0x00,0x26,0xff,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x11,0x00,0x00,0x00,0x00, +0x93,0x83,0xbc,0x18,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10,0x8f,0x82,0xbc,0x14, +0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03, +0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0x84,0x02, +0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xd1, +0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01, +0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01, +0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25, +0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x6e, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x10,0x0c,0x00,0x01,0xe9,0x00,0x00,0x00,0x00, +0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21, +0x27,0x90,0xb4,0x00,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, +0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00, +0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6, +0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x28,0x21, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x38, +0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05, +0xaf,0x84,0x84,0x38,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21, +0x36,0x52,0x02,0x2c,0x27,0x90,0xb4,0x00,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, +0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06, +0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x38, +0x0c,0x00,0x1e,0x94,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01, +0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x21, +0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x4c,0x27,0x85,0x89,0x18,0x0c,0x00,0x17,0xa4, +0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x4c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa5, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x05,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00,0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18,0x0c,0x00,0x24,0x2c,0x00,0x00,0x00,0x00, +0x24,0x05,0x00,0x05,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x14,0x8c,0x44,0x00,0x00,0x0c,0x00,0x24,0x49, +0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x65,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x4c, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40, +0xaf,0x80,0x89,0x4c,0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00, +0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x40, +0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x21,0x00,0x00,0x00,0x00, +0x3c,0x02,0xff,0x90,0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01, +0x27,0x84,0x89,0x18,0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe5, +0x00,0x00,0x00,0x00,0x27,0x84,0x86,0x58,0x0c,0x00,0x18,0x1f,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x8b, +0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x58,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05, +0x00,0x00,0x18,0x21,0x8f,0x82,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02, +0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x34,0xc6,0x00,0x5f,0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x5d,0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01, +0xa0,0xc3,0x00,0x00,0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21, +0x35,0x29,0x00,0x5e,0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00, +0x91,0x03,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01, +0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c, +0x24,0x05,0x0f,0x00,0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xc5,0x3c,0x02,0xb0,0x03, +0x24,0x04,0x08,0x8c,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80, +0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30, +0x24,0x06,0x00,0x03,0x0c,0x00,0x13,0x5f,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xc5, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0xa3,0x80,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0xa3,0x82,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x60,0x7c, +0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xb8, +0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21, +0xa7,0x82,0x8f,0xf0,0x27,0x88,0x90,0x00,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08, +0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21, +0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21, +0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4, +0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c, +0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xdc, +0xac,0x43,0x00,0x00,0xaf,0x84,0xb4,0x00,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x00,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03, +0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb4,0x04, +0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0x54, +0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x88,0x00,0x18, +0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01, +0xa0,0x45,0x00,0x21,0xaf,0x87,0xb4,0x0c,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00, +0x8f,0x82,0xb4,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21, +0xaf,0x88,0xb4,0x10,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x10, +0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x14, +0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x14,0x25,0xc4,0x00,0xe4, +0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x18,0xa0,0x80,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x18,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c, +0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x1c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00, +0x8f,0x82,0xb4,0x1c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21, +0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04, +0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03, +0xaf,0x87,0xb4,0x20,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x24, +0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x28,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x2c, +0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x30,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x34, +0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x38,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x3c, +0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x40,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00, +0x8f,0x82,0xb4,0x40,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21, +0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x44,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18, +0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x44,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03, +0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x48,0x34,0x63,0x00,0x6c, +0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x48,0x24,0x05,0xff,0xff, +0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb4,0x00, +0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00, +0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14, +0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20, +0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x63,0x40, +0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x80,0x60,0x21,0x10,0x40,0x00,0x56, +0x00,0x00,0x70,0x21,0x97,0x82,0x8f,0xf0,0x94,0x8a,0x00,0x0c,0x27,0x87,0x90,0x00, +0x00,0x02,0x40,0xc0,0x01,0x02,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21, +0x90,0x8b,0x00,0x18,0xa4,0x4a,0x00,0x00,0x94,0x83,0x00,0x0e,0x39,0x64,0x00,0x10, +0x2c,0x84,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x34,0x85,0x00,0x02, +0x39,0x63,0x00,0x11,0x00,0x83,0x28,0x0b,0x34,0xa3,0x00,0x08,0x39,0x64,0x00,0x12, +0x00,0x02,0x10,0x80,0x00,0xa4,0x18,0x0b,0x00,0x47,0x10,0x21,0x94,0x49,0x00,0x04, +0x34,0x64,0x00,0x20,0x00,0x6b,0x20,0x0b,0x34,0x83,0x00,0x40,0x39,0x62,0x00,0x01, +0x00,0x82,0x18,0x0b,0x00,0x09,0x30,0xc0,0x34,0x64,0x00,0x80,0x00,0xc9,0x28,0x21, +0x39,0x62,0x00,0x02,0x00,0x60,0x68,0x21,0x00,0x82,0x68,0x0a,0x00,0x05,0x28,0x80, +0x3c,0x02,0xb0,0x08,0x00,0xa7,0x28,0x21,0x00,0xc2,0x30,0x21,0x01,0x02,0x40,0x21, +0x34,0x03,0xff,0xff,0x35,0xa4,0x01,0x00,0x39,0x62,0x00,0x03,0x2d,0x67,0x00,0x13, +0xad,0x0a,0x00,0x00,0xa4,0xa3,0x00,0x00,0xac,0xc3,0x00,0x00,0xa7,0x89,0x8f,0xf0, +0x10,0xe0,0x00,0x0f,0x00,0x82,0x68,0x0a,0x3c,0x03,0x80,0x01,0x00,0x0b,0x10,0x80, +0x24,0x63,0x02,0x44,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x60, +0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,0x00,0x02,0x74,0x03, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x44,0x00,0x00,0x93,0x83,0x8f,0xe4, +0x91,0x82,0x00,0x21,0x01,0xc4,0x20,0x21,0x91,0x85,0x00,0x10,0x00,0x04,0x24,0x00, +0x00,0x62,0x18,0x21,0x00,0x04,0x74,0x03,0x00,0x6e,0x18,0x23,0x00,0x65,0x10,0x2a, +0x00,0xa2,0x18,0x0a,0x00,0x0d,0x24,0x00,0x3c,0x02,0xb0,0x06,0x24,0x05,0xff,0xff, +0x00,0x64,0x18,0x25,0x34,0x42,0x80,0x20,0xac,0x43,0x00,0x00,0xa5,0x85,0x00,0x0e, +0xa1,0x80,0x00,0x10,0xa5,0x85,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x62,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x64,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14, +0x34,0x63,0x00,0x66,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x38, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6e,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x65,0x08,0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00, +0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21, +0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10, +0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x4f, +0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x4f,0x24,0xa3,0x00,0x50,0x27,0xbd,0xff,0xc8, +0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x30, +0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20, +0xaf,0xb0,0x00,0x10,0x00,0x80,0x88,0x21,0x84,0x84,0x00,0x08,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x65,0x6c,0x3c,0x03,0xb0,0x06, +0x00,0x04,0x20,0x80,0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x06,0xb0,0x06, +0x8c,0x82,0x00,0x00,0x34,0xc6,0x80,0x24,0x8c,0x88,0x00,0x00,0x8c,0xc4,0x00,0x00, +0x96,0x25,0x00,0x08,0x30,0x52,0xff,0xff,0x00,0x08,0x44,0x02,0x34,0x84,0x01,0x00, +0x3c,0x02,0xb0,0x00,0x00,0x08,0x18,0xc0,0x00,0x12,0x3a,0x00,0xac,0xc4,0x00,0x00, +0x00,0xe2,0x38,0x21,0xae,0x32,0x02,0xb8,0x00,0x68,0x18,0x21,0x24,0xa5,0x00,0x02, +0x8c,0xf6,0x00,0x00,0x30,0xa5,0x01,0xff,0x8c,0xf4,0x00,0x04,0x27,0x86,0x90,0x00, +0x00,0x03,0x18,0x80,0x00,0x12,0x98,0xc0,0xa6,0x25,0x00,0x08,0x00,0x66,0x18,0x21, +0x02,0x72,0x10,0x21,0x94,0x65,0x00,0x00,0x00,0x02,0x48,0x80,0x01,0x26,0x30,0x21, +0x24,0x02,0xff,0xff,0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x10,0xa4,0xc2,0x00,0x02, +0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,0x01,0x24,0x20,0x21,0xa4,0xc8,0x00,0x04, +0x8c,0xf0,0x00,0x08,0xa6,0x23,0x00,0x06,0xa6,0x25,0x00,0x0a,0xa0,0x82,0x00,0x06, +0x86,0x25,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x24,0x03,0x00,0x13, +0x10,0xa3,0x00,0xee,0xac,0x47,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, +0xa6,0x20,0x00,0x02,0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08, +0x8c,0x45,0x00,0x00,0x00,0x10,0x1b,0xc2,0x00,0x04,0x20,0x82,0x30,0x63,0x00,0x01, +0xac,0xc5,0x00,0x08,0x10,0x60,0x00,0xc7,0x30,0x97,0x00,0x01,0x00,0x10,0x16,0x82, +0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,0x00,0x10,0x26,0x02, +0x00,0x10,0x2e,0x42,0x30,0x48,0x00,0x7f,0x24,0x02,0x00,0x01,0x30,0x75,0x00,0x01, +0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xb3,0x30,0xa3,0x00,0x01,0x00,0x60,0x28,0x21, +0x0c,0x00,0x19,0x42,0x01,0x00,0x38,0x21,0x02,0x72,0x18,0x21,0x00,0x03,0x18,0x80, +0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x10,0x27,0x84,0x90,0x08,0x00,0x06,0x10,0x0a, +0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02, +0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x72,0x28,0x21, +0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x04,0x00,0xa2,0x58,0x21,0x8d,0x64,0x00,0x18, +0x00,0x10,0x15,0xc2,0x30,0x42,0x00,0x01,0x8c,0x83,0x00,0x0c,0x27,0x84,0x90,0x20, +0x00,0xa4,0x48,0x21,0xa6,0x22,0x00,0x00,0xa6,0x36,0x00,0x04,0x8d,0x26,0x00,0x00, +0x00,0x03,0x19,0x42,0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01, +0x00,0xc2,0x40,0x24,0x00,0x03,0x1d,0x00,0x01,0x03,0x40,0x25,0x00,0x08,0x15,0x02, +0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x42,0x00,0x10,0x3c,0x82, +0x00,0x10,0x2c,0x02,0x30,0x42,0x00,0x01,0x30,0xcd,0x00,0x01,0x30,0x6c,0x00,0x01, +0x30,0xe6,0x00,0x01,0x30,0x8a,0x00,0x03,0x32,0x94,0x00,0x07,0x30,0xa5,0x00,0x01, +0xad,0x28,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,0x8d,0x64,0x00,0x18, +0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,0x01,0x03,0x18,0x24, +0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,0x00,0x62,0x18,0x25, +0xad,0x23,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x6a,0x00,0x00,0x00,0x00, +0x15,0x80,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x5b,0x24,0x02,0x00,0x01, +0x96,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,0xa6,0x22,0x00,0x04, +0x00,0xa0,0x20,0x21,0x0c,0x00,0x19,0x42,0x01,0xa0,0x28,0x21,0x02,0x72,0x18,0x21, +0x00,0x03,0x40,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x10,0x01,0x04,0x20,0x21, +0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, +0x96,0x23,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0xa4,0x43,0x00,0x06, +0x27,0x82,0x90,0x04,0x92,0x26,0x00,0x01,0x01,0x02,0x10,0x21,0x8c,0x45,0x00,0x18, +0x27,0x83,0x90,0x20,0x01,0x03,0x18,0x21,0xa0,0x60,0x00,0x00,0xa0,0x86,0x00,0x07, +0x94,0xa2,0x00,0x10,0x24,0x03,0x00,0x04,0x30,0x42,0x00,0x0f,0x10,0x43,0x00,0x36, +0x24,0xa5,0x00,0x10,0x94,0xa3,0x00,0x16,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21, +0xa4,0x43,0x00,0x02,0x94,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x24,0x02,0x72,0x20,0x21,0x94,0xa2,0x00,0x00,0x24,0x03,0x00,0xa4, +0x30,0x42,0x00,0xff,0x10,0x43,0x00,0x1f,0x00,0x00,0x00,0x00,0x94,0xa2,0x00,0x00, +0x24,0x03,0x00,0x88,0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x14,0x02,0x72,0x18,0x21, +0x27,0x84,0x90,0x20,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00, +0x3c,0x04,0x00,0x80,0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x72,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa0,0x54,0x00,0x00,0x8f,0xbf,0x00,0x30, +0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x94,0xa2,0x00,0x18, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xe9,0x02,0x72,0x18,0x21, +0x02,0x72,0x20,0x21,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21, +0x8c,0x83,0x00,0x00,0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24, +0x08,0x00,0x1a,0x37,0xac,0x83,0x00,0x00,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21, +0x08,0x00,0x1a,0x21,0xa4,0x40,0x00,0x02,0x11,0x42,0x00,0x07,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x02,0x14,0x40,0xff,0xa7,0x00,0xa0,0x20,0x21,0x96,0x22,0x00,0x04, +0x08,0x00,0x19,0xff,0x24,0x42,0x00,0x0c,0x96,0x22,0x00,0x04,0x08,0x00,0x19,0xff, +0x24,0x42,0x00,0x08,0x16,0xe6,0xff,0x96,0x3c,0x02,0xff,0xfb,0x8d,0x63,0x00,0x18, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xf8, +0x00,0x00,0x30,0x21,0x16,0xe6,0xff,0x4e,0x00,0x60,0x28,0x21,0x3c,0x02,0xfb,0xff, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0xe2,0x00,0x08,0x08,0x00,0x19,0xb7, +0x00,0x00,0x30,0x21,0x93,0x87,0xbb,0x14,0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82, +0x27,0x82,0x90,0x08,0x2c,0xe5,0x00,0x0c,0x01,0x22,0x48,0x21,0x30,0x63,0x00,0x01, +0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,0x00,0xe0,0x40,0x21,0x00,0x03,0x10,0x40, +0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0xe2,0x10,0x21,0x24,0x48,0x00,0x04, +0x02,0x72,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x10,0x27,0x83,0x90,0x08, +0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,0xa1,0x28,0x00,0x07,0xa0,0x40,0x00,0x06, +0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0xc7,0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01, +0xa6,0x22,0x00,0x02,0x0c,0x00,0x01,0xc2,0x00,0xe0,0x20,0x21,0x08,0x00,0x1a,0x3b, +0x00,0x00,0x00,0x00,0x30,0xa7,0xff,0xff,0x00,0x07,0x18,0xc0,0x00,0x67,0x18,0x21, +0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x44,0x27,0x85,0x90,0x10, +0x00,0x03,0x18,0x80,0x34,0xc6,0x00,0x20,0x00,0x65,0x18,0x21,0xac,0xc2,0x00,0x00, +0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x29,0x00,0x80,0x28,0x21, +0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01, +0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x90,0xa2,0x00,0x04, +0x3c,0x03,0xb0,0x03,0x27,0x86,0x90,0x00,0x14,0x40,0x00,0x06,0x34,0x63,0x00,0x20, +0x24,0x02,0x00,0x01,0xa0,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,0x03,0xe0,0x00,0x08, +0xa4,0xa7,0x00,0x00,0x94,0xa4,0x00,0x02,0x3c,0x02,0x80,0x01,0x24,0x42,0x82,0x6c, +0xac,0x62,0x00,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x66,0x18,0x21,0x94,0x62,0x00,0x04,0xa4,0x67,0x00,0x02,0x3c,0x03,0xb0,0x08, +0x00,0x02,0x20,0xc0,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21, +0x00,0x83,0x20,0x21,0xa4,0x47,0x00,0x00,0xac,0x87,0x00,0x00,0x90,0xa2,0x00,0x04, +0xa4,0xa7,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x04, +0x90,0x82,0x00,0x16,0x24,0x85,0x00,0x06,0x34,0x42,0x00,0x01,0x30,0x43,0x00,0x02, +0x14,0x60,0xff,0xda,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,0x08,0x00,0x1a,0xa7, +0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0x80,0x38,0x21, +0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x3c,0x0a,0xb0,0x06, +0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x44,0x3c,0x0b,0xb0,0x08,0x27,0x89,0x90,0x00, +0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,0xac,0x62,0x00,0x00, +0x97,0x82,0x8f,0xf0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,0x00,0x6b,0x28,0x21, +0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21, +0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,0x00,0x08,0x28,0xc0, +0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x27,0x82,0x90,0x04, +0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x10,0x00,0x64,0x18,0x21, +0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,0x30,0x42,0xff,0xff, +0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02, +0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,0x00,0x44,0x10,0x25, +0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xf0,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x84,0xe3,0x00,0x06, +0x27,0x82,0xb4,0x00,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21, +0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x91,0x00,0x00,0x00,0x00,0x08,0x00,0x1b,0x0b, +0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,0x27,0x8a,0x90,0x00, +0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,0x00,0x03,0x18,0x80, +0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x6c,0x64, +0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,0x11,0x05,0x00,0x35, +0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x86,0x10,0x2a, +0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,0x01,0x40,0x60,0x21, +0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,0x00,0x07,0x10,0xc0, +0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,0x00,0x4a,0x10,0x21, +0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,0x14,0x60,0xff,0xf5, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x00,0x08,0x20,0xc0, +0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,0xa1,0x62,0x00,0x04, +0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,0x94,0x46,0x00,0x02, +0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,0xa4,0x66,0x00,0x00, +0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,0x3c,0x02,0x80,0x01, +0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0x6c,0xad,0xa2,0x00,0x00,0x10,0x87,0x00,0x03, +0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x08,0x00,0x1b,0x59, +0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,0x24,0x42,0xff,0xff, +0x30,0x43,0x00,0xff,0x14,0x60,0xff,0xf7,0xa1,0x62,0x00,0x04,0x24,0x02,0xff,0xff, +0x08,0x00,0x1b,0x59,0xa5,0x62,0x00,0x02,0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21, +0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80,0x27,0x82,0x90,0x04,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10, +0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00, +0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,0x24,0x42,0x6d,0x98,0xac,0xa2,0x00,0x00, +0x27,0x83,0x90,0x10,0x00,0xc3,0x30,0x21,0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06, +0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff, +0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02,0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff, +0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21, +0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06, +0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21,0x0c,0x00,0x1b,0x19,0x02,0x00,0x28,0x21, +0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08, +0x3c,0x09,0x80,0x01,0x27,0x88,0x90,0x00,0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0, +0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04, +0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21,0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0x6c, +0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02, +0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a, +0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21,0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10, +0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16, +0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16, +0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e,0x27,0x88,0x90,0x00,0x00,0x02,0x20,0xc0, +0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04, +0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20, +0x25,0x23,0x82,0x6c,0xac,0xc3,0x00,0x00,0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00, +0x08,0x00,0x1b,0x97,0xa4,0x90,0x00,0x02,0x08,0x00,0x1b,0x8e,0x32,0x50,0xff,0xff, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6f,0x60,0x34,0x63,0x00,0x20, +0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04,0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21, +0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23,0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff, +0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73,0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0, +0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x03,0x0e,0x20,0x21,0x27,0x8d,0x90,0x00, +0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21, +0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04,0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02, +0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21,0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08, +0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0x6c, +0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20,0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57, +0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21,0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21, +0x01,0x40,0x38,0x21,0x27,0x8b,0x90,0x04,0x27,0x8a,0x90,0x10,0x00,0x06,0x40,0xc0, +0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18, +0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02, +0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff, +0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21, +0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02,0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0, +0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03, +0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21, +0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0, +0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21, +0x27,0x26,0x82,0x6c,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00, +0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10, +0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e,0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05, +0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd, +0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e, +0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, +0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0x6c, +0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21, +0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00,0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00, +0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x26,0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x01, +0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0,0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x8d,0x90,0x00,0x00,0x4d,0x10,0x21,0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff, +0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00,0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01, +0x08,0x00,0x1c,0x01,0xa5,0x82,0x00,0x02,0x08,0x00,0x1c,0x01,0x3c,0x19,0x80,0x01, +0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20, +0x24,0x42,0x71,0xa0,0xaf,0xb2,0x00,0x68,0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60, +0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84,0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c, +0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74,0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c, +0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a,0x27,0x82,0xb4,0x00,0xaf,0xa6,0x00,0x90, +0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94, +0x27,0x86,0x90,0x04,0xaf,0xa3,0x00,0x1c,0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff, +0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0,0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21, +0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80,0x27,0x84,0x90,0x10,0x00,0x64,0x20,0x21, +0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21, +0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c,0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01, +0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40, +0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50,0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12, +0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28,0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4, +0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82,0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11, +0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98,0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40, +0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06,0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00, +0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00, +0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc, +0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18,0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff, +0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48,0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21, +0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48,0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02, +0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21,0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21, +0x00,0x03,0x80,0x80,0x27,0x85,0x90,0x00,0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21, +0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21, +0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08,0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e, +0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01,0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03, +0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21, +0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80, +0x27,0x82,0x90,0x10,0x27,0x85,0x90,0x08,0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21, +0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff, +0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80, +0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46, +0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02, +0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02, +0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21, +0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21, +0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff, +0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21,0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00, +0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e, +0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a, +0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,0x27,0x84,0x90,0x04,0x94,0xb2,0x00,0x14, +0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21, +0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x10,0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06, +0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2, +0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e, +0x00,0xa3,0x38,0x21,0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06, +0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c, +0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38, +0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14, +0x08,0x00,0x1d,0x2d,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x58, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f, +0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87, +0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83, +0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d, +0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50, +0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21, +0x27,0x8c,0x90,0x00,0x3c,0x0b,0x80,0xff,0x24,0x10,0x00,0x04,0x27,0x91,0x90,0x04, +0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,0x27,0x8e,0x90,0x10,0x01,0x80,0x78,0x21, +0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21, +0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44, +0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03, +0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff, +0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b, +0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff, +0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21, +0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40,0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04, +0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25, +0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01, +0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c, +0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00, +0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21, +0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88, +0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21, +0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x18,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00, +0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21, +0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a, +0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff, +0x08,0x00,0x1d,0x85,0xaf,0xa3,0x00,0x2c,0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xa7, +0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x60,0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44, +0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xa7,0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48, +0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xd8, +0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x10,0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80, +0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x49, +0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x09,0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80, +0x27,0x83,0x90,0x10,0x8f,0xa4,0x00,0x1c,0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01, +0x02,0x40,0x28,0x21,0x0c,0x00,0x1e,0xea,0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13, +0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48, +0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24, +0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30, +0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44, +0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04, +0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00, +0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff, +0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80, +0x27,0x82,0x90,0x04,0x00,0xa2,0x10,0x21,0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff, +0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff, +0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04, +0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x10,0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00, +0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb, +0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00, +0x08,0x00,0x1d,0x0c,0x26,0xb5,0xff,0xff,0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21, +0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,0x08,0x00,0x1e,0x1a,0xaf,0xa2,0x00,0x2c, +0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x04,0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48, +0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x0c,0x00,0x1b,0xd8,0xaf,0xb7,0x00,0x10, +0x08,0x00,0x1d,0xfb,0x00,0x00,0xb8,0x21,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21, +0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00, +0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x00,0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21, +0x00,0x03,0x80,0x80,0x27,0x82,0x90,0x04,0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10, +0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2,0x3c,0x04,0x00,0x80,0x27,0x85,0x90,0x00, +0x08,0x00,0x1d,0xeb,0x02,0x05,0x28,0x21,0x27,0x83,0x90,0x18,0x27,0x82,0x90,0x10, +0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05, +0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa3,0x00,0x10, +0x08,0x00,0x1e,0x62,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x18,0x02,0x02,0x10,0x21, +0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58,0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23, +0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40, +0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xd9, +0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94, +0x08,0x00,0x1e,0x83,0x00,0x64,0x10,0x06,0x08,0x00,0x1c,0xd9,0x00,0x00,0x20,0x21, +0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,0x08,0x00,0x1c,0xa9,0xaf,0xa2,0x00,0x40, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20, +0x24,0x63,0x7a,0x50,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45, +0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c, +0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16, +0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16, +0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00, +0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01, +0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,0x08,0x00,0x1e,0xbe,0xa6,0x03,0x00,0x14, +0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x10,0xc0, +0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80, +0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, +0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x7c,0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff, +0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xbe, +0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,0x08,0x00,0x1e,0xbe,0xa6,0x02,0x00,0x14, +0x96,0x05,0x00,0x00,0x0c,0x00,0x1e,0xea,0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xa5, +0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,0x0c,0x00,0x1e,0xea,0x00,0x00,0x00,0x00, +0x08,0x00,0x1e,0xa1,0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xa8,0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00, +0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xcc,0xac,0x62,0x00,0x00, +0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21, +0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00, +0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00, +0x94,0xc8,0x00,0x00,0x27,0x83,0x90,0x00,0x93,0x85,0x8b,0x70,0x00,0x08,0x10,0xc0, +0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08, +0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x88, +0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08, +0x08,0x00,0x1f,0x16,0xa4,0xc2,0x00,0x14,0x08,0x00,0x1f,0x16,0x00,0x00,0x18,0x21, +0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24, +0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c, +0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03, +0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,0x24,0x42,0x7c,0x80,0x02,0xb1,0x48,0x21, +0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x10, +0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,0x27,0x84,0x90,0x04,0x01,0x24,0x20,0x21, +0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,0x27,0x83,0x90,0x20,0x01,0x23,0x48,0x21, +0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04, +0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2, +0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40, +0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21, +0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21, +0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21, +0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,0x27,0x90,0x90,0x00,0x02,0x30,0x80,0x21, +0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21, +0xa6,0x83,0x00,0x1a,0x27,0x82,0x90,0x08,0x0c,0x00,0x08,0xe3,0x02,0x22,0x88,0x21, +0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30, +0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x54,0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0, +0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c, +0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28, +0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03, +0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21, +0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80,0x24,0x42,0x7d,0xbc,0x00,0x80,0x98,0x21, +0x27,0x84,0x90,0x10,0x01,0x24,0x20,0x21,0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00, +0x80,0x83,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18, +0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21, +0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10, +0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21, +0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21, +0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21, +0x27,0x83,0x90,0x18,0x01,0x23,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x70, +0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00, +0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80, +0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x20,0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21, +0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01, +0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,0x02,0xa0,0x20,0x21,0x27,0x82,0x90,0x00, +0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a, +0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40, +0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10, +0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0xbb,0x00,0x00,0x00,0x00, +0x27,0x83,0x90,0x20,0x01,0x23,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf, +0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d, +0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21, +0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40,0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00, +0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02, +0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20, +0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff, +0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f, +0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20, +0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10, +0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08, +0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef, +0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1, +0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3, +0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a, +0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d, +0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,0x27,0x99,0x90,0x00,0x01,0xf2,0xc0,0x23, +0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04, +0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21, +0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23, +0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff, +0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23, +0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40, +0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00, +0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x90,0x04, +0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40, +0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x10, +0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04, +0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x20, +0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2, +0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a, +0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01, +0x27,0x84,0x90,0x00,0x00,0xc4,0x18,0x21,0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02, +0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23, +0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0, +0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,0x02,0x03,0x80,0x21,0x27,0x82,0x90,0x08, +0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21, +0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xe3,0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21, +0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xc1,0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b, +0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6, +0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x37,0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x66, +0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x66,0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c, +0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xb4,0x00,0x14, +0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xd9,0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff, +0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,0x00,0x04,0x20,0x80,0x27,0x82,0x90,0x00, +0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21, +0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff, +0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,0x27,0x88,0x90,0x00,0x00,0x06,0x30,0x80, +0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03, +0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21, +0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20, +0x24,0x42,0x82,0x6c,0xac,0xe2,0x00,0x00,0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00, +0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0, +0x00,0x44,0x10,0x21,0x27,0x89,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21, +0x97,0x83,0x8f,0xf0,0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0, +0x00,0x0a,0x40,0xc0,0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21, +0x01,0x02,0x40,0x21,0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20, +0x34,0x09,0xff,0xff,0x24,0x42,0x82,0xc8,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00, +0xac,0xe4,0x00,0x00,0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xf0, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x63,0x00,0x20,0x24,0x42,0x83,0x48,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00, +0x34,0x84,0x01,0x10,0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff, +0x10,0x62,0x00,0x16,0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x50, +0x00,0x40,0x28,0x21,0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x54,0x25,0x43,0xff,0xff, +0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00, +0x8c,0x83,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24, +0x38,0x42,0x00,0x00,0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14, +0xac,0x83,0x00,0x00,0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03, +0x00,0x00,0x50,0x21,0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0xa0,0x35,0x6b,0x01,0x20, +0x8d,0x68,0x00,0x00,0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2, +0x11,0x03,0x00,0x37,0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6, +0x01,0x20,0x30,0x21,0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21, +0x00,0xa8,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a, +0x90,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff, +0xa0,0x82,0x00,0x08,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09, +0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40, +0x00,0x43,0x10,0x21,0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04, +0x00,0x00,0x00,0x00,0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08, +0xa0,0xc5,0x00,0xd6,0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0, +0x24,0x84,0x00,0x03,0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b, +0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08, +0x90,0xc2,0x00,0xd5,0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5, +0x00,0x00,0x00,0x00,0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03, +0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04, +0x14,0x40,0xff,0xbf,0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x90,0x82,0x00,0x05,0x08,0x00,0x21,0x0d,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x7a, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20, +0x24,0x42,0x84,0xfc,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00, +0x30,0x90,0x00,0xff,0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0xa4, +0x00,0x00,0x50,0x21,0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x84,0x27,0x99,0xb5,0x80, +0x27,0x8e,0xb5,0x7e,0x27,0x8c,0xb4,0xa8,0x27,0x8d,0xb5,0x00,0x27,0x88,0xb5,0x78, +0x00,0x0a,0x18,0x80,0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58, +0x00,0x6e,0x20,0x21,0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00, +0xa1,0x00,0x00,0x04,0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21, +0x24,0x06,0x00,0x01,0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00, +0xac,0x40,0x00,0x00,0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9, +0x24,0x84,0x00,0x01,0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21, +0x00,0x4c,0x18,0x21,0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04, +0xac,0x82,0x00,0x00,0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01, +0x28,0xc2,0x00,0x1c,0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6, +0x24,0x63,0x00,0x03,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b, +0x25,0x08,0x00,0xec,0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60, +0x00,0x00,0x48,0x21,0x27,0x83,0xb4,0x50,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01, +0x29,0x22,0x00,0x0c,0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x20,0xd2, +0x00,0x00,0x00,0x00,0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0xa0,0x24,0x09,0x00,0x07, +0x10,0x80,0x00,0x0a,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff, +0xa0,0x62,0x00,0x00,0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6, +0x08,0x00,0x21,0x90,0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00, +0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80, +0x27,0x83,0xb4,0xa0,0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x84,0x00,0x20,0x24,0x42,0x86,0x68,0x30,0xc6,0x00,0xff,0x93,0xaa,0x00,0x13, +0x30,0xa5,0x00,0xff,0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xe8, +0x25,0x8f,0x00,0xd0,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc, +0x2c,0x43,0x00,0x18,0x10,0x60,0x00,0xc7,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80, +0x24,0x63,0x02,0x90,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x1c, +0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x17,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x11,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0c, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0x03,0xe0,0x00,0x08, +0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xe8, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0x00,0x02, +0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x0a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe9,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe0, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdb,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19,0x14,0x40,0xff,0xc5, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd0, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b,0x10,0x40,0xff,0xf1, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb5, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf4, +0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xbd, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xb5,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc6,0x24,0x02,0x00,0x03, +0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xae, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xa9,0x24,0x02,0x00,0x02, +0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x03,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xd8, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x9a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x95,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x88, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf3,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x17, +0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x81, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x76,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x97, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x51, +0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x65,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf9, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf7,0x2d,0x42,0x00,0x25,0x08,0x00,0x22,0x2d, +0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x50, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe6, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad,0x00,0x00,0x00,0x00, +0x08,0x00,0x22,0x79,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a,0x14,0x40,0xff,0xd8, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe9,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c, +0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xbd,0x00,0x00,0x00,0x00, +0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff, +0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,0x00,0x04,0x48,0x80,0x01,0x82,0x58,0x21, +0x01,0x89,0x40,0x21,0x25,0x78,0x00,0x08,0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60, +0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64, +0x01,0x27,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60, +0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00, +0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00, +0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b, +0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4, +0x27,0x87,0x81,0x64,0x08,0x00,0x22,0xb0,0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4, +0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01, +0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x02,0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60, +0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,0x10,0xe0,0x00,0x1d,0x24,0x83,0xff,0xfc, +0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x10,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01, +0x24,0x63,0x02,0xf0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x65, +0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x5a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0xad,0x82,0x00,0xd0, +0x8d,0xe3,0x00,0x00,0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xad,0xa2,0x00,0x00,0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00, +0x93,0x05,0x00,0x01,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05, +0x24,0x02,0x00,0x01,0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08, +0xad,0x80,0x00,0xd8,0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05, +0x00,0x00,0x00,0x00,0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08, +0xa1,0x83,0x00,0xdd,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43, +0xad,0xa2,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00, +0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40, +0x00,0x04,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x22,0xc2, +0xad,0xc5,0x00,0x00,0x97,0x82,0x8b,0x7c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a, +0x10,0x40,0xfe,0xab,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x15,0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64, +0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21, +0xac,0x64,0x00,0x60,0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80, +0x01,0x82,0x10,0x21,0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x37,0xa1,0x80,0x00,0xdd, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3, +0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x0a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa0, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x9d,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x93,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdd,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19, +0x14,0x40,0xff,0x7c,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x83,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b, +0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x14,0xa2,0xff,0x6c,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3, +0x24,0x42,0xff,0xf4,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xbd,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x68, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xee, +0x24,0x02,0x00,0x03,0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xae,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5c, +0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x74, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x49,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x9a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x48, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x3b,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x64,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x17,0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xa5, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x81,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x29,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0xc2,0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x6a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x18, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x6a,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x68,0x2d,0x42,0x00,0x25, +0x08,0x00,0x23,0x9e,0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x03,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x57,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad, +0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xea,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a, +0x14,0x40,0xff,0xd8,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x5a,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x2c,0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xe5, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,0xaf,0xbf,0x00,0x14, +0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,0x8c,0x50,0x00,0x00, +0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,0xa3,0x82,0x80,0x10, +0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,0x14,0x40,0x00,0x09, +0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x01, +0xa3,0x82,0xbc,0x18,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x37,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0x00, +0xa3,0x80,0xbc,0x18,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x16, +0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0xff, +0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x13,0x32,0x02,0x01,0x00, +0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xaf,0xbf,0x00,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,0x00,0x03,0x33,0x02, +0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,0x00,0x62,0x18,0x24, +0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,0x31,0x08,0x00,0xff, +0x01,0x00,0x30,0x21,0x0c,0x00,0x24,0xdf,0xaf,0xa9,0x00,0x10,0x8f,0xbf,0x00,0x18, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x25,0x31, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,0x08,0x00,0x24,0x3f, +0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0x3c,0x02,0xb0,0x03,0xaf,0xbe,0x00,0x38, +0xaf,0xb5,0x00,0x2c,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c, +0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24, +0xaf,0xb2,0x00,0x20,0x34,0x42,0x00,0x3f,0x90,0x43,0x00,0x00,0x00,0x80,0x80,0x21, +0x00,0x00,0xf0,0x21,0x00,0x00,0x88,0x21,0x10,0x60,0x00,0x76,0x00,0x00,0xa8,0x21, +0x3c,0x01,0xb0,0x03,0xa0,0x20,0x00,0x3f,0x00,0x10,0x12,0x02,0x24,0x04,0x06,0x14, +0x0c,0x00,0x06,0xd1,0x30,0x54,0x00,0x0f,0x24,0x04,0x06,0x14,0x0c,0x00,0x06,0xd1, +0xaf,0xa2,0x00,0x10,0x3c,0x03,0x00,0xff,0x34,0x63,0xff,0xff,0x32,0x10,0x00,0x7f, +0x00,0x43,0x10,0x24,0x00,0x10,0x86,0x00,0x02,0x02,0x80,0x25,0x02,0x00,0x28,0x21, +0x24,0x04,0x06,0x14,0x3c,0x13,0xbf,0xff,0x0c,0x00,0x06,0xbf,0x3c,0x16,0xb0,0x03, +0x00,0x00,0x90,0x21,0x3c,0x17,0x40,0x00,0x36,0x73,0xff,0xff,0x36,0xd6,0x00,0x3e, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25,0x00,0x40,0x28,0x21, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21,0x0c,0x00,0x25,0xf9, +0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x10,0x40,0x00,0x46,0x30,0x70,0x00,0xff, +0x12,0x00,0xff,0xfa,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00, +0x00,0x53,0x10,0x24,0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00, +0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x37,0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x35, +0x00,0x00,0x00,0x00,0x32,0x31,0x00,0x7f,0x12,0x20,0x00,0x04,0x24,0x03,0x00,0x04, +0x27,0xc2,0x00,0x01,0x30,0x5e,0x00,0xff,0x02,0xb1,0xa8,0x21,0x12,0x43,0x00,0x2a, +0x3c,0x03,0xb0,0x03,0x02,0x43,0x10,0x21,0xa0,0x51,0x00,0x34,0x26,0x42,0x00,0x01, +0x30,0x52,0x00,0xff,0x2e,0x43,0x00,0x05,0x14,0x60,0xff,0xd9,0x00,0x00,0x00,0x00, +0x8f,0xa5,0x00,0x10,0x0c,0x00,0x06,0xbf,0x24,0x04,0x06,0x14,0x12,0xa0,0x00,0x0e, +0x3c,0x02,0xb0,0x03,0x13,0xc0,0x00,0x0d,0x34,0x42,0x00,0x3c,0x00,0x15,0x10,0x40, +0x00,0x55,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x55,0x10,0x21,0x00,0x02,0xa8,0x80, +0x02,0xbe,0x00,0x1b,0x17,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, +0x00,0x00,0xa8,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3c,0x3c,0x03,0xb0,0x03, +0x3c,0x04,0xb0,0x03,0xa4,0x55,0x00,0x00,0x34,0x63,0x00,0x1c,0x34,0x84,0x00,0x1d, +0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0xa0,0x82,0x00,0x00,0x7b,0xbe,0x01,0xfc, +0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0xa2,0xd1,0x00,0x00,0x08,0x00,0x24,0x98, +0x26,0x42,0x00,0x01,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0x8d, +0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x3c,0x3c,0x04,0xb0,0x03, +0x3c,0x05,0xb0,0x03,0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0x1c,0x34,0xa5,0x00,0x1d, +0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xb7, +0xa0,0xa3,0x00,0x00,0x0c,0x00,0x17,0x99,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x8b, +0x00,0x10,0x12,0x02,0x3c,0x02,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x34,0x42,0x00,0x3c, +0x34,0x84,0x00,0x14,0x24,0x03,0x00,0x01,0xa4,0x40,0x00,0x00,0x3c,0x01,0xb0,0x03, +0xa0,0x23,0x00,0x3f,0x08,0x00,0x24,0xb7,0xac,0x90,0x00,0x00,0x27,0xbd,0xff,0xd8, +0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0x30,0xb1,0x00,0xff, +0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x38, +0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,0x3c,0x04,0xb0,0x09, +0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,0x90,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x2a, +0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x20, +0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,0x16,0x60,0xff,0xe2, +0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0d, +0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,0x16,0x22,0xff,0xda, +0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f, +0x3c,0x06,0x0c,0xb8,0x08,0x00,0x24,0xea,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12, +0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12, +0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x12,0x24,0x04,0x08,0x44,0x24,0x04,0x08,0x4c, +0x0c,0x00,0x13,0x5f,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x07,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x44, +0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x24,0xf5, +0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c, +0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21,0x14,0x40,0x00,0x07, +0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x24, +0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f,0x0c,0x00,0x25,0xae, +0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21,0x24,0x02,0x00,0x01, +0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02, +0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff, +0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21, +0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x44, +0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x25,0x49, +0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,0x30,0xa5,0x00,0xff, +0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x12, +0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x07, +0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x05,0xff,0xff, +0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xe2, +0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,0x24,0x04,0x08,0x40, +0x08,0x00,0x25,0x88,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x44, +0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x14, +0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0a, +0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,0x08,0x00,0x25,0x82, +0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xb8, +0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x48, +0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xa2,0x24,0x05,0xff,0xff, +0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8,0x30,0x84,0x00,0xff, +0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10,0x28,0x82,0x00,0x02, +0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x17, +0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05,0x24,0x04,0x08,0x3c, +0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac,0x0c,0x00,0x13,0x41, +0x24,0x05,0x0f,0xff,0x08,0x00,0x25,0xbc,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x34, +0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa8, +0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24,0x0c,0x00,0x13,0x5f, +0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f, +0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f, +0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa0,0x00,0xa0,0x30,0x21, +0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb, +0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x20, +0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0x34,0xa5,0x17,0x09, +0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24,0x34,0x84,0x02,0x28, +0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00,0x34,0xe7,0x04,0x50, +0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03, +0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x53,0x00,0x80,0x40,0x21, +0x8c,0x89,0x00,0x04,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x8c,0xc3,0x00,0x04, +0x3c,0x02,0x01,0x00,0x00,0x62,0x10,0x24,0x10,0x40,0x00,0x4b,0x30,0x62,0x00,0x08, +0x10,0x45,0x00,0x59,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4, +0x30,0x44,0x00,0xff,0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54, +0x24,0x02,0x00,0x94,0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38, +0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88, +0x14,0x62,0x00,0x39,0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38, +0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff, +0x30,0xe2,0x00,0x80,0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21, +0x94,0xc3,0x00,0x60,0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00, +0x90,0xc2,0x00,0x62,0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15, +0x24,0x02,0x00,0x06,0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac, +0x94,0xc4,0x00,0x66,0x27,0x82,0x89,0x68,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff, +0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02, +0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff, +0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0x76, +0xad,0x07,0x00,0x10,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x68, +0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00, +0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36, +0x3c,0x03,0xff,0xff,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25, +0xac,0xa4,0x00,0x00,0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x94,0xc2,0x00,0x50,0x08,0x00,0x26,0x34,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac, +0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, +0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00, +0x24,0x03,0x00,0x2e,0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21, +0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e, +0x24,0x03,0x00,0x0e,0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac, +0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, +0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14, +0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x30,0xc6,0x00,0xff,0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x8b,0xbc,0x30,0x27,0x83,0xbc,0x36,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21, +0x94,0x47,0x00,0x00,0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff, +0x95,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01, +0x10,0x43,0x00,0x18,0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x4b,0x30,0x21,0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x36,0x27,0x85,0xbc,0x34, +0x00,0x45,0x28,0x21,0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02, +0xa4,0x40,0x00,0x00,0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01, +0x01,0x44,0x20,0x21,0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00, +0x8c,0x82,0x00,0x04,0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x04,0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24, +0x00,0x47,0x28,0x25,0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2, +0x01,0x43,0x18,0x21,0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21, +0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01, +0x14,0x62,0x00,0x0d,0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09, +0x00,0x82,0x20,0x21,0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00, +0x34,0xc6,0x01,0x00,0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00, +0x24,0x02,0x00,0x06,0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x09,0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e, +0x08,0x00,0x26,0xd6,0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff, +0x00,0xa2,0x28,0x21,0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21, +0x00,0x62,0x18,0x24,0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x42,0x80,0x00,0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8, +0x00,0x00,0x00,0x00,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, +0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, +0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0, +0x8c,0xc4,0x01,0xac,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26, +0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21, +0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02, +0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09, +0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05, +0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03, +0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00, +0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x68,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21, +0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21, +0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x68,0x01,0x22,0x10,0x24, +0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2, +0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00, +0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00, +0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x20, +0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x28,0x8c,0xa3,0x00,0x04, +0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x24, +0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, +0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff, +0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x21, +0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20, +0x24,0x42,0x9d,0x64,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20, +0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0xac,0x80,0x00,0x00, +0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,0xac,0x80,0x00,0x50, +0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,0xa0,0x80,0x00,0x5c, +0x24,0x42,0x9e,0x28,0x24,0x83,0x00,0x68,0x24,0x05,0x00,0x0f,0x24,0xa5,0xff,0xff, +0xac,0x62,0x00,0x00,0x04,0xa1,0xff,0xfd,0x24,0x63,0x00,0x04,0x3c,0x02,0x80,0x01, +0x24,0x42,0x9f,0x10,0xac,0x82,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01, +0x24,0x63,0xa0,0x9c,0x24,0x42,0xa0,0x08,0xac,0x83,0x00,0x88,0xac,0x82,0x00,0x98, +0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x24,0x63,0xa1,0x44,0x24,0x42,0xa2,0x5c, +0xac,0x83,0x00,0xa0,0xac,0x82,0x00,0xa4,0xa0,0x80,0x01,0xba,0xac,0x80,0x01,0xa8, +0xac,0x80,0x01,0xac,0xac,0x80,0x01,0xb0,0xac,0x80,0x01,0xb4,0xa0,0x80,0x01,0xb8, +0x03,0xe0,0x00,0x08,0xa0,0x80,0x01,0xb9,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0x28,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x9e,0x40, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11, +0x00,0x80,0x28,0x21,0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d, +0x00,0x00,0x00,0x00,0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04, +0x00,0x83,0x20,0x21,0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b, +0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff, +0xac,0xa2,0x00,0x04,0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50, +0xac,0xa0,0x00,0x54,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0xbc,0xac,0x62,0x00,0x00, +0x8c,0x86,0x00,0x04,0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21, +0x8c,0x45,0x00,0x00,0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff, +0x30,0x42,0x00,0xff,0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14, +0xac,0x85,0x00,0x40,0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, +0x24,0x63,0x9f,0x10,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, +0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21, +0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54, +0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00,0x08,0x00,0x27,0xd1, +0xae,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x42,0x00,0x20,0x24,0x63,0x9f,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16, +0x00,0x80,0x80,0x21,0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44, +0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50, +0x30,0xa3,0x00,0xff,0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f, +0x30,0x42,0x00,0x03,0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c, +0xae,0x03,0x00,0x30,0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00, +0x08,0x00,0x27,0xe9,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, +0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x08,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40, +0x83,0x85,0x8b,0xd4,0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02, +0xae,0x04,0x00,0x14,0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04, +0xae,0x03,0x00,0x3c,0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01, +0x24,0x02,0x00,0x01,0xa3,0x86,0x8b,0xd4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd, +0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x0e,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x9c, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03, +0x8c,0x42,0x00,0x00,0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xd4, +0x92,0x05,0x00,0x41,0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2, +0x00,0x03,0x1e,0x02,0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21, +0xae,0x03,0x00,0x18,0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03, +0x24,0x02,0x00,0x01,0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xd4, +0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x33, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0x44,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37, +0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00, +0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25, +0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21, +0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68, +0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac, +0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04,0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68, +0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10,0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac, +0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00, +0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, +0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac, +0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0, +0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00, +0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27, +0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x5c, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37,0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04, +0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10, +0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04, +0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00, +0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68,0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00, +0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04, +0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68,0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10, +0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03, +0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23, +0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30, +0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01, +0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xa3, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20, +0x24,0x63,0xa3,0x74,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0x3c,0x02,0x80,0x01, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c, +0x00,0x80,0x80,0x21,0x24,0x52,0x9e,0x28,0x00,0x00,0x88,0x21,0x3c,0x03,0xb0,0x09, +0x34,0x63,0x00,0x06,0x8e,0x06,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x06,0x22,0x02, +0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f, +0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff, +0x10,0x44,0x00,0x68,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x01,0x00,0xc2,0x10,0x21, +0x8c,0x44,0x00,0x04,0x3c,0x03,0x7c,0x00,0x34,0x63,0x00,0xf0,0x00,0x83,0x18,0x24, +0xae,0x04,0x00,0x44,0x8c,0x44,0x00,0x00,0x10,0x60,0x00,0x69,0x00,0x00,0x38,0x21, +0x3c,0x09,0xb0,0x03,0x3c,0x06,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01, +0x24,0x08,0x00,0x40,0x34,0xc6,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38, +0x16,0x20,0x00,0x06,0x24,0xa5,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01, +0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04, +0x24,0x07,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04, +0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44, +0x8c,0x44,0x00,0x00,0x10,0xa8,0x00,0x2d,0x00,0x66,0x18,0x24,0x14,0x60,0xff,0xec, +0x00,0x8b,0x10,0x24,0x14,0x4c,0xff,0xea,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x2f, +0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60,0x00,0x02,0x1e,0x42, +0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01,0xae,0x02,0x00,0x00, +0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64,0x8e,0x04,0x00,0x58, +0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0xae,0x00,0x00,0x4c, +0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,0x8e,0x03,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x42,0x00,0x68, +0x00,0x00,0x00,0x00,0x10,0x52,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x40,0xf8,0x09, +0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0xae,0x03,0x00,0x60,0x08,0x00,0x28,0xeb,0xae,0x04,0x00,0x64,0x8e,0x02,0x00,0x64, +0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00,0x7a,0x02,0x0d,0x7c, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26, +0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x34,0x63,0x00,0x06, +0x8e,0x04,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x04,0x22,0x02,0x00,0x44,0x10,0x23, +0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x14,0x87,0xff,0xc5, +0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03, +0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01, +0x08,0x00,0x29,0x4b,0xa2,0x02,0x00,0x5c,0x08,0x00,0x29,0x4b,0xa2,0x00,0x00,0x5c, +0x3c,0x02,0xff,0xff,0x00,0x82,0x10,0x24,0x3c,0x03,0x28,0x38,0x14,0x43,0xff,0x94, +0x24,0x02,0x00,0x01,0x08,0x00,0x29,0x23,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xcc,0xac,0x43,0x00,0x00, +0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,0x00,0x80,0x40,0x21,0x10,0x62,0x00,0x20, +0x00,0x00,0x20,0x21,0x93,0x82,0x81,0xf1,0x00,0x03,0x28,0x80,0x3c,0x07,0xb0,0x06, +0x00,0xa8,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x66,0x00,0xa8,0x10,0x44,0x00,0x1c, +0x34,0xe7,0x80,0x18,0x3c,0x05,0xb0,0x01,0xaf,0x86,0xbc,0x20,0x00,0xc5,0x28,0x21, +0x8c,0xa3,0x00,0x00,0x00,0x06,0x20,0xc2,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00, +0x00,0x82,0x20,0x25,0xaf,0x83,0xbc,0x28,0x8c,0xa2,0x00,0x04,0xac,0xe4,0x00,0x00, +0x8d,0x03,0x01,0xa8,0xaf,0x82,0xbc,0x24,0x24,0x64,0x00,0x01,0x04,0x80,0x00,0x0a, +0x00,0x80,0x10,0x21,0x00,0x02,0x11,0x83,0x8d,0x03,0x01,0xac,0x00,0x02,0x11,0x80, +0x00,0x82,0x10,0x23,0x00,0x43,0x18,0x26,0xad,0x02,0x01,0xa8,0x00,0x03,0x20,0x2b, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x29,0x95,0x24,0x62,0x00,0x40, +0x27,0x82,0x89,0x68,0x00,0x06,0x20,0xc2,0x00,0x04,0x22,0x00,0x00,0xa2,0x48,0x21, +0x3c,0x02,0x00,0x80,0x00,0x82,0x58,0x25,0x93,0x82,0x81,0xf0,0x3c,0x0a,0xb0,0x06, +0x3c,0x03,0xb0,0x01,0x2c,0x42,0x00,0x02,0x00,0xc3,0x38,0x21,0x35,0x4a,0x80,0x18, +0x14,0x40,0xff,0xef,0x00,0x00,0x20,0x21,0x8c,0xe5,0x00,0x00,0x8d,0x23,0x00,0x00, +0x24,0x02,0xc0,0x00,0x00,0xa2,0x10,0x24,0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x00, +0x8d,0x04,0x01,0xa8,0x27,0x83,0x8a,0x68,0x8c,0xe5,0x00,0x04,0x00,0x04,0x20,0x80, +0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0xa2,0x10,0x25, +0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x04,0xaf,0x86,0xbc,0x20,0x8c,0xe2,0x00,0x00, +0x93,0x85,0x81,0xf0,0xaf,0x82,0xbc,0x28,0x8c,0xe3,0x00,0x04,0xad,0x4b,0x00,0x00, +0x8d,0x02,0x01,0xa8,0xaf,0x83,0xbc,0x24,0x24,0xa5,0xff,0xff,0x24,0x44,0x00,0x01, +0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83, +0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xad,0x04,0x01,0xa8,0xa3,0x85,0x81,0xf0, +0x79,0x02,0x0d,0x7c,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x26,0x08,0x00,0x29,0x9c, +0x00,0x02,0x20,0x2b,0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01, +0x34,0xc6,0x00,0x18,0x34,0x84,0x00,0x20,0x24,0x42,0xa7,0x54,0x24,0x03,0xff,0x83, +0xac,0x82,0x00,0x00,0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8, +0x3c,0x03,0xb0,0x07,0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00, +0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01, +0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07, +0xa3,0xa3,0x00,0x00,0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10, +0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38, +0xa0,0xa2,0x00,0x00,0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20, +0xa3,0xa4,0x00,0x00,0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x30, +0xa3,0xa3,0x00,0x00,0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x08,}; + +u8 rtl8192e_fwdata_array[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00, +0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72, +0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b, +0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e, +0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98, +0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c, +0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c, +0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e, +0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89, +0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44, +0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab, +0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08, +0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c, +0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74, +0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c, +0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00, +0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64, +0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x63, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c, +0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60, +0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80, +0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c, +0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4, +0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38, +0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8, +0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, +0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x6c,0x80,0x00,0x07,0x80, +0x80,0x00,0x07,0x80,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x94, +0x80,0x00,0x56,0xb0,0x80,0x00,0x57,0x08,0x80,0x00,0x57,0x30,0x80,0x00,0x58,0x28, +0x80,0x00,0x58,0xe0,0x80,0x00,0x59,0x88,0x80,0x00,0x59,0xfc,0x80,0x00,0x5b,0x08, +0x80,0x00,0x5b,0x40,0x80,0x00,0x5b,0x54,0x80,0x00,0x5b,0x68,0x80,0x00,0x5c,0x50, +0x80,0x00,0x5c,0x90,0x80,0x00,0x5d,0x44,0x80,0x00,0x5d,0x6c,0x80,0x00,0x56,0x70, +0x80,0x00,0x5d,0xbc,0x80,0x00,0x64,0x48,0x80,0x00,0x64,0xc0,0x80,0x00,0x64,0xcc, +0x80,0x00,0x64,0xd8,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0xe4,0x80,0x00,0x64,0xf0,0x80,0x00,0x64,0xfc, +0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xd8, +0x80,0x00,0x88,0x18,0x80,0x00,0x88,0x50,0x80,0x00,0x88,0x80,0x80,0x00,0x88,0xb0, +0x80,0x00,0x88,0xc4,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x40,0x80,0x00,0x89,0x7c, +0x80,0x00,0x89,0x84,0x80,0x00,0x89,0xc0,0x80,0x00,0x89,0xd4,0x80,0x00,0x89,0xdc, +0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4, +0x80,0x00,0x8a,0x14,0x80,0x00,0x8a,0x28,0x80,0x00,0x8a,0x3c,0x80,0x00,0x86,0xe8, +0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x9c, +0x80,0x00,0x8d,0xdc,0x80,0x00,0x8e,0x14,0x80,0x00,0x8e,0x44,0x80,0x00,0x8e,0x74, +0x80,0x00,0x8e,0x88,0x80,0x00,0x8e,0xf0,0x80,0x00,0x8f,0x04,0x80,0x00,0x8f,0x40, +0x80,0x00,0x8f,0x48,0x80,0x00,0x8f,0x84,0x80,0x00,0x8f,0x98,0x80,0x00,0x8f,0xa0, +0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8, +0x80,0x00,0x8f,0xd8,0x80,0x00,0x8f,0xec,0x80,0x00,0x90,0x00,0x80,0x00,0x8b,0x88, +}; + +#endif diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c new file mode 100644 index 00000000000..5b1247e6e8a --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -0,0 +1,3352 @@ +#include "r8192E.h" +#include "r8192E_hw.h" +#include "r819xE_phyreg.h" +#include "r8190_rtl8256.h" +#include "r819xE_phy.h" +#include "r8192E_dm.h" +#ifdef ENABLE_DOT11D +#include "dot11d.h" +#endif +static u32 RF_CHANNEL_TABLE_ZEBRA[] = { + 0, + 0x085c, //2412 1 + 0x08dc, //2417 2 + 0x095c, //2422 3 + 0x09dc, //2427 4 + 0x0a5c, //2432 5 + 0x0adc, //2437 6 + 0x0b5c, //2442 7 + 0x0bdc, //2447 8 + 0x0c5c, //2452 9 + 0x0cdc, //2457 10 + 0x0d5c, //2462 11 + 0x0ddc, //2467 12 + 0x0e5c, //2472 13 + 0x0f72, //2484 +}; +#ifdef RTL8190P +u32 Rtl8190PciMACPHY_Array[] = { +0x03c,0xffff0000,0x00000f0f, +0x340,0xffffffff,0x161a1a1a, +0x344,0xffffffff,0x12121416, +0x348,0x0000ffff,0x00001818, +0x12c,0xffffffff,0x04000802, +0x318,0x00000fff,0x00000800, +}; +u32 Rtl8190PciMACPHY_Array_PG[] = { +0x03c,0xffff0000,0x00000f0f, +0x340,0xffffffff,0x0a0c0d0f, +0x344,0xffffffff,0x06070809, +0x344,0xffffffff,0x06070809, +0x348,0x0000ffff,0x00000000, +0x12c,0xffffffff,0x04000802, +0x318,0x00000fff,0x00000800, +}; + +u32 Rtl8190PciAGCTAB_Array[AGCTAB_ArrayLength] = { +0xc78,0x7d000001, +0xc78,0x7d010001, +0xc78,0x7d020001, +0xc78,0x7d030001, +0xc78,0x7c040001, +0xc78,0x7b050001, +0xc78,0x7a060001, +0xc78,0x79070001, +0xc78,0x78080001, +0xc78,0x77090001, +0xc78,0x760a0001, +0xc78,0x750b0001, +0xc78,0x740c0001, +0xc78,0x730d0001, +0xc78,0x720e0001, +0xc78,0x710f0001, +0xc78,0x70100001, +0xc78,0x6f110001, +0xc78,0x6e120001, +0xc78,0x6d130001, +0xc78,0x6c140001, +0xc78,0x6b150001, +0xc78,0x6a160001, +0xc78,0x69170001, +0xc78,0x68180001, +0xc78,0x67190001, +0xc78,0x661a0001, +0xc78,0x651b0001, +0xc78,0x641c0001, +0xc78,0x491d0001, +0xc78,0x481e0001, +0xc78,0x471f0001, +0xc78,0x46200001, +0xc78,0x45210001, +0xc78,0x44220001, +0xc78,0x43230001, +0xc78,0x28240001, +0xc78,0x27250001, +0xc78,0x26260001, +0xc78,0x25270001, +0xc78,0x24280001, +0xc78,0x23290001, +0xc78,0x222a0001, +0xc78,0x212b0001, +0xc78,0x202c0001, +0xc78,0x0a2d0001, +0xc78,0x082e0001, +0xc78,0x062f0001, +0xc78,0x05300001, +0xc78,0x04310001, +0xc78,0x03320001, +0xc78,0x02330001, +0xc78,0x01340001, +0xc78,0x00350001, +0xc78,0x00360001, +0xc78,0x00370001, +0xc78,0x00380001, +0xc78,0x00390001, +0xc78,0x003a0001, +0xc78,0x003b0001, +0xc78,0x003c0001, +0xc78,0x003d0001, +0xc78,0x003e0001, +0xc78,0x003f0001, +0xc78,0x7d400001, +0xc78,0x7d410001, +0xc78,0x7d420001, +0xc78,0x7d430001, +0xc78,0x7c440001, +0xc78,0x7b450001, +0xc78,0x7a460001, +0xc78,0x79470001, +0xc78,0x78480001, +0xc78,0x77490001, +0xc78,0x764a0001, +0xc78,0x754b0001, +0xc78,0x744c0001, +0xc78,0x734d0001, +0xc78,0x724e0001, +0xc78,0x714f0001, +0xc78,0x70500001, +0xc78,0x6f510001, +0xc78,0x6e520001, +0xc78,0x6d530001, +0xc78,0x6c540001, +0xc78,0x6b550001, +0xc78,0x6a560001, +0xc78,0x69570001, +0xc78,0x68580001, +0xc78,0x67590001, +0xc78,0x665a0001, +0xc78,0x655b0001, +0xc78,0x645c0001, +0xc78,0x495d0001, +0xc78,0x485e0001, +0xc78,0x475f0001, +0xc78,0x46600001, +0xc78,0x45610001, +0xc78,0x44620001, +0xc78,0x43630001, +0xc78,0x28640001, +0xc78,0x27650001, +0xc78,0x26660001, +0xc78,0x25670001, +0xc78,0x24680001, +0xc78,0x23690001, +0xc78,0x226a0001, +0xc78,0x216b0001, +0xc78,0x206c0001, +0xc78,0x0a6d0001, +0xc78,0x086e0001, +0xc78,0x066f0001, +0xc78,0x05700001, +0xc78,0x04710001, +0xc78,0x03720001, +0xc78,0x02730001, +0xc78,0x01740001, +0xc78,0x00750001, +0xc78,0x00760001, +0xc78,0x00770001, +0xc78,0x00780001, +0xc78,0x00790001, +0xc78,0x007a0001, +0xc78,0x007b0001, +0xc78,0x007c0001, +0xc78,0x007d0001, +0xc78,0x007e0001, +0xc78,0x007f0001, +0xc78,0x3600001e, +0xc78,0x3601001e, +0xc78,0x3602001e, +0xc78,0x3603001e, +0xc78,0x3604001e, +0xc78,0x3605001e, +0xc78,0x3a06001e, +0xc78,0x3c07001e, +0xc78,0x3e08001e, +0xc78,0x4209001e, +0xc78,0x430a001e, +0xc78,0x450b001e, +0xc78,0x470c001e, +0xc78,0x480d001e, +0xc78,0x490e001e, +0xc78,0x4b0f001e, +0xc78,0x4c10001e, +0xc78,0x4d11001e, +0xc78,0x4d12001e, +0xc78,0x4e13001e, +0xc78,0x4f14001e, +0xc78,0x5015001e, +0xc78,0x5116001e, +0xc78,0x5117001e, +0xc78,0x5218001e, +0xc78,0x5219001e, +0xc78,0x531a001e, +0xc78,0x541b001e, +0xc78,0x541c001e, +0xc78,0x551d001e, +0xc78,0x561e001e, +0xc78,0x561f001e, +0xc78,0x5720001e, +0xc78,0x5821001e, +0xc78,0x5822001e, +0xc78,0x5923001e, +0xc78,0x5924001e, +0xc78,0x5a25001e, +0xc78,0x5b26001e, +0xc78,0x5b27001e, +0xc78,0x5c28001e, +0xc78,0x5c29001e, +0xc78,0x5d2a001e, +0xc78,0x5d2b001e, +0xc78,0x5e2c001e, +0xc78,0x5e2d001e, +0xc78,0x5f2e001e, +0xc78,0x602f001e, +0xc78,0x6030001e, +0xc78,0x6131001e, +0xc78,0x6132001e, +0xc78,0x6233001e, +0xc78,0x6234001e, +0xc78,0x6335001e, +0xc78,0x6336001e, +0xc78,0x6437001e, +0xc78,0x6538001e, +0xc78,0x6639001e, +0xc78,0x663a001e, +0xc78,0x673b001e, +0xc78,0x683c001e, +0xc78,0x693d001e, +0xc78,0x6a3e001e, +0xc78,0x6b3f001e, +}; + +u32 Rtl8190PciPHY_REGArray[PHY_REGArrayLength] = { +0x800,0x00050060, +0x804,0x00000005, +0x808,0x0000fc00, +0x80c,0x0000001c, +0x810,0x801010aa, +0x814,0x000908c0, +0x818,0x00000000, +0x81c,0x00000000, +0x820,0x00000004, +0x824,0x00690000, +0x828,0x00000004, +0x82c,0x00e90000, +0x830,0x00000004, +0x834,0x00690000, +0x838,0x00000004, +0x83c,0x00e90000, +0x840,0x00000000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x65a965a9, +0x85c,0x65a965a9, +0x860,0x001f0010, +0x864,0x007f0010, +0x868,0x001f0010, +0x86c,0x007f0010, +0x870,0x0f100f70, +0x874,0x0f100f70, +0x878,0x00000000, +0x87c,0x00000000, +0x880,0x5c385eb8, +0x884,0x6357060d, +0x888,0x0460c341, +0x88c,0x0000ff00, +0x890,0x00000000, +0x894,0xfffffffe, +0x898,0x4c42382f, +0x89c,0x00656056, +0x8b0,0x00000000, +0x8e0,0x00000000, +0x8e4,0x00000000, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x35541545, +0xa00,0x00d0c7d8, +0xa04,0xab1f0008, +0xa08,0x80cd8300, +0xa0c,0x2e62740f, +0xa10,0x95009b78, +0xa14,0x11145008, +0xa18,0x00881117, +0xa1c,0x89140fa0, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00000000, +0xc00,0x00000040, +0xc04,0x0000500f, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08000000, +0xc14,0x40000100, +0xc18,0x08000000, +0xc1c,0x40000100, +0xc20,0x08000000, +0xc24,0x40000100, +0xc28,0x08000000, +0xc2c,0x40000100, +0xc30,0x6de9ac44, +0xc34,0x164052cd, +0xc38,0x00070a14, +0xc3c,0x0a969764, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020000, +0xc4c,0x00000300, +0xc50,0x69543420, +0xc54,0x433c0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x69543420, +0xc64,0x433c0094, +0xc68,0x69543420, +0xc6c,0x433c0094, +0xc70,0x2c7f000d, +0xc74,0x0186175b, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x00000000, +0xc88,0x40000100, +0xc8c,0x08000000, +0xc90,0x40000100, +0xc94,0x00000000, +0xc98,0x40000100, +0xc9c,0x00000000, +0xca0,0x00492492, +0xca4,0x00000000, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x00492492, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xd00,0x00000740, +0xd04,0x0000040f, +0xd08,0x0000803f, +0xd0c,0x00000001, +0xd10,0xa0633333, +0xd14,0x33333c63, +0xd18,0x6a8f5b6b, +0xd1c,0x00000000, +0xd20,0x00000000, +0xd24,0x00000000, +0xd28,0x00000000, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x00000000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x024dbd02, +0xd58,0x00000000, +0xd5c,0x14032064, +}; +u32 Rtl8190PciPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = { +0x800,0x00050060, +0x804,0x00000004, +0x808,0x0000fc00, +0x80c,0x0000001c, +0x810,0x801010aa, +0x814,0x000908c0, +0x818,0x00000000, +0x81c,0x00000000, +0x820,0x00000004, +0x824,0x00690000, +0x828,0x00000004, +0x82c,0x00e90000, +0x830,0x00000004, +0x834,0x00690000, +0x838,0x00000004, +0x83c,0x00e90000, +0x840,0x00000000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x65a965a9, +0x85c,0x65a965a9, +0x860,0x001f0000, +0x864,0x007f0000, +0x868,0x001f0010, +0x86c,0x007f0010, +0x870,0x0f100f70, +0x874,0x0f100f70, +0x878,0x00000000, +0x87c,0x00000000, +0x880,0x5c385898, +0x884,0x6357060d, +0x888,0x0460c341, +0x88c,0x0000fc00, +0x890,0x00000000, +0x894,0xfffffffe, +0x898,0x4c42382f, +0x89c,0x00656056, +0x8b0,0x00000000, +0x8e0,0x00000000, +0x8e4,0x00000000, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x34441444, +0xa00,0x00d0c7d8, +0xa04,0x2b1f0008, +0xa08,0x80cd8300, +0xa0c,0x2e62740f, +0xa10,0x95009b78, +0xa14,0x11145008, +0xa18,0x00881117, +0xa1c,0x89140fa0, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00000000, +0xc00,0x00000040, +0xc04,0x0000500c, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08000000, +0xc14,0x40000100, +0xc18,0x08000000, +0xc1c,0x40000100, +0xc20,0x08000000, +0xc24,0x40000100, +0xc28,0x08000000, +0xc2c,0x40000100, +0xc30,0x6de9ac44, +0xc34,0x164052cd, +0xc38,0x00070a14, +0xc3c,0x0a969764, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020000, +0xc4c,0x00000300, +0xc50,0x69543420, +0xc54,0x433c0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x69543420, +0xc64,0x433c0094, +0xc68,0x69543420, +0xc6c,0x433c0094, +0xc70,0x2c7f000d, +0xc74,0x0186175b, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x00000000, +0xc88,0x40000100, +0xc8c,0x08000000, +0xc90,0x40000100, +0xc94,0x00000000, +0xc98,0x40000100, +0xc9c,0x00000000, +0xca0,0x00492492, +0xca4,0x00000000, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x00492492, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xd00,0x00000740, +0xd04,0x0000040c, +0xd08,0x0000803f, +0xd0c,0x00000001, +0xd10,0xa0633333, +0xd14,0x33333c63, +0xd18,0x6a8f5b6b, +0xd1c,0x00000000, +0xd20,0x00000000, +0xd24,0x00000000, +0xd28,0x00000000, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x00000000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x024dbd02, +0xd58,0x00000000, +0xd5c,0x14032064, +}; + +u32 Rtl8190PciRadioA_Array[RadioA_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x00000ee0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x009,0x000007f0, +0x00a,0x000009d0, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x00f,0x00000990, +0x012,0x00000806, +0x014,0x000005ab, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000f80, +0x01b,0x00000f5e, +0x01c,0x00000008, +0x01d,0x00000607, +0x01e,0x000006cc, +0x01f,0x00000000, +0x020,0x000001a5, +0x01f,0x00000001, +0x020,0x00000165, +0x01f,0x00000002, +0x020,0x000000c6, +0x01f,0x00000003, +0x020,0x00000086, +0x01f,0x00000004, +0x020,0x00000046, +0x01f,0x00000005, +0x020,0x000001e6, +0x01f,0x00000006, +0x020,0x000001a6, +0x01f,0x00000007, +0x020,0x00000166, +0x01f,0x00000008, +0x020,0x000000c7, +0x01f,0x00000009, +0x020,0x00000087, +0x01f,0x0000000a, +0x020,0x000000f7, +0x01f,0x0000000b, +0x020,0x000000d7, +0x01f,0x0000000c, +0x020,0x000000b7, +0x01f,0x0000000d, +0x020,0x00000097, +0x01f,0x0000000e, +0x020,0x00000077, +0x01f,0x0000000f, +0x020,0x00000057, +0x01f,0x00000010, +0x020,0x00000037, +0x01f,0x00000011, +0x020,0x000000fb, +0x01f,0x00000012, +0x020,0x000000db, +0x01f,0x00000013, +0x020,0x000000bb, +0x01f,0x00000014, +0x020,0x000000ff, +0x01f,0x00000015, +0x020,0x000000e3, +0x01f,0x00000016, +0x020,0x000000c3, +0x01f,0x00000017, +0x020,0x000000a3, +0x01f,0x00000018, +0x020,0x00000083, +0x01f,0x00000019, +0x020,0x00000063, +0x01f,0x0000001a, +0x020,0x00000043, +0x01f,0x0000001b, +0x020,0x00000023, +0x01f,0x0000001c, +0x020,0x00000003, +0x01f,0x0000001d, +0x020,0x000001e3, +0x01f,0x0000001e, +0x020,0x000001c3, +0x01f,0x0000001f, +0x020,0x000001a3, +0x01f,0x00000020, +0x020,0x00000183, +0x01f,0x00000021, +0x020,0x00000163, +0x01f,0x00000022, +0x020,0x00000143, +0x01f,0x00000023, +0x020,0x00000123, +0x01f,0x00000024, +0x020,0x00000103, +0x023,0x00000203, +0x024,0x00000200, +0x00b,0x000001ba, +0x02c,0x000003d7, +0x02d,0x00000ff0, +0x000,0x00000037, +0x004,0x00000160, +0x007,0x00000080, +0x002,0x0000088d, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x000,0x000000bf, +0x00d,0x0000001f, +0x00d,0x00000c9f, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +u32 Rtl8190PciRadioB_Array[RadioB_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x000006e0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x000,0x000000b7, +0x00a,0x00000850, +0x000,0x000000bf, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000e00, +0x01b,0x00000f5e, +0x01d,0x00000607, +0x01e,0x000006cc, +0x00b,0x000001ba, +0x023,0x00000203, +0x024,0x00000200, +0x000,0x00000037, +0x004,0x00000160, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x00d,0x00000ccc, +0x000,0x000000bf, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +u32 Rtl8190PciRadioC_Array[RadioC_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x00000ee0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x009,0x000007f0, +0x00a,0x000009d0, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x00f,0x00000990, +0x012,0x00000806, +0x014,0x000005ab, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000f80, +0x01b,0x00000f5e, +0x01c,0x00000008, +0x01d,0x00000607, +0x01e,0x000006cc, +0x01f,0x00000000, +0x020,0x000001a5, +0x01f,0x00000001, +0x020,0x00000165, +0x01f,0x00000002, +0x020,0x000000c6, +0x01f,0x00000003, +0x020,0x00000086, +0x01f,0x00000004, +0x020,0x00000046, +0x01f,0x00000005, +0x020,0x000001e6, +0x01f,0x00000006, +0x020,0x000001a6, +0x01f,0x00000007, +0x020,0x00000166, +0x01f,0x00000008, +0x020,0x000000c7, +0x01f,0x00000009, +0x020,0x00000087, +0x01f,0x0000000a, +0x020,0x000000f7, +0x01f,0x0000000b, +0x020,0x000000d7, +0x01f,0x0000000c, +0x020,0x000000b7, +0x01f,0x0000000d, +0x020,0x00000097, +0x01f,0x0000000e, +0x020,0x00000077, +0x01f,0x0000000f, +0x020,0x00000057, +0x01f,0x00000010, +0x020,0x00000037, +0x01f,0x00000011, +0x020,0x000000fb, +0x01f,0x00000012, +0x020,0x000000db, +0x01f,0x00000013, +0x020,0x000000bb, +0x01f,0x00000014, +0x020,0x000000ff, +0x01f,0x00000015, +0x020,0x000000e3, +0x01f,0x00000016, +0x020,0x000000c3, +0x01f,0x00000017, +0x020,0x000000a3, +0x01f,0x00000018, +0x020,0x00000083, +0x01f,0x00000019, +0x020,0x00000063, +0x01f,0x0000001a, +0x020,0x00000043, +0x01f,0x0000001b, +0x020,0x00000023, +0x01f,0x0000001c, +0x020,0x00000003, +0x01f,0x0000001d, +0x020,0x000001e3, +0x01f,0x0000001e, +0x020,0x000001c3, +0x01f,0x0000001f, +0x020,0x000001a3, +0x01f,0x00000020, +0x020,0x00000183, +0x01f,0x00000021, +0x020,0x00000163, +0x01f,0x00000022, +0x020,0x00000143, +0x01f,0x00000023, +0x020,0x00000123, +0x01f,0x00000024, +0x020,0x00000103, +0x023,0x00000203, +0x024,0x00000200, +0x00b,0x000001ba, +0x02c,0x000003d7, +0x02d,0x00000ff0, +0x000,0x00000037, +0x004,0x00000160, +0x007,0x00000080, +0x002,0x0000088d, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x000,0x000000bf, +0x00d,0x0000001f, +0x00d,0x00000c9f, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +u32 Rtl8190PciRadioD_Array[RadioD_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x000006e0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x000,0x000000b7, +0x00a,0x00000850, +0x000,0x000000bf, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000e00, +0x01b,0x00000f5e, +0x01d,0x00000607, +0x01e,0x000006cc, +0x00b,0x000001ba, +0x023,0x00000203, +0x024,0x00000200, +0x000,0x00000037, +0x004,0x00000160, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x00d,0x00000ccc, +0x000,0x000000bf, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +#endif +#ifdef RTL8192E +u32 Rtl8192PciEMACPHY_Array[] = { +0x03c,0xffff0000,0x00000f0f, +0x340,0xffffffff,0x161a1a1a, +0x344,0xffffffff,0x12121416, +0x348,0x0000ffff,0x00001818, +0x12c,0xffffffff,0x04000802, +0x318,0x00000fff,0x00000100, +}; +u32 Rtl8192PciEMACPHY_Array_PG[] = { +0x03c,0xffff0000,0x00000f0f, +0xe00,0xffffffff,0x06090909, +0xe04,0xffffffff,0x00030306, +0xe08,0x0000ff00,0x00000000, +0xe10,0xffffffff,0x0a0c0d0f, +0xe14,0xffffffff,0x06070809, +0xe18,0xffffffff,0x0a0c0d0f, +0xe1c,0xffffffff,0x06070809, +0x12c,0xffffffff,0x04000802, +0x318,0x00000fff,0x00000800, +}; +u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLength] = { +0xc78,0x7d000001, +0xc78,0x7d010001, +0xc78,0x7d020001, +0xc78,0x7d030001, +0xc78,0x7d040001, +0xc78,0x7d050001, +0xc78,0x7c060001, +0xc78,0x7b070001, +0xc78,0x7a080001, +0xc78,0x79090001, +0xc78,0x780a0001, +0xc78,0x770b0001, +0xc78,0x760c0001, +0xc78,0x750d0001, +0xc78,0x740e0001, +0xc78,0x730f0001, +0xc78,0x72100001, +0xc78,0x71110001, +0xc78,0x70120001, +0xc78,0x6f130001, +0xc78,0x6e140001, +0xc78,0x6d150001, +0xc78,0x6c160001, +0xc78,0x6b170001, +0xc78,0x6a180001, +0xc78,0x69190001, +0xc78,0x681a0001, +0xc78,0x671b0001, +0xc78,0x661c0001, +0xc78,0x651d0001, +0xc78,0x641e0001, +0xc78,0x491f0001, +0xc78,0x48200001, +0xc78,0x47210001, +0xc78,0x46220001, +0xc78,0x45230001, +0xc78,0x44240001, +0xc78,0x43250001, +0xc78,0x28260001, +0xc78,0x27270001, +0xc78,0x26280001, +0xc78,0x25290001, +0xc78,0x242a0001, +0xc78,0x232b0001, +0xc78,0x222c0001, +0xc78,0x212d0001, +0xc78,0x202e0001, +0xc78,0x0a2f0001, +0xc78,0x08300001, +0xc78,0x06310001, +0xc78,0x05320001, +0xc78,0x04330001, +0xc78,0x03340001, +0xc78,0x02350001, +0xc78,0x01360001, +0xc78,0x00370001, +0xc78,0x00380001, +0xc78,0x00390001, +0xc78,0x003a0001, +0xc78,0x003b0001, +0xc78,0x003c0001, +0xc78,0x003d0001, +0xc78,0x003e0001, +0xc78,0x003f0001, +0xc78,0x7d400001, +0xc78,0x7d410001, +0xc78,0x7d420001, +0xc78,0x7d430001, +0xc78,0x7d440001, +0xc78,0x7d450001, +0xc78,0x7c460001, +0xc78,0x7b470001, +0xc78,0x7a480001, +0xc78,0x79490001, +0xc78,0x784a0001, +0xc78,0x774b0001, +0xc78,0x764c0001, +0xc78,0x754d0001, +0xc78,0x744e0001, +0xc78,0x734f0001, +0xc78,0x72500001, +0xc78,0x71510001, +0xc78,0x70520001, +0xc78,0x6f530001, +0xc78,0x6e540001, +0xc78,0x6d550001, +0xc78,0x6c560001, +0xc78,0x6b570001, +0xc78,0x6a580001, +0xc78,0x69590001, +0xc78,0x685a0001, +0xc78,0x675b0001, +0xc78,0x665c0001, +0xc78,0x655d0001, +0xc78,0x645e0001, +0xc78,0x495f0001, +0xc78,0x48600001, +0xc78,0x47610001, +0xc78,0x46620001, +0xc78,0x45630001, +0xc78,0x44640001, +0xc78,0x43650001, +0xc78,0x28660001, +0xc78,0x27670001, +0xc78,0x26680001, +0xc78,0x25690001, +0xc78,0x246a0001, +0xc78,0x236b0001, +0xc78,0x226c0001, +0xc78,0x216d0001, +0xc78,0x206e0001, +0xc78,0x0a6f0001, +0xc78,0x08700001, +0xc78,0x06710001, +0xc78,0x05720001, +0xc78,0x04730001, +0xc78,0x03740001, +0xc78,0x02750001, +0xc78,0x01760001, +0xc78,0x00770001, +0xc78,0x00780001, +0xc78,0x00790001, +0xc78,0x007a0001, +0xc78,0x007b0001, +0xc78,0x007c0001, +0xc78,0x007d0001, +0xc78,0x007e0001, +0xc78,0x007f0001, +0xc78,0x2e00001e, +0xc78,0x2e01001e, +0xc78,0x2e02001e, +0xc78,0x2e03001e, +0xc78,0x2e04001e, +0xc78,0x2e05001e, +0xc78,0x3006001e, +0xc78,0x3407001e, +0xc78,0x3908001e, +0xc78,0x3c09001e, +0xc78,0x3f0a001e, +0xc78,0x420b001e, +0xc78,0x440c001e, +0xc78,0x450d001e, +0xc78,0x460e001e, +0xc78,0x460f001e, +0xc78,0x4710001e, +0xc78,0x4811001e, +0xc78,0x4912001e, +0xc78,0x4a13001e, +0xc78,0x4b14001e, +0xc78,0x4b15001e, +0xc78,0x4c16001e, +0xc78,0x4d17001e, +0xc78,0x4e18001e, +0xc78,0x4f19001e, +0xc78,0x4f1a001e, +0xc78,0x501b001e, +0xc78,0x511c001e, +0xc78,0x521d001e, +0xc78,0x521e001e, +0xc78,0x531f001e, +0xc78,0x5320001e, +0xc78,0x5421001e, +0xc78,0x5522001e, +0xc78,0x5523001e, +0xc78,0x5624001e, +0xc78,0x5725001e, +0xc78,0x5726001e, +0xc78,0x5827001e, +0xc78,0x5828001e, +0xc78,0x5929001e, +0xc78,0x592a001e, +0xc78,0x5a2b001e, +0xc78,0x5b2c001e, +0xc78,0x5c2d001e, +0xc78,0x5c2e001e, +0xc78,0x5d2f001e, +0xc78,0x5e30001e, +0xc78,0x5f31001e, +0xc78,0x6032001e, +0xc78,0x6033001e, +0xc78,0x6134001e, +0xc78,0x6235001e, +0xc78,0x6336001e, +0xc78,0x6437001e, +0xc78,0x6438001e, +0xc78,0x6539001e, +0xc78,0x663a001e, +0xc78,0x673b001e, +0xc78,0x673c001e, +0xc78,0x683d001e, +0xc78,0x693e001e, +0xc78,0x6a3f001e, +}; +u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLength] = { +0x0, }; +u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = { +0x800,0x00000000, +0x804,0x00000001, +0x808,0x0000fc00, +0x80c,0x0000001c, +0x810,0x801010aa, +0x814,0x008514d0, +0x818,0x00000040, +0x81c,0x00000000, +0x820,0x00000004, +0x824,0x00690000, +0x828,0x00000004, +0x82c,0x00e90000, +0x830,0x00000004, +0x834,0x00690000, +0x838,0x00000004, +0x83c,0x00e90000, +0x840,0x00000000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x65a965a9, +0x85c,0x65a965a9, +0x860,0x001f0010, +0x864,0x007f0010, +0x868,0x001f0010, +0x86c,0x007f0010, +0x870,0x0f100f70, +0x874,0x0f100f70, +0x878,0x00000000, +0x87c,0x00000000, +0x880,0x6870e36c, +0x884,0xe3573600, +0x888,0x4260c340, +0x88c,0x0000ff00, +0x890,0x00000000, +0x894,0xfffffffe, +0x898,0x4c42382f, +0x89c,0x00656056, +0x8b0,0x00000000, +0x8e0,0x00000000, +0x8e4,0x00000000, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x31121311, +0xa00,0x00d0c7d8, +0xa04,0x811f0008, +0xa08,0x80cd8300, +0xa0c,0x2e62740f, +0xa10,0x95009b78, +0xa14,0x11145008, +0xa18,0x00881117, +0xa1c,0x89140fa0, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00000000, +0xc00,0x00000040, +0xc04,0x00005433, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08000000, +0xc1c,0x40000100, +0xc20,0x08000000, +0xc24,0x40000100, +0xc28,0x08000000, +0xc2c,0x40000100, +0xc30,0x6de9ac44, +0xc34,0x465c52cd, +0xc38,0x497f5994, +0xc3c,0x0a969764, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020000, +0xc4c,0x00000300, +0xc50,0x69543420, +0xc54,0x433c0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x69543420, +0xc64,0x433c0094, +0xc68,0x69543420, +0xc6c,0x433c0094, +0xc70,0x2c7f000d, +0xc74,0x0186175b, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x20000000, +0xc88,0x40000100, +0xc8c,0x20200000, +0xc90,0x40000100, +0xc94,0x00000000, +0xc98,0x40000100, +0xc9c,0x00000000, +0xca0,0x00492492, +0xca4,0x00000000, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x00492492, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xd00,0x00000750, +0xd04,0x00000403, +0xd08,0x0000907f, +0xd0c,0x00000001, +0xd10,0xa0633333, +0xd14,0x33333c63, +0xd18,0x6a8f5b6b, +0xd1c,0x00000000, +0xd20,0x00000000, +0xd24,0x00000000, +0xd28,0x00000000, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x00000000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x024dbd02, +0xd58,0x00000000, +0xd5c,0x04032064, +0xe00,0x161a1a1a, +0xe04,0x12121416, +0xe08,0x00001800, +0xe0c,0x00000000, +0xe10,0x161a1a1a, +0xe14,0x12121416, +0xe18,0x161a1a1a, +0xe1c,0x12121416, +}; +u32 Rtl8192PciERadioA_Array[RadioA_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x00000ee0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x009,0x000007f0, +0x00a,0x000009d0, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x00f,0x00000990, +0x012,0x00000806, +0x014,0x000005ab, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000f80, +0x01b,0x00000f5e, +0x01c,0x00000008, +0x01d,0x00000607, +0x01e,0x000006cc, +0x01f,0x00000000, +0x020,0x000001a5, +0x01f,0x00000001, +0x020,0x00000165, +0x01f,0x00000002, +0x020,0x000000c6, +0x01f,0x00000003, +0x020,0x00000086, +0x01f,0x00000004, +0x020,0x00000046, +0x01f,0x00000005, +0x020,0x000001e6, +0x01f,0x00000006, +0x020,0x000001a6, +0x01f,0x00000007, +0x020,0x00000166, +0x01f,0x00000008, +0x020,0x000000c7, +0x01f,0x00000009, +0x020,0x00000087, +0x01f,0x0000000a, +0x020,0x000000f7, +0x01f,0x0000000b, +0x020,0x000000d7, +0x01f,0x0000000c, +0x020,0x000000b7, +0x01f,0x0000000d, +0x020,0x00000097, +0x01f,0x0000000e, +0x020,0x00000077, +0x01f,0x0000000f, +0x020,0x00000057, +0x01f,0x00000010, +0x020,0x00000037, +0x01f,0x00000011, +0x020,0x000000fb, +0x01f,0x00000012, +0x020,0x000000db, +0x01f,0x00000013, +0x020,0x000000bb, +0x01f,0x00000014, +0x020,0x000000ff, +0x01f,0x00000015, +0x020,0x000000e3, +0x01f,0x00000016, +0x020,0x000000c3, +0x01f,0x00000017, +0x020,0x000000a3, +0x01f,0x00000018, +0x020,0x00000083, +0x01f,0x00000019, +0x020,0x00000063, +0x01f,0x0000001a, +0x020,0x00000043, +0x01f,0x0000001b, +0x020,0x00000023, +0x01f,0x0000001c, +0x020,0x00000003, +0x01f,0x0000001d, +0x020,0x000001e3, +0x01f,0x0000001e, +0x020,0x000001c3, +0x01f,0x0000001f, +0x020,0x000001a3, +0x01f,0x00000020, +0x020,0x00000183, +0x01f,0x00000021, +0x020,0x00000163, +0x01f,0x00000022, +0x020,0x00000143, +0x01f,0x00000023, +0x020,0x00000123, +0x01f,0x00000024, +0x020,0x00000103, +0x023,0x00000203, +0x024,0x00000100, +0x00b,0x000001ba, +0x02c,0x000003d7, +0x02d,0x00000ff0, +0x000,0x00000037, +0x004,0x00000160, +0x007,0x00000080, +0x002,0x0000088d, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x000,0x000000bf, +0x00d,0x0000001f, +0x00d,0x00000c9f, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +u32 Rtl8192PciERadioB_Array[RadioB_ArrayLength] = { +0x019,0x00000003, +0x000,0x000000bf, +0x001,0x000006e0, +0x002,0x0000004c, +0x003,0x000007f1, +0x004,0x00000975, +0x005,0x00000c58, +0x006,0x00000ae6, +0x007,0x000000ca, +0x008,0x00000e1c, +0x000,0x000000b7, +0x00a,0x00000850, +0x000,0x000000bf, +0x00b,0x000001ba, +0x00c,0x00000240, +0x00e,0x00000020, +0x015,0x00000f80, +0x016,0x00000020, +0x017,0x00000597, +0x018,0x0000050a, +0x01a,0x00000e00, +0x01b,0x00000f5e, +0x01d,0x00000607, +0x01e,0x000006cc, +0x00b,0x000001ba, +0x023,0x00000203, +0x024,0x00000100, +0x000,0x00000037, +0x004,0x00000160, +0x016,0x00000200, +0x016,0x00000380, +0x016,0x00000020, +0x016,0x000001a0, +0x00d,0x00000ccc, +0x000,0x000000bf, +0x002,0x0000004d, +0x000,0x00000cbf, +0x004,0x00000975, +0x007,0x00000700, +}; +u32 Rtl8192PciERadioC_Array[RadioC_ArrayLength] = { +0x0, }; +u32 Rtl8192PciERadioD_Array[RadioD_ArrayLength] = { +0x0, }; +#endif + +/*************************Define local function prototype**********************/ + +static u32 phy_FwRFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset); +static void phy_FwRFSerialWrite(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset,u32 Data); +/*************************Define local function prototype**********************/ +/****************************************************************************** + *function: This function read BB parameters from Header file we gen, + * and do register read/write + * input: u32 dwBitMask //taget bit pos in the addr to be modified + * output: none + * return: u32 return the shift bit bit position of the mask + * ****************************************************************************/ +u32 rtl8192_CalculateBitShift(u32 dwBitMask) +{ + u32 i; + for (i=0; i<=31; i++) + { + if (((dwBitMask>>i)&0x1) == 1) + break; + } + return i; +} +/****************************************************************************** + *function: This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false. + * input: none + * output: none + * return: 0(illegal, false), 1(legal,true) + * ***************************************************************************/ +u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) +{ + u8 ret = 1; + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef RTL8190P + if(priv->rf_type == RF_2T4R) + { + ret= 1; + } + else if (priv->rf_type == RF_1T2R) + { + if(eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B) + ret = 0; + else if(eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) + ret = 1; + } +#else + #ifdef RTL8192E + if (priv->rf_type == RF_2T4R) + ret = 0; + else if (priv->rf_type == RF_1T2R) + { + if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B) + ret = 1; + else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) + ret = 0; + } + #endif +#endif + return ret; +} +/****************************************************************************** + *function: This function set specific bits to BB register + * input: net_device dev + * u32 dwRegAddr //target addr to be modified + * u32 dwBitMask //taget bit pos in the addr to be modified + * u32 dwData //value to be write + * output: none + * return: none + * notice: + * ****************************************************************************/ +void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData) +{ + + u32 OriginalValue, BitShift, NewValue; + + if(dwBitMask!= bMaskDWord) + {//if not "double word" write + OriginalValue = read_nic_dword(dev, dwRegAddr); + BitShift = rtl8192_CalculateBitShift(dwBitMask); + NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift)); + write_nic_dword(dev, dwRegAddr, NewValue); + }else + write_nic_dword(dev, dwRegAddr, dwData); + return; +} +/****************************************************************************** + *function: This function reads specific bits from BB register + * input: net_device dev + * u32 dwRegAddr //target addr to be readback + * u32 dwBitMask //taget bit pos in the addr to be readback + * output: none + * return: u32 Data //the readback register value + * notice: + * ****************************************************************************/ +u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask) +{ + u32 Ret = 0, OriginalValue, BitShift; + + OriginalValue = read_nic_dword(dev, dwRegAddr); + BitShift = rtl8192_CalculateBitShift(dwBitMask); + Ret = (OriginalValue & dwBitMask) >> BitShift; + + return (Ret); +} +/****************************************************************************** + *function: This function read register from RF chip + * input: net_device dev + * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D + * u32 Offset //target address to be read + * output: none + * return: u32 readback value + * notice: There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information. + * ****************************************************************************/ +u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 ret = 0; + u32 NewOffset = 0; + BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath]; + //rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0); + //make sure RF register offset is correct + Offset &= 0x3f; + + //switch page for 8256 RF IC + if (priv->rf_chip == RF_8256) + { +#ifdef RTL8190P + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] +#else + #ifdef RTL8192E + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + #endif +#endif + if (Offset >= 31) + { + priv->RfReg0Value[eRFPath] |= 0x140; + //Switch to Reg_Mode2 for Reg 31-45 + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + //modify offset + NewOffset = Offset -30; + } + else if (Offset >= 16) + { + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + //Switch to Reg_Mode 1 for Reg16-30 + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + + NewOffset = Offset - 15; + } + else + NewOffset = Offset; + } + else + { + RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n"); + NewOffset = Offset; + } + //put desired read addr to LSSI control Register + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset); + //Issue a posedge trigger + // + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); + + + // TODO: we should not delay such a long time. Ask help from SD3 + msleep(1); + + ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); + + + // Switch back to Reg_Mode0; + if(priv->rf_chip == RF_8256) + { + priv->RfReg0Value[eRFPath] &= 0xebf; + + rtl8192_setBBreg( + dev, + pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + +#ifdef RTL8190P + if(priv->rf_type == RF_2T4R) + { + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] + } + else if(priv->rf_type == RF_1T2R) + { + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] + } +#else + #ifdef RTL8192E + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + #endif +#endif + } + + + return ret; + +} + +/****************************************************************************** + *function: This function write data to RF register + * input: net_device dev + * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D + * u32 Offset //target address to be written + * u32 Data //The new register data to be written + * output: none + * return: none + * notice: For RF8256 only. + =========================================================== + *Reg Mode RegCTL[1] RegCTL[0] Note + * (Reg00[12]) (Reg00[10]) + *=========================================================== + *Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) + *------------------------------------------------------------------ + *Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) + *------------------------------------------------------------------ + * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) + *------------------------------------------------------------------ + * ****************************************************************************/ +void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 DataAndAddr = 0, NewOffset = 0; + BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; + + Offset &= 0x3f; + if (priv->rf_chip == RF_8256) + { + +#ifdef RTL8190P + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] +#else + #ifdef RTL8192E + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + #endif +#endif + + if (Offset >= 31) + { + priv->RfReg0Value[eRFPath] |= 0x140; + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); + NewOffset = Offset - 30; + } + else if (Offset >= 16) + { + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); + NewOffset = Offset - 15; + } + else + NewOffset = Offset; + } + else + { + RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n"); + NewOffset = Offset; + } + + // Put write addr in [5:0] and write data in [31:16] + DataAndAddr = (Data<<16) | (NewOffset&0x3f); + + // Write Operation + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); + + + if(Offset==0x0) + priv->RfReg0Value[eRFPath] = Data; + + // Switch back to Reg_Mode0; + if(priv->rf_chip == RF_8256) + { + if(Offset != 0) + { + priv->RfReg0Value[eRFPath] &= 0xebf; + rtl8192_setBBreg( + dev, + pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + } +#ifdef RTL8190P + if(priv->rf_type == RF_2T4R) + { + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] + } + else if(priv->rf_type == RF_1T2R) + { + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] + } +#else + #ifdef RTL8192E + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + #endif +#endif + } + + return; +} + +/****************************************************************************** + *function: This function set specific bits to RF register + * input: net_device dev + * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D + * u32 RegAddr //target addr to be modified + * u32 BitMask //taget bit pos in the addr to be modified + * u32 Data //value to be write + * output: none + * return: none + * notice: + * ****************************************************************************/ +void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 Original_Value, BitShift, New_Value; +// u8 time = 0; + + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + return; +#ifdef RTL8192E + if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) + return; +#endif + //spin_lock_irqsave(&priv->rf_lock, flags); + //down(&priv->rf_sem); + + RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n"); + if (priv->Rf_Mode == RF_OP_By_FW) + { + if (BitMask != bMask12Bits) // RF data is 12 bits only + { + Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr); + BitShift = rtl8192_CalculateBitShift(BitMask); + New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); + + phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value); + }else + phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data); + udelay(200); + + } + else + { + if (BitMask != bMask12Bits) // RF data is 12 bits only + { + Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr); + BitShift = rtl8192_CalculateBitShift(BitMask); + New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); + + rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value); + }else + rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data); + } + //spin_unlock_irqrestore(&priv->rf_lock, flags); + //up(&priv->rf_sem); + return; +} + +/****************************************************************************** + *function: This function reads specific bits from RF register + * input: net_device dev + * u32 RegAddr //target addr to be readback + * u32 BitMask //taget bit pos in the addr to be readback + * output: none + * return: u32 Data //the readback register value + * notice: + * ****************************************************************************/ +u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask) +{ + u32 Original_Value, Readback_Value, BitShift; + struct r8192_priv *priv = ieee80211_priv(dev); + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + return 0; +#ifdef RTL8192E + if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) + return 0; +#endif + down(&priv->rf_sem); + if (priv->Rf_Mode == RF_OP_By_FW) + { + Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr); + udelay(200); + } + else + { + Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr); + + } + BitShift = rtl8192_CalculateBitShift(BitMask); + Readback_Value = (Original_Value & BitMask) >> BitShift; + up(&priv->rf_sem); +// udelay(200); + return (Readback_Value); +} + +/****************************************************************************** + *function: We support firmware to execute RF-R/W. + * input: dev + * output: none + * return: none + * notice: + * ***************************************************************************/ +static u32 phy_FwRFSerialRead( + struct net_device* dev, + RF90_RADIO_PATH_E eRFPath, + u32 Offset ) +{ + u32 retValue = 0; + u32 Data = 0; + u8 time = 0; + //DbgPrint("FW RF CTRL\n\r"); + /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can + not execute the scheme in the initial step. Otherwise, RF-R/W will waste + much time. This is only for site survey. */ + // 1. Read operation need not insert data. bit 0-11 + //Data &= bMask12Bits; + // 2. Write RF register address. Bit 12-19 + Data |= ((Offset&0xFF)<<12); + // 3. Write RF path. bit 20-21 + Data |= ((eRFPath&0x3)<<20); + // 4. Set RF read indicator. bit 22=0 + //Data |= 0x00000; + // 5. Trigger Fw to operate the command. bit 31 + Data |= 0x80000000; + // 6. We can not execute read operation if bit 31 is 1. + while (read_nic_dword(dev, QPNR)&0x80000000) + { + // If FW can not finish RF-R/W for more than ?? times. We must reset FW. + if (time++ < 100) + { + //DbgPrint("FW not finish RF-R Time=%d\n\r", time); + udelay(10); + } + else + break; + } + // 7. Execute read operation. + write_nic_dword(dev, QPNR, Data); + // 8. Check if firmawre send back RF content. + while (read_nic_dword(dev, QPNR)&0x80000000) + { + // If FW can not finish RF-R/W for more than ?? times. We must reset FW. + if (time++ < 100) + { + //DbgPrint("FW not finish RF-W Time=%d\n\r", time); + udelay(10); + } + else + return (0); + } + retValue = read_nic_dword(dev, RF_DATA); + + return (retValue); + +} /* phy_FwRFSerialRead */ + +/****************************************************************************** + *function: We support firmware to execute RF-R/W. + * input: dev + * output: none + * return: none + * notice: + * ***************************************************************************/ +static void +phy_FwRFSerialWrite( + struct net_device* dev, + RF90_RADIO_PATH_E eRFPath, + u32 Offset, + u32 Data ) +{ + u8 time = 0; + + //DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data); + /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can + not execute the scheme in the initial step. Otherwise, RF-R/W will waste + much time. This is only for site survey. */ + + // 1. Set driver write bit and 12 bit data. bit 0-11 + //Data &= bMask12Bits; // Done by uper layer. + // 2. Write RF register address. bit 12-19 + Data |= ((Offset&0xFF)<<12); + // 3. Write RF path. bit 20-21 + Data |= ((eRFPath&0x3)<<20); + // 4. Set RF write indicator. bit 22=1 + Data |= 0x400000; + // 5. Trigger Fw to operate the command. bit 31=1 + Data |= 0x80000000; + + // 6. Write operation. We can not write if bit 31 is 1. + while (read_nic_dword(dev, QPNR)&0x80000000) + { + // If FW can not finish RF-R/W for more than ?? times. We must reset FW. + if (time++ < 100) + { + //DbgPrint("FW not finish RF-W Time=%d\n\r", time); + udelay(10); + } + else + break; + } + // 7. No matter check bit. We always force the write. Because FW will + // not accept the command. + write_nic_dword(dev, QPNR, Data); + /* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware + to finish RF write operation. */ + /* 2008/01/17 MH We support delay in firmware side now. */ + //delay_us(20); + +} /* phy_FwRFSerialWrite */ + + +/****************************************************************************** + *function: This function read BB parameters from Header file we gen, + * and do register read/write + * input: dev + * output: none + * return: none + * notice: BB parameters may change all the time, so please make + * sure it has been synced with the newest. + * ***************************************************************************/ +void rtl8192_phy_configmac(struct net_device* dev) +{ + u32 dwArrayLen = 0, i = 0; + u32* pdwArray = NULL; + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef TO_DO_LIST +if(Adapter->bInHctTest) + { + RT_TRACE(COMP_PHY, "Rtl819XMACPHY_ArrayDTM\n"); + dwArrayLen = MACPHY_ArrayLengthDTM; + pdwArray = Rtl819XMACPHY_ArrayDTM; + } + else if(priv->bTXPowerDataReadFromEEPORM) +#endif + if(priv->bTXPowerDataReadFromEEPORM) + { + RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n"); + dwArrayLen = MACPHY_Array_PGLength; + pdwArray = Rtl819XMACPHY_Array_PG; + + } + else + { + RT_TRACE(COMP_PHY,"Read rtl819XMACPHY_Array\n"); + dwArrayLen = MACPHY_ArrayLength; + pdwArray = Rtl819XMACPHY_Array; + } + for(i = 0; ibInHctTest) + { + AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM; + + if(priv->RF_Type == RF_2T4R) + { + PHY_REGArrayLen = PHY_REGArrayLengthDTM; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArrayDTM; + } + else if (priv->RF_Type == RF_1T2R) + { + PHY_REGArrayLen = PHY_REG_1T2RArrayLengthDTM; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArrayDTM; + } + } + else +#endif + { + AGCTAB_ArrayLen = AGCTAB_ArrayLength; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array; + if(priv->rf_type == RF_2T4R) + { + PHY_REGArrayLen = PHY_REGArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArray; + } + else if (priv->rf_type == RF_1T2R) + { + PHY_REGArrayLen = PHY_REG_1T2RArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArray; + } + } + + if (ConfigType == BaseBand_Config_PHY_REG) + { + for (i=0; iPHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 + priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) + priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874 + priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) + + // RF Interface Readback Value + priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0 + priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) + priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4 + priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) + + // RF Interface Output (and Enable) + priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860 + priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864 + priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868 + priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C + + // RF Interface (Output and) Enable + priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) + priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) + priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) + priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) + + //Addr of LSSI. Wirte RF register by driver + priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter + priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; + priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; + priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter; + + // RF parameter + priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select + priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; + priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; + priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; + + // Tx AGC Gain Stage (same for all path. Should we remove this?) + priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + + // Tranceiver A~D HSSI Parameter-1 + priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1 + priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1 + priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1 + priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1 + + // Tranceiver A~D HSSI Parameter-2 + priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2 + priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2 + priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2 + priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1 + + // RF switch Control + priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control + priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; + priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; + priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; + + // AGC control 1 + priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; + priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; + priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; + priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; + + // AGC control 2 + priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; + priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; + priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; + priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; + + // RX AFE control 1 + priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; + priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; + priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; + priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; + + // RX AFE control 1 + priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE; + priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; + priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; + priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; + + // Tx AFE control 1 + priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; + priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; + priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; + priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; + + // Tx AFE control 2 + priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE; + priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; + priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; + priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; + + // Tranceiver LSSI Readback + priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; + +} +/****************************************************************************** + *function: This function is to write register and then readback to make sure whether BB and RF is OK + * input: net_device dev + * HW90_BLOCK_E CheckBlock + * RF90_RADIO_PATH_E eRFPath //only used when checkblock is HW90_BLOCK_RF + * output: none + * return: return whether BB and RF is ok(0:OK; 1:Fail) + * notice: This function may be removed in the ASIC + * ***************************************************************************/ +RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath) +{ + //struct r8192_priv *priv = ieee80211_priv(dev); +// BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; + RT_STATUS ret = RT_STATUS_SUCCESS; + u32 i, CheckTimes = 4, dwRegRead = 0; + u32 WriteAddr[4]; + u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; + // Initialize register address offset to be checked + WriteAddr[HW90_BLOCK_MAC] = 0x100; + WriteAddr[HW90_BLOCK_PHY0] = 0x900; + WriteAddr[HW90_BLOCK_PHY1] = 0x800; + WriteAddr[HW90_BLOCK_RF] = 0x3; + RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock); + for(i=0 ; i < CheckTimes ; i++) + { + + // + // Write Data to register and readback + // + switch(CheckBlock) + { + case HW90_BLOCK_MAC: + RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!"); + break; + + case HW90_BLOCK_PHY0: + case HW90_BLOCK_PHY1: + write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]); + dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]); + break; + + case HW90_BLOCK_RF: + WriteData[i] &= 0xfff; + rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]); + // TODO: we should not delay for such a long time. Ask SD3 + mdelay(10); + dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord); + mdelay(10); + break; + + default: + ret = RT_STATUS_FAILURE; + break; + } + + + // + // Check whether readback data is correct + // + if(dwRegRead != WriteData[i]) + { + RT_TRACE(COMP_ERR, "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]); + ret = RT_STATUS_FAILURE; + break; + } + } + + return ret; +} + + +/****************************************************************************** + *function: This function initialize BB&RF + * input: net_device dev + * output: none + * return: none + * notice: Initialization value may change all the time, so please make + * sure it has been synced with the newest. + * ***************************************************************************/ +RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + u8 bRegValue = 0, eCheckItem = 0; + u32 dwRegValue = 0; + /************************************** + //<1>Initialize BaseBand + **************************************/ + + /*--set BB Global Reset--*/ + bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET); + write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT)); + + /*---set BB reset Active---*/ + dwRegValue = read_nic_dword(dev, CPU_GEN); + write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST))); + + /*----Ckeck FPGAPHY0 and PHY1 board is OK----*/ + // TODO: this function should be removed on ASIC , Emily 2007.2.2 + for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++) + { + rtStatus = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path + if(rtStatus != RT_STATUS_SUCCESS) + { + RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1); + return rtStatus; + } + } + /*---- Set CCK and OFDM Block "OFF"----*/ + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); + /*----BB Register Initilazation----*/ + //==m==>Set PHY REG From Header<==m== + rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG); + + /*----Set BB reset de-Active----*/ + dwRegValue = read_nic_dword(dev, CPU_GEN); + write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST)); + + /*----BB AGC table Initialization----*/ + //==m==>Set PHY REG From Header<==m== + rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB); + + if (priv->card_8192_version > VERSION_8190_BD) + { + if(priv->rf_type == RF_2T4R) + { + // Antenna gain offset from B/C/D to A + dwRegValue = ( priv->AntennaTxPwDiff[2]<<8 | + priv->AntennaTxPwDiff[1]<<4 | + priv->AntennaTxPwDiff[0]); + } + else + dwRegValue = 0x0; //Antenna gain offset doesn't make sense in RF 1T2R. + rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), dwRegValue); + + + //XSTALLCap +#ifdef RTL8190P + dwRegValue = priv->CrystalCap & 0x3; // bit0~1 of crystal cap + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap01, dwRegValue); + dwRegValue = ((priv->CrystalCap & 0xc)>>2); // bit2~3 of crystal cap + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, bXtalCap23, dwRegValue); +#else + #ifdef RTL8192E + dwRegValue = priv->CrystalCap; + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue); + #endif +#endif + + } + + // Check if the CCK HighPower is turned ON. + // This is used to calculate PWDB. +// priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200)); + return rtStatus; +} +/****************************************************************************** + *function: This function initialize BB&RF + * input: net_device dev + * output: none + * return: none + * notice: Initialization value may change all the time, so please make + * sure it has been synced with the newest. + * ***************************************************************************/ +RT_STATUS rtl8192_BBConfig(struct net_device* dev) +{ + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + rtl8192_InitBBRFRegDef(dev); + //config BB&RF. As hardCode based initialization has not been well + //implemented, so use file first.FIXME:should implement it for hardcode? + rtStatus = rtl8192_BB_Config_ParaFile(dev); + return rtStatus; +} + +/****************************************************************************** + *function: This function obtains the initialization value of Tx power Level offset + * input: net_device dev + * output: none + * return: none + * ***************************************************************************/ +void rtl8192_phy_getTxPower(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef RTL8190P + priv->MCSTxPowerLevelOriginalOffset[0] = + read_nic_dword(dev, MCS_TXAGC); + priv->MCSTxPowerLevelOriginalOffset[1] = + read_nic_dword(dev, (MCS_TXAGC+4)); + priv->CCKTxPowerLevelOriginalOffset = + read_nic_dword(dev, CCK_TXAGC); +#else + #ifdef RTL8192E + priv->MCSTxPowerLevelOriginalOffset[0] = + read_nic_dword(dev, rTxAGC_Rate18_06); + priv->MCSTxPowerLevelOriginalOffset[1] = + read_nic_dword(dev, rTxAGC_Rate54_24); + priv->MCSTxPowerLevelOriginalOffset[2] = + read_nic_dword(dev, rTxAGC_Mcs03_Mcs00); + priv->MCSTxPowerLevelOriginalOffset[3] = + read_nic_dword(dev, rTxAGC_Mcs07_Mcs04); + priv->MCSTxPowerLevelOriginalOffset[4] = + read_nic_dword(dev, rTxAGC_Mcs11_Mcs08); + priv->MCSTxPowerLevelOriginalOffset[5] = + read_nic_dword(dev, rTxAGC_Mcs15_Mcs12); + #endif +#endif + + // read rx initial gain + priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1); + priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1); + priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1); + priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1); + RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n", + priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], + priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); + + // read framesync + priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3); + priv->framesyncC34 = read_nic_dword(dev, rOFDM0_RxDetector2); + RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n", + rOFDM0_RxDetector3, priv->framesync); + // read SIFS (save the value read fome MACPHY_REG.txt) + priv->SifsTime = read_nic_word(dev, SIFS); + return; +} + +/****************************************************************************** + *function: This function obtains the initialization value of Tx power Level offset + * input: net_device dev + * output: none + * return: none + * ***************************************************************************/ +void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u8 powerlevel = 0,powerlevelOFDM24G = 0; + char ant_pwr_diff; + u32 u4RegValue; + + if(priv->epromtype == EPROM_93c46) + { + powerlevel = priv->TxPowerLevelCCK[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; + } + else if(priv->epromtype == EPROM_93c56) + { + if(priv->rf_type == RF_1T2R) + { + powerlevel = priv->TxPowerLevelCCK_C[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_C[channel-1]; + } + else if(priv->rf_type == RF_2T4R) + { + // Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-C Tx + // Power must be calculated by the antenna diff. + // So we have to rewrite Antenna gain offset register here. + powerlevel = priv->TxPowerLevelCCK_A[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_A[channel-1]; + + ant_pwr_diff = priv->TxPowerLevelOFDM24G_C[channel-1] + -priv->TxPowerLevelOFDM24G_A[channel-1]; + ant_pwr_diff &= 0xf; + //DbgPrint(" ant_pwr_diff = 0x%x", (u8)(ant_pwr_diff)); + priv->RF_C_TxPwDiff = ant_pwr_diff; + + priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care + priv->AntennaTxPwDiff[1] = (u8)(ant_pwr_diff);// RF-C + priv->AntennaTxPwDiff[0] = 0;// RF-B, don't care + + // Antenna gain offset from B/C/D to A + u4RegValue = ( priv->AntennaTxPwDiff[2]<<8 | + priv->AntennaTxPwDiff[1]<<4 | + priv->AntennaTxPwDiff[0]); + + rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue); + } + } +#ifdef TODO + // + // CCX 2 S31, AP control of client transmit power: + // 1. We shall not exceed Cell Power Limit as possible as we can. + // 2. Tolerance is +/- 5dB. + // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit. + // + // TODO: + // 1. 802.11h power contraint + // + // 071011, by rcnjko. + // + if( pMgntInfo->OpMode == RT_OP_MODE_INFRASTRUCTURE && + pMgntInfo->bWithCcxCellPwr && + channel == pMgntInfo->dot11CurrentChannelNumber) + { + u8 CckCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr); + u8 LegacyOfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr); + u8 OfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, pMgntInfo->CcxCellPwr); + + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", + pMgntInfo->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx)); + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", + channel, powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G)); + + // CCK + if(powerlevel > CckCellPwrIdx) + powerlevel = CckCellPwrIdx; + // Legacy OFDM, HT OFDM + if(powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff > OfdmCellPwrIdx) + { + if((OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff) > 0) + { + powerlevelOFDM24G = OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff; + } + else + { + LegacyOfdmCellPwrIdx = 0; + } + } + + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n", + powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G)); + } + + pHalData->CurrentCckTxPwrIdx = powerlevel; + pHalData->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G; +#endif + switch(priv->rf_chip) + { + case RF_8225: + // PHY_SetRF8225CckTxPower(Adapter, powerlevel); + // PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G); + break; + case RF_8256: + PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + break; + case RF_8258: + break; + default: + RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", __FUNCTION__); + break; + } + return; +} + +/****************************************************************************** + *function: This function check Rf chip to do RF config + * input: net_device dev + * output: none + * return: only 8256 is supported + * ***************************************************************************/ +RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + switch(priv->rf_chip) + { + case RF_8225: +// rtStatus = PHY_RF8225_Config(Adapter); + break; + case RF_8256: + rtStatus = PHY_RF8256_Config(dev); + break; + + case RF_8258: + break; + case RF_PSEUDO_11N: + //rtStatus = PHY_RF8225_Config(Adapter); + break; + + default: + RT_TRACE(COMP_ERR, "error chip id\n"); + break; + } + return rtStatus; +} + +/****************************************************************************** + *function: This function update Initial gain + * input: net_device dev + * output: none + * return: As Windows has not implemented this, wait for complement + * ***************************************************************************/ +void rtl8192_phy_updateInitGain(struct net_device* dev) +{ + return; +} + +/****************************************************************************** + *function: This function read RF parameters from general head file, and do RF 3-wire + * input: net_device dev + * output: none + * return: return code show if RF configuration is successful(0:pass, 1:fail) + * Note: Delay may be required for RF configuration + * ***************************************************************************/ +u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath) +{ + + int i; + //u32* pRFArray; + u8 ret = 0; + + switch(eRFPath){ + case RF90_PATH_A: + for(i = 0;iTxPowerLevelCCK[channel-1]; + u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; + + switch(priv->rf_chip) + { + case RF_8225: +#ifdef TO_DO_LIST + PHY_SetRF8225CckTxPower(Adapter, powerlevel); + PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G); +#endif + break; + + case RF_8256: + PHY_SetRF8256CCKTxPower(dev, powerlevel); + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + break; + + case RF_8258: + break; + default: + RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n"); + break; + } + return; +} +/**************************************************************************************** + *function: This function set command table variable(struct SwChnlCmd). + * input: SwChnlCmd* CmdTable //table to be set. + * u32 CmdTableIdx //variable index in table to be set + * u32 CmdTableSz //table size. + * SwChnlCmdID CmdID //command ID to set. + * u32 Para1 + * u32 Para2 + * u32 msDelay + * output: + * return: true if finished, false otherwise + * Note: + * ************************************************************************************/ +u8 rtl8192_phy_SetSwChnlCmdArray( + SwChnlCmd* CmdTable, + u32 CmdTableIdx, + u32 CmdTableSz, + SwChnlCmdID CmdID, + u32 Para1, + u32 Para2, + u32 msDelay + ) +{ + SwChnlCmd* pCmd; + + if(CmdTable == NULL) + { + RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n"); + return false; + } + if(CmdTableIdx >= CmdTableSz) + { + RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n", + CmdTableIdx, CmdTableSz); + return false; + } + + pCmd = CmdTable + CmdTableIdx; + pCmd->CmdID = CmdID; + pCmd->Para1 = Para1; + pCmd->Para2 = Para2; + pCmd->msDelay = msDelay; + + return true; +} +/****************************************************************************** + *function: This function set channel step by step + * input: struct net_device *dev + * u8 channel + * u8* stage //3 stages + * u8* step // + * u32* delay //whether need to delay + * output: store new stage, step and delay for next step(combine with function above) + * return: true if finished, false otherwise + * Note: Wait for simpler function to replace it //wb + * ***************************************************************************/ +u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u8* step, u32* delay) +{ + struct r8192_priv *priv = ieee80211_priv(dev); +// PCHANNEL_ACCESS_SETTING pChnlAccessSetting; + SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT]; + u32 PreCommonCmdCnt; + SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT]; + u32 PostCommonCmdCnt; + SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT]; + u32 RfDependCmdCnt; + SwChnlCmd *CurrentCmd = NULL; + //RF90_RADIO_PATH_E eRFPath; + u8 eRFPath; +// u32 RfRetVal; +// u8 RetryCnt; + + RT_TRACE(COMP_TRACE, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel); +// RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel)); + +#ifdef ENABLE_DOT11D + if (!IsLegalChannel(priv->ieee80211, channel)) + { + RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel); + return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop. + } +#endif + + //for(eRFPath = RF90_PATH_A; eRFPath NumTotalRFPath; eRFPath++) + //for(eRFPath = 0; eRFPath Fill up pre common command. + PreCommonCmdCnt = 0; + rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, + CmdID_SetTxPowerLevel, 0, 0, 0); + rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, + CmdID_End, 0, 0, 0); + + // <2> Fill up post common command. + PostCommonCmdCnt = 0; + + rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT, + CmdID_End, 0, 0, 0); + + // <3> Fill up RF dependent command. + RfDependCmdCnt = 0; + switch( priv->rf_chip ) + { + case RF_8225: + if (!(channel >= 1 && channel <= 14)) + { + RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel); + return false; + } + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10); + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_8256: + // TEST!! This is not the table for 8256!! + if (!(channel >= 1 && channel <= 14)) + { + RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel); + return false; + } + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, channel, 10); + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_8258: + break; + + default: + RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); + return false; + break; + } + + + do{ + switch(*stage) + { + case 0: + CurrentCmd=&PreCommonCmd[*step]; + break; + case 1: + CurrentCmd=&RfDependCmd[*step]; + break; + case 2: + CurrentCmd=&PostCommonCmd[*step]; + break; + } + + if(CurrentCmd->CmdID==CmdID_End) + { + if((*stage)==2) + { + return true; + } + else + { + (*stage)++; + (*step)=0; + continue; + } + } + + switch(CurrentCmd->CmdID) + { + case CmdID_SetTxPowerLevel: + if(priv->card_8192_version > (u8)VERSION_8190_BD) //xiong: consider it later! + rtl8192_SetTxPowerLevel(dev,channel); + break; + case CmdID_WritePortUlong: + write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2); + break; + case CmdID_WritePortUshort: + write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2); + break; + case CmdID_WritePortUchar: + write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2); + break; + case CmdID_RF_WriteReg: + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bMask12Bits, CurrentCmd->Para2<<7); + break; + default: + break; + } + + break; + }while(true); + }/*for(Number of RF paths)*/ + + (*delay)=CurrentCmd->msDelay; + (*step)++; + return false; +} + +/****************************************************************************** + *function: This function does acturally set channel work + * input: struct net_device *dev + * u8 channel + * output: none + * return: noin + * Note: We should not call this function directly + * ***************************************************************************/ +void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + u32 delay = 0; + + while(!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay)) + { + if(delay>0) + msleep(delay);//or mdelay? need further consideration + if(!priv->up) + break; + } +} +/****************************************************************************** + *function: Callback routine of the work item for switch channel. + * input: + * + * output: none + * return: noin + * ***************************************************************************/ +void rtl8192_SwChnl_WorkItem(struct net_device *dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + + RT_TRACE(COMP_TRACE, "==> SwChnlCallback819xUsbWorkItem()\n"); + + RT_TRACE(COMP_TRACE, "=====>--%s(), set chan:%d, priv:%p\n", __FUNCTION__, priv->chan, priv); + + rtl8192_phy_FinishSwChnlNow(dev , priv->chan); + + RT_TRACE(COMP_TRACE, "<== SwChnlCallback819xUsbWorkItem()\n"); +} + +/****************************************************************************** + *function: This function scheduled actural workitem to set channel + * input: net_device dev + * u8 channel //channel to set + * output: none + * return: return code show if workitem is scheduled(1:pass, 0:fail) + * Note: Delay may be required for RF configuration + * ***************************************************************************/ +u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_PHY, "=====>%s()\n", __FUNCTION__); + if(!priv->up) + return false; + if(priv->SwChnlInProgress) + return false; + +// if(pHalData->SetBWModeInProgress) +// return; + + //-------------------------------------------- + switch(priv->ieee80211->mode) + { + case WIRELESS_MODE_A: + case WIRELESS_MODE_N_5G: + if (channel<=14){ + RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14"); + return false; + } + break; + case WIRELESS_MODE_B: + if (channel>14){ + RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14"); + return false; + } + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + if (channel>14){ + RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14"); + return false; + } + break; + } + //-------------------------------------------- + + priv->SwChnlInProgress = true; + if(channel == 0) + channel = 1; + + priv->chan=channel; + + priv->SwChnlStage=0; + priv->SwChnlStep=0; +// schedule_work(&(priv->SwChnlWorkItem)); +// rtl8192_SwChnl_WorkItem(dev); + if(priv->up) { +// queue_work(priv->priv_wq,&(priv->SwChnlWorkItem)); + rtl8192_SwChnl_WorkItem(dev); + } + priv->SwChnlInProgress = false; + return true; +} + +static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + switch(priv->CurrentChannelBW) + { + /* 20 MHz channel*/ + case HT_CHANNEL_WIDTH_20: + //added by vivi, cck,tx power track, 20080703 + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; + + if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) + priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; + if(priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + RT_TRACE(COMP_POWER_TRACKING, "20M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); + + if(priv->ieee80211->current_network.channel== 14 && !priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = TRUE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = FALSE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + break; + + /* 40 MHz channel*/ + case HT_CHANNEL_WIDTH_20_40: + //added by vivi, cck,tx power track, 20080703 + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; + + RT_TRACE(COMP_POWER_TRACKING, "40M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); + if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) + priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; + if(priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = TRUE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) + { + priv->bcck_in_ch14 = FALSE; + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + } + else + dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + break; + } +} + +#ifndef RTL8190P +static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) + priv->bcck_in_ch14 = TRUE; + else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) + priv->bcck_in_ch14 = FALSE; + + //write to default index and tx power track will be done in dm. + switch(priv->CurrentChannelBW) + { + /* 20 MHz channel*/ + case HT_CHANNEL_WIDTH_20: + if(priv->Record_CCK_20Mindex == 0) + priv->Record_CCK_20Mindex = 6; //set default value. + priv->CCK_index = priv->Record_CCK_20Mindex;//6; + RT_TRACE(COMP_POWER_TRACKING, "20MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(),CCK_index = %d\n", priv->CCK_index); + break; + + /* 40 MHz channel*/ + case HT_CHANNEL_WIDTH_20_40: + priv->CCK_index = priv->Record_CCK_40Mindex;//0; + RT_TRACE(COMP_POWER_TRACKING, "40MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(), CCK_index = %d\n", priv->CCK_index); + break; + } + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); +} +#endif + +static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev) +{ +#ifdef RTL8192E + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + +#ifdef RTL8190P + CCK_Tx_Power_Track_BW_Switch_TSSI(dev); +#else + //if(pHalData->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) + CCK_Tx_Power_Track_BW_Switch_TSSI(dev); + else + CCK_Tx_Power_Track_BW_Switch_ThermalMeter(dev); +#endif +} + + +// +/****************************************************************************** + *function: Callback routine of the work item for set bandwidth mode. + * input: struct net_device *dev + * HT_CHANNEL_WIDTH Bandwidth //20M or 40M + * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care + * output: none + * return: none + * Note: I doubt whether SetBWModeInProgress flag is necessary as we can + * test whether current work in the queue or not.//do I? + * ***************************************************************************/ +void rtl8192_SetBWModeWorkItem(struct net_device *dev) +{ + + struct r8192_priv *priv = ieee80211_priv(dev); + u8 regBwOpMode; + + RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", \ + priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz") + + + if(priv->rf_chip== RF_PSEUDO_11N) + { + priv->SetBWModeInProgress= false; + return; + } + if(!priv->up) + { + priv->SetBWModeInProgress= false; + return; + } + //<1>Set MAC register + regBwOpMode = read_nic_byte(dev, BW_OPMODE); + + switch(priv->CurrentChannelBW) + { + case HT_CHANNEL_WIDTH_20: + regBwOpMode |= BW_OPMODE_20MHZ; + // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + break; + + case HT_CHANNEL_WIDTH_20_40: + regBwOpMode &= ~BW_OPMODE_20MHZ; + // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + break; + + default: + RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW); + break; + } + + //<2>Set PHY related register + switch(priv->CurrentChannelBW) + { + case HT_CHANNEL_WIDTH_20: + // Add by Vivi 20071119 + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); +// rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); + + // Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207 +// write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000); +// write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317); +// write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); + if(!priv->btxpower_tracking) + { + write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000); + write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317); + write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); + } + else + CCK_Tx_Power_Track_BW_Switch(dev); + +#ifdef RTL8190P + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 1); + rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x44); // 0xc30 is for 8190 only, Emily +#else + #ifdef RTL8192E + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); + #endif +#endif + + break; + case HT_CHANNEL_WIDTH_20_40: + // Add by Vivi 20071119 + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); + //rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); + //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); + //rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); + + // Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207 + //write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000); + //write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e); + //write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); + if(!priv->btxpower_tracking) + { + write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000); + write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e); + write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); + } + else + CCK_Tx_Power_Track_BW_Switch(dev); + + // Set Control channel to upper or lower. These settings are required only for 40MHz + rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); + rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); + + +#ifdef RTL8190P + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 0); + rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x42); // 0xc30 is for 8190 only, Emily + + // Set whether CCK should be sent in upper or lower channel. Suggest by YN. 20071207 + // It is set in Tx descriptor for 8192x series + if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) + { + rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x01); + }else if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) + { + rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x02); + } + +#else + #ifdef RTL8192E + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); + #endif +#endif + break; + default: + RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW); + break; + + } + //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 + +#if 1 + //<3>Set RF related register + switch( priv->rf_chip ) + { + case RF_8225: +#ifdef TO_DO_LIST + PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW); +#endif + break; + + case RF_8256: + PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); + break; + + case RF_8258: + // PHY_SetRF8258Bandwidth(); + break; + + case RF_PSEUDO_11N: + // Do Nothing + break; + + default: + RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); + break; + } +#endif + atomic_dec(&(priv->ieee80211->atm_swbw)); + priv->SetBWModeInProgress= false; + + RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()"); +} + +/****************************************************************************** + *function: This function schedules bandwith switch work. + * input: struct net_device *dev + * HT_CHANNEL_WIDTH Bandwidth //20M or 40M + * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care + * output: none + * return: none + * Note: I doubt whether SetBWModeInProgress flag is necessary as we can + * test whether current work in the queue or not.//do I? + * ***************************************************************************/ +void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + + if(priv->SetBWModeInProgress) + return; + + atomic_inc(&(priv->ieee80211->atm_swbw)); + priv->SetBWModeInProgress= true; + + priv->CurrentChannelBW = Bandwidth; + + if(Offset==HT_EXTCHNL_OFFSET_LOWER) + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; + else if(Offset==HT_EXTCHNL_OFFSET_UPPER) + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; + else + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + //queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem)); + // schedule_work(&(priv->SetBWModeWorkItem)); + rtl8192_SetBWModeWorkItem(dev); + +} + + +extern void InitialGain819xPci(struct net_device *dev, u8 Operation) +{ +#define SCAN_RX_INITIAL_GAIN 0x17 +#define POWER_DETECTION_TH 0x08 + struct r8192_priv *priv = ieee80211_priv(dev); + u32 BitMask; + u8 initial_gain; + + if(priv->up) + { + switch(Operation) + { + case IG_Backup: + RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n"); + initial_gain = SCAN_RX_INITIAL_GAIN;//pHalData->DefaultInitialGain[0];// + BitMask = bMaskByte0; + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF + priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask); + priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask); + priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask); + priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask); + BitMask = bMaskByte2; + priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask); + + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); + + RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain); + write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH); + write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH); + break; + case IG_Restore: + RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n"); + BitMask = 0x7f; //Bit0~ Bit6 + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF + + rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1); + BitMask = bMaskByte2; + rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca); + + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); + + rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); + + + if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON + break; + default: + RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n"); + break; + } + } +} + diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h new file mode 100644 index 00000000000..fa77abe8882 --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -0,0 +1,125 @@ +#ifndef _R819XU_PHY_H +#define _R819XU_PHY_H +/* Channel switch:The size of command tables for switch channel*/ +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#ifdef RTL8190P +#define MACPHY_Array_PGLength 21 +#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG +#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array +#define RadioC_ArrayLength 246 +#define RadioD_ArrayLength 78 +#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array +#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array +#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array +#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array +#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array +#define PHY_REGArrayLength 280 +#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray +#define PHY_REG_1T2RArrayLength 280 +#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray +#endif + + #ifdef RTL8192E + #define MACPHY_Array_PGLength 30 + #define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG + #define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array + #define RadioC_ArrayLength 1 + #define RadioD_ArrayLength 1 + #define Rtl819XRadioA_Array Rtl8192PciERadioA_Array + #define Rtl819XRadioB_Array Rtl8192PciERadioB_Array + #define Rtl819XRadioC_Array Rtl8192PciERadioC_Array + #define Rtl819XRadioD_Array Rtl8192PciERadioD_Array + #define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array + #define PHY_REGArrayLength 1 + #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray + #define PHY_REG_1T2RArrayLength 296 + #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray + #endif +#define AGCTAB_ArrayLength 384 +#define MACPHY_ArrayLength 18 + +#define RadioA_ArrayLength 246 +#define RadioB_ArrayLength 78 + + +typedef enum _SwChnlCmdID{ + CmdID_End, + CmdID_SetTxPowerLevel, + CmdID_BBRegWrite10, + CmdID_WritePortUlong, + CmdID_WritePortUshort, + CmdID_WritePortUchar, + CmdID_RF_WriteReg, +}SwChnlCmdID; + +/*--------------------------------Define structure--------------------------------*/ +/* 1. Switch channel related */ +typedef struct _SwChnlCmd{ + SwChnlCmdID CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +}__attribute__ ((packed)) SwChnlCmd; + +extern u32 rtl819XMACPHY_Array_PG[]; +extern u32 rtl819XPHY_REG_1T2RArray[]; +extern u32 rtl819XAGCTAB_Array[]; +extern u32 rtl819XRadioA_Array[]; +extern u32 rtl819XRadioB_Array[]; +extern u32 rtl819XRadioC_Array[]; +extern u32 rtl819XRadioD_Array[]; + +typedef enum _HW90_BLOCK{ + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, // Never use this +}HW90_BLOCK_E, *PHW90_BLOCK_E; + +typedef enum _RF90_RADIO_PATH{ + RF90_PATH_A = 0, //Radio Path A + RF90_PATH_B = 1, //Radio Path B + RF90_PATH_C = 2, //Radio Path C + RF90_PATH_D = 3, //Radio Path D + RF90_PATH_MAX //Max RF number 92 support +}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; + +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff + +//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask); +extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath); +extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData); +extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask); +//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset); +//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); +extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data); +extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); +extern void rtl8192_phy_configmac(struct net_device* dev); +extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType); +//extern void rtl8192_InitBBRFRegDef(struct net_device* dev); +extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); +//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev); +extern RT_STATUS rtl8192_BBConfig(struct net_device* dev); +extern void rtl8192_phy_getTxPower(struct net_device* dev); +extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel); +extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev); +extern void rtl8192_phy_updateInitGain(struct net_device* dev); +extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath); + +extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel); +extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +extern void rtl8192_SwChnl_WorkItem(struct net_device *dev); +extern void rtl8192_SetBWModeWorkItem(struct net_device *dev); +extern void InitialGain819xPci(struct net_device *dev, u8 Operation); + +#endif diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h new file mode 100644 index 00000000000..d4a439275ef --- /dev/null +++ b/drivers/staging/rtl8192e/r819xE_phyreg.h @@ -0,0 +1,878 @@ +#ifndef _R819XU_PHYREG_H +#define _R819XU_PHYREG_H + + +#define RF_DATA 0x1d4 // FW will write RF data in the register. + +//Register //duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +//page 1 +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +//90P +#define MCS_TXAGC 0x340 // MCS AGC +#define CCK_TXAGC 0x348 // CCK AGC + +//page8 +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC +#define rFPGA0_TxInfo 0x804 +#define rFPGA0_PSDFunction 0x808 +#define rFPGA0_TxGainStage 0x80c +#define rFPGA0_RFTiming1 0x810 +#define rFPGA0_RFTiming2 0x814 +//#define rFPGA0_XC_RFTiming 0x818 +//#define rFPGA0_XD_RFTiming 0x81c +#define rFPGA0_XA_HSSIParameter1 0x820 +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rFPGA0_XC_HSSIParameter1 0x830 +#define rFPGA0_XC_HSSIParameter2 0x834 +#define rFPGA0_XD_HSSIParameter1 0x838 +#define rFPGA0_XD_HSSIParameter2 0x83c +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 +#define rFPGA0_XC_LSSIParameter 0x848 +#define rFPGA0_XD_LSSIParameter 0x84c +#define rFPGA0_RFWakeUpParameter 0x850 +#define rFPGA0_RFSleepUpParameter 0x854 +#define rFPGA0_XAB_SwitchControl 0x858 +#define rFPGA0_XCD_SwitchControl 0x85c +#define rFPGA0_XA_RFInterfaceOE 0x860 +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rFPGA0_XC_RFInterfaceOE 0x868 +#define rFPGA0_XD_RFInterfaceOE 0x86c +#define rFPGA0_XAB_RFInterfaceSW 0x870 +#define rFPGA0_XCD_RFInterfaceSW 0x874 +#define rFPGA0_XAB_RFParameter 0x878 +#define rFPGA0_XCD_RFParameter 0x87c +#define rFPGA0_AnalogParameter1 0x880 +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AnalogParameter4 0x88c +#define rFPGA0_XA_LSSIReadBack 0x8a0 +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac +#define rFPGA0_PSDReport 0x8b4 +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 + +//page 9 +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC +#define rFPGA1_TxBlock 0x904 +#define rFPGA1_DebugSelect 0x908 +#define rFPGA1_TxInfo 0x90c + +//page a +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 +#define rCCK0_CCA 0xa08 +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC +#define rCCK0_RxHP 0xa14 +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +//page c +#define rOFDM0_LSTF 0xc00 +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA +#define rOFDM0_XAAGCCore1 0xc50 +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c +#define rOFDM0_XATxIQImbalance 0xc80 +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 + + +//page d +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 +#define rOFDM1_CFO 0xd08 +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support +#define rOFDM_ShortCFOAB 0xdac +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + +//page e +#define rTxAGC_Rate18_06 0xe00 +#define rTxAGC_Rate54_24 0xe04 +#define rTxAGC_CCK_Mcs32 0xe08 +#define rTxAGC_Mcs03_Mcs00 0xe10 +#define rTxAGC_Mcs07_Mcs04 0xe14 +#define rTxAGC_Mcs11_Mcs08 0xe18 +#define rTxAGC_Mcs15_Mcs12 0xe1c + + +//RF +//Zebra1 +#define rZebra1_HSSIEnable 0x0 +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 +#define rZebra1_TxGain 0x8 +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +//Bit Mask +//page-1 +#define bBBResetB 0x100 +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +//page-8 +#define bRFMOD 0x1 +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bOFDMRxADCPhase 0x10000 +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f +#define bXBTxAGC 0xf00 +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 +#define bPAStart 0xf0000000 +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 +#define b3WireDataLength 0x800 +#define b3WireAddressLength 0x400 +#define b3WireRFPowerDown 0x1 +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf //3-wire total control +#define bRFSI_RFENV 0x10 +#define bRFSI_TRSW 0x20 +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 +#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal +#define bLSSIReadBackData 0xfff +#define bLSSIReadOKFlag 0x1000 +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz + +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 +#define bADClkPhase 0x4000000 +#define b80MClkDelay 0x18000000 +#define bAFEWatchDogEnable 0x20000000 +#define bXtalCap 0x0f000000 +#define bXtalCap01 0xc0000000 +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bIntDifClkEnable 0x400 +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 + +#define bCCKRxAGCFormat 0x200 + +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +//page-9 +#define bOFDMTxSC 0x30000000 +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +//page-a +#define bCCKBBMode 0x3 +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 +#define bCCKSideBand 0x10 +#define bCCKScramble 0x8 +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 + +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 + +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +//page c +#define bNumOfSTF 0x3 +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 + +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 + +#define bDAFormat 0x40000 + +#define bTxChEmuEnable 0x01000000 + +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 + +#define bExtLNAGain 0x7c00 + +//page d +#define bSTBCEn 0x4 +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 + +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 + +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 + +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 + +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 + +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 + +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//page e +#define bTxAGCRate18_06 0x7f7f7f7f +#define bTxAGCRate54_24 0x7f7f7f7f +#define bTxAGCRateMCS32 0x7f +#define bTxAGCRateCCK 0x7f00 +#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f +#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f +#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f +#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f + + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//RF +//Zebra1 +#define bZebra1_HSSIEnable 0x8 +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + +//byte endable for sb_write +#define bByte0 0x1 +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff + +//for PutRFRegsetting & GetRFRegSetting BitMask +#define bMask12Bits 0xfff + +#define bEnable 0x1 +#define bDisable 0x0 + +#define LeftAntenna 0x0 +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +#define rRTL8256RxMixerPole 0xb +#define bZebraRxMixerPole 0x6 +#define rRTL8256TxBBOPBias 0x9 +#define bRTL8256TxBBOPBias 0x400 +#define rRTL8256TxBBBW 19 +#define bRTL8256TxBBBW 0x18 + +#endif //__INC_HAL8190PCIPHYREG_H diff --git a/drivers/staging/rtl8192e/r819xP_firmware_img.h b/drivers/staging/rtl8192e/r819xP_firmware_img.h new file mode 100644 index 00000000000..33cc537e315 --- /dev/null +++ b/drivers/staging/rtl8192e/r819xP_firmware_img.h @@ -0,0 +1,3637 @@ +#ifndef __INC_R819XU_FIRMWARE_IMG_H +#define __INC_R819XU_FIRMWARE_IMG_H +/*Created on 2008/ 5/19, 6:38*/ +#include + +u8 rtl8190_fwboot_array[] = { +0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08, +0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xd6,0x04,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff, +0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b, +0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00, +0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xd6,0x04,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0, +0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00, +0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00, +0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff, +0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01, +0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01, +0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24, +0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10, +0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10, +0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x6a,0xbc, +0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,}; + +u8 rtl8190_fwmain_array[] = { +0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x1a,0x1e, +0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09, +0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24, +0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0, +0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x94,0x50,0x00,0x85,0x18,0x21, +0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00, +0x27,0x82,0x94,0x5a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00, +0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x94,0x50, +0x24,0x02,0x00,0x0a,0x24,0x03,0x09,0xc4,0xa3,0x82,0x94,0x52,0x24,0x02,0x00,0x04, +0x24,0x04,0x00,0x01,0x24,0x05,0x00,0x02,0xa7,0x83,0x94,0x66,0xa3,0x82,0x94,0x58, +0x24,0x03,0x04,0x00,0x24,0x02,0x02,0x00,0xaf,0x83,0x94,0x6c,0xa3,0x85,0x94,0x59, +0xa7,0x82,0x94,0x5a,0xa7,0x84,0x94,0x5c,0xaf,0x84,0x94,0x68,0xa3,0x84,0x94,0x51, +0xa3,0x80,0x94,0x53,0xa3,0x80,0x94,0x54,0xa3,0x80,0x94,0x55,0xa3,0x84,0x94,0x56, +0xa3,0x85,0x94,0x57,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x7c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00, +0x27,0x84,0x94,0x78,0x00,0x00,0x10,0x21,0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00, +0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc0, +0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00, +0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00, +0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03, +0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11, +0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07, +0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10, +0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b, +0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20, +0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x24, +0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54, +0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x94,0x74,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18, +0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,0x27,0x85,0x94,0x70,0x8c,0xa3,0x00,0x00, +0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a, +0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01, +0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3, +0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40, +0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x94,0x78,0x00,0x0a,0x20,0x0b, +0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01, +0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x94,0x78,0xa0,0x67,0x00,0x01, +0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07, +0x00,0x00,0x00,0x00,0x27,0x83,0x94,0x70,0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,0xac,0x62,0x00,0x00,0x27,0x85,0x94,0x74, +0x27,0x82,0x94,0x70,0x00,0xc5,0x28,0x21,0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00, +0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xb7,0xac,0xa0,0x00,0x00, +0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x94,0x8c,0x08,0x00,0x00,0xa7, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x94,0x80,0x08,0x00,0x00,0xa7,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x10, +0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00, +0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03, +0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2, +0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09, +0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,0x30,0x43,0x00,0x03,0x83,0x82,0x94,0x78, +0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04, +0x30,0x43,0x00,0x06,0x93,0x82,0x94,0x90,0x08,0x00,0x01,0x1f,0x00,0x43,0x10,0x21, +0x83,0x82,0x94,0x84,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x1f, +0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01, +0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xe4, +0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08, +0x24,0x02,0x00,0x01,0xaf,0x84,0x94,0xa0,0xa3,0x82,0x94,0xb0,0xa7,0x80,0x94,0xa4, +0xa7,0x80,0x94,0xa6,0xaf,0x80,0x94,0xa8,0xaf,0x80,0x94,0xac,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x05,0x24,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac, +0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21, +0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x05,0x5c,0x27,0xbd,0xff,0xe0, +0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0x8f,0x90,0x94,0xa0,0x0c,0x00,0x02,0x90,0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a, +0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01, +0xae,0x02,0x00,0x00,0x97,0x84,0x94,0xa4,0x97,0x82,0x94,0xa6,0x3c,0x03,0xb0,0x02, +0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,0xa7,0x82,0x94,0xa6,0xa4,0x82,0x00,0x00, +0x8f,0x84,0x94,0xa8,0x8f,0x82,0x94,0xa0,0x93,0x85,0x94,0x52,0x24,0x84,0x00,0x01, +0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03, +0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,0x34,0xe7,0x80,0x18,0xaf,0x82,0x94,0xa0, +0xaf,0x84,0x94,0xa8,0x10,0xa0,0x00,0x08,0x34,0xc6,0x01,0x08,0x8f,0x83,0x94,0xac, +0x8f,0x84,0x94,0x6c,0x8c,0xc2,0x00,0x00,0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b, +0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00, +0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00, +0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x48,0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20, +0x8f,0x90,0x94,0xa0,0xac,0x43,0x00,0x00,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21, +0x0c,0x00,0x02,0x90,0x00,0xc0,0x98,0x21,0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19, +0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24, +0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,0x00,0x47,0x80,0x24,0x97,0x86,0x94,0xa4, +0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00, +0x8f,0x84,0x94,0xa0,0x3c,0x02,0xb0,0x02,0x97,0x85,0x94,0xa6,0x00,0xc2,0x30,0x21, +0x8f,0x82,0x94,0xa8,0x24,0x84,0x00,0x10,0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24, +0x24,0x42,0x00,0x01,0xa7,0x85,0x94,0xa6,0xaf,0x84,0x94,0xa0,0xaf,0x82,0x94,0xa8, +0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, +0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14, +0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc, +0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08, +0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01, +0x00,0x02,0x10,0x80,0x24,0x63,0x08,0x94,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14, +0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x8c,0xa4,0x00,0x00,0x0c,0x00,0x1e,0xfc,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x0c,0x00,0x2b,0x59,0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x87,0x83,0x88,0x06,0x93,0x82,0x80,0x18,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x93,0x83,0x88,0x07,0x24,0x02,0x00,0x01, +0xa3,0x82,0x80,0x11,0xa3,0x83,0x80,0x19,0xa3,0x83,0x80,0x18,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x93,0x82,0x80,0x19,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xf6, +0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xf3,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff, +0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,0x8f,0x82,0x80,0x14,0xa3,0x85,0x8b,0xcb, +0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40, +0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0, +0x00,0x05,0x10,0x40,0x27,0x84,0x8b,0xd4,0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0, +0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40, +0x27,0x84,0x8b,0xd4,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00, +0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10, +0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,0x27,0x84,0x8b,0xd4,0x00,0x44,0x10,0x21, +0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x86,0x94,0xa0,0x8f,0x82,0x80,0x14, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21, +0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,0xa3,0x82,0x8b,0xd3,0xa3,0x83,0x8b,0xd2, +0x27,0x8a,0x8b,0xd0,0x00,0x00,0x20,0x21,0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80, +0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01, +0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00, +0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80, +0x97,0x83,0x94,0xa6,0x97,0x85,0x94,0xa4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c, +0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x94,0xa6,0x34,0x84,0x80,0x18, +0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c, +0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00, +0xaf,0x86,0x94,0xa0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x8e, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x8f,0x86,0x94,0xa0,0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08, +0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12, +0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21, +0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08, +0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x48,0x28,0x24,0x97,0x83,0x94,0xa6, +0x97,0x85,0x94,0xa4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x94,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x94,0xa0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38, +0x93,0x82,0x94,0xb0,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01, +0x8f,0x82,0x94,0xa8,0x3c,0x05,0xb0,0x06,0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18, +0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,0x00,0x00,0x30,0x21,0x97,0x82,0x94,0xa4, +0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,0x00,0x43,0x10,0x21,0xaf,0x84,0x94,0xac, +0xa7,0x80,0x94,0xa6,0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x8f,0x86,0x94,0xa0,0x8f,0x82,0x94,0xa8, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a, +0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,0x27,0x89,0x8b,0xa0,0x24,0xe2,0x00,0x01, +0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a, +0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f, +0x00,0x00,0x00,0x00,0x97,0x82,0x8b,0xa6,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x8b,0xa6,0x90,0xa3,0x00,0x15,0x97,0x82,0x8b,0xa8,0x00,0x03,0x1e,0x00, +0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,0xa7,0x82,0x8b,0xa8,0x8c,0xa4,0x00,0x20, +0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54, +0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,0x00,0x00,0x00,0x00,0x97,0x82,0x8b,0xac, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0xac,0x84,0xa3,0x00,0x06, +0x8f,0x82,0x8b,0xbc,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x8b,0xbc, +0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,0xaf,0x82,0x94,0xa8,0x10,0x60,0x00,0x09, +0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05, +0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,0xa3,0x83,0x8b,0xa2,0xa3,0x82,0x8b,0xa3, +0x90,0xa2,0x00,0x18,0x93,0x83,0x8b,0xcb,0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0xa7,0x82,0x8b,0xb6,0xa3,0x83,0x8b,0xc4,0x27,0x89,0x8b,0xa0, +0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a, +0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x45,0x40,0x24,0x97,0x83,0x94,0xa6, +0x97,0x85,0x94,0xa4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x94,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x94,0xa0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00, +0x0c,0x00,0x02,0x2e,0x00,0x00,0x00,0x00,0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xdd, +0x00,0x00,0x00,0x00,0x97,0x82,0x8b,0xae,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x8b,0xae,0x84,0xa3,0x00,0x06,0x8f,0x82,0x8b,0xc0,0x00,0x00,0x00,0x00, +0x00,0x43,0x10,0x21,0xaf,0x82,0x8b,0xc0,0x08,0x00,0x02,0xd5,0x25,0x42,0x00,0x01, +0x97,0x82,0x8b,0xaa,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0xaa, +0x84,0xa3,0x00,0x06,0x8f,0x82,0x8b,0xb8,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xaf,0x82,0x8b,0xb8,0x08,0x00,0x02,0xd5,0x25,0x42,0x00,0x01,0x97,0x82,0x8b,0xa4, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0xa4,0x08,0x00,0x02,0xbd, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20, +0x8f,0x8a,0x94,0xa0,0x3c,0x02,0x00,0x10,0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21, +0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c, +0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42, +0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25, +0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a, +0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34, +0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18, +0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20, +0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff, +0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01, +0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00, +0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,0x97,0x83,0x94,0xa6,0x97,0x85,0x94,0xa4, +0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06, +0xa7,0x83,0x94,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00, +0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24, +0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x8a,0x94,0xa0,0x10,0xa2,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20, +0x24,0x42,0x0d,0xdc,0x3c,0x03,0xb0,0x00,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20, +0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21, +0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14, +0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08, +0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02, +0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76, +0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00, +0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2, +0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24, +0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04, +0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2, +0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02, +0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26, +0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02, +0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00, +0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00, +0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x92,0x01,0x20,0x20,0x21,0x08,0x00,0x03,0x9d, +0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07, +0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,0x27,0x83,0x94,0x50,0x00,0x43,0x10,0x21, +0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xc4,0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40, +0x27,0x83,0x94,0x58,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xc4, +0x00,0x07,0x22,0x02,0x27,0x82,0x94,0x50,0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00, +0x08,0x00,0x03,0xc4,0x00,0x07,0x22,0x02,0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21, +0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00, +0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e, +0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xc4, +0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00, +0x08,0x00,0x03,0xc3,0x30,0x67,0xff,0xff,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x03,0xc3,0x30,0x67,0x00,0xff,0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00, +0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x03,0xf5,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x03,0xfa,0x3c,0x02,0xb0,0x0a, +0x08,0x00,0x03,0xfe,0x3c,0x02,0xb0,0x0a,0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08, +0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02, +0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00, +0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24, +0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00, +0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24, +0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02, +0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02, +0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69, +0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15, +0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21, +0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24, +0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,0x08,0x00,0x03,0x9d,0x02,0x51,0x10,0x21, +0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24, +0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0x9d, +0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00, +0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0x08,0x00,0x03,0x9c,0xa0,0x62,0x00,0x00,0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21, +0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17, +0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,0x00,0x00,0x00,0x00,0x27,0x83,0x94,0x50, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27, +0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0x9c, +0xac,0x82,0x00,0x18,0x27,0x83,0x94,0x58,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21, +0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24, +0x00,0x45,0x10,0x25,0x08,0x00,0x03,0x9c,0xa4,0x82,0x00,0x02,0x27,0x83,0x94,0x50, +0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x52, +0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f, +0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x3f, +0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x48,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a, +0x08,0x00,0x04,0x75,0x00,0x43,0x18,0x21,0x97,0x85,0x94,0xa4,0x3c,0x07,0xb0,0x02, +0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20, +0x24,0x42,0x12,0x38,0x24,0x03,0xff,0x80,0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07, +0x97,0x82,0x94,0xa6,0x97,0x85,0x94,0xa4,0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8, +0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08, +0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25, +0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,0xac,0xc5,0x00,0x00,0xaf,0x84,0x94,0xa0, +0xa7,0x82,0x94,0xa4,0xa7,0x80,0x94,0xa6,0xaf,0x80,0x94,0xa8,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07, +0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03, +0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14, +0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x04,0xd9,0xac,0x62,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07, +0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a, +0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10, +0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09, +0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24, +0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00, +0x30,0xa9,0x00,0xff,0x27,0x83,0x94,0x50,0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21, +0x00,0x05,0x20,0x40,0x27,0x82,0x94,0x50,0x00,0x05,0x28,0x80,0x27,0x83,0x94,0x58, +0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27, +0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00, +0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18, +0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25, +0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00, +0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00, +0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25, +0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,0x00,0x44,0x10,0x25,0x3c,0x02,0xb0,0x02, +0x34,0x42,0x00,0x08,0x3c,0x03,0xb0,0x02,0xaf,0x82,0x8c,0x78,0xaf,0x83,0x8c,0x7c, +0xa7,0x80,0x8c,0x80,0xa7,0x80,0x8c,0x82,0xaf,0x80,0x8c,0x84,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xbf,0x00,0x20,0x94,0x82,0x00,0x04, +0x3c,0x05,0xff,0x8f,0x00,0x80,0x18,0x21,0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x0a, +0x34,0xa5,0xff,0xff,0x90,0x84,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xfc, +0x00,0x64,0x20,0x21,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x10,0x2b, +0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x0c,0x00,0x07,0xc9,0x00,0x00,0x00,0x00, +0x08,0x00,0x05,0x4a,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c, +0x8f,0x90,0x94,0xa0,0x0c,0x00,0x30,0x54,0x00,0x80,0x90,0x21,0x00,0x40,0x88,0x21, +0x93,0x82,0x82,0x28,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b,0x24,0x02,0x00,0x01, +0xa3,0x82,0x82,0x28,0x24,0x03,0x00,0x05,0x24,0x02,0x00,0x04,0xa3,0x83,0x8c,0x73, +0xa3,0x82,0x8c,0x72,0xa7,0x80,0x82,0x2a,0x00,0x00,0x28,0x21,0x27,0x86,0x8c,0x70, +0x00,0x05,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01, +0x30,0x65,0xff,0xff,0xae,0x04,0x00,0x00,0x10,0xa0,0xff,0xfa,0x00,0x05,0x10,0x80, +0x8f,0x83,0x94,0xa0,0x97,0x82,0x94,0xa6,0x24,0x05,0x8f,0xff,0x24,0x63,0x00,0x04, +0x00,0x65,0x18,0x24,0x26,0x04,0x00,0x04,0x24,0x42,0x00,0x04,0xaf,0x83,0x94,0xa0, +0xa7,0x82,0x94,0xa6,0x00,0x85,0x80,0x24,0x97,0x84,0x82,0x2a,0x27,0x93,0x80,0x34, +0x02,0x40,0x28,0x21,0x00,0x93,0x20,0x21,0x0c,0x00,0x30,0xd8,0x02,0x20,0x30,0x21, +0x97,0x87,0x82,0x2a,0x24,0x02,0x00,0x52,0x00,0xf1,0x18,0x21,0xa7,0x83,0x82,0x2a, +0x82,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x06,0x00,0x60,0x38,0x21, +0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x28,0x82,0x43,0x00,0x01,0x24,0x02,0x00,0x54,0x14,0x62,0xff,0xf8, +0x24,0x02,0x00,0x4c,0x82,0x43,0x00,0x02,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xf4, +0x00,0x00,0x00,0x00,0x30,0xe6,0xff,0xff,0x10,0xc0,0x00,0x0c,0x00,0x00,0x28,0x21, +0x02,0x60,0x48,0x21,0x24,0x08,0x8f,0xff,0x00,0xa9,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xa3,0x00,0x04,0x30,0x65,0xff,0xff,0x26,0x02,0x00,0x04,0x00,0xa6,0x18,0x2b, +0xae,0x04,0x00,0x00,0x14,0x60,0xff,0xf8,0x00,0x48,0x80,0x24,0x97,0x83,0x94,0xa6, +0x97,0x85,0x94,0xa4,0x3c,0x02,0xb0,0x02,0x00,0x67,0x18,0x21,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x94,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8f,0x82,0x94,0xa0,0x8c,0x86,0x00,0x00,0x30,0xe5,0xff,0xff,0x24,0x03,0x8f,0xff, +0x00,0x45,0x10,0x21,0x3c,0x04,0x0f,0x00,0x00,0x43,0x10,0x24,0x00,0xc4,0x30,0x24, +0x3c,0x03,0x04,0x00,0xaf,0x82,0x94,0xa0,0x10,0xc3,0xff,0xd1,0x00,0x00,0x00,0x00, +0x0c,0x00,0x04,0x8e,0x00,0x00,0x00,0x00,0xa3,0x80,0x82,0x28,0x08,0x00,0x05,0x88, +0x00,0x00,0x00,0x00,0x8f,0x82,0x8c,0x7c,0x97,0x83,0x8c,0x80,0x8f,0x87,0x8c,0x78, +0x3c,0x06,0xff,0xff,0xac,0x43,0x00,0x00,0x8f,0x82,0x8c,0x7c,0x3c,0x03,0x80,0x00, +0x24,0xe5,0x00,0x08,0xac,0x43,0x00,0x04,0x8f,0x82,0x8c,0x7c,0x34,0xc6,0x1f,0xff, +0x3c,0x03,0x00,0x40,0x30,0x42,0x0f,0xff,0x3c,0x04,0xb0,0x06,0x00,0x02,0x10,0xc2, +0x00,0x43,0x10,0x25,0x00,0xa6,0x28,0x24,0x34,0x84,0x80,0x18,0x27,0xbd,0xff,0xf8, +0xac,0x82,0x00,0x00,0xaf,0x85,0x8c,0x78,0xaf,0x87,0x8c,0x7c,0xa7,0x80,0x8c,0x80, +0xa7,0x80,0x8c,0x82,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x8f,0x91,0x8c,0x78, +0x00,0x80,0x80,0x21,0xaf,0xbf,0x00,0x1c,0x0c,0x00,0x06,0x78,0x00,0xa0,0x90,0x21, +0x97,0x82,0x8c,0x80,0x36,0x10,0x12,0x00,0x26,0x2a,0x00,0x04,0x24,0x4c,0x00,0x14, +0x2c,0x42,0x04,0x01,0x14,0x40,0x00,0x0a,0x24,0x09,0x8f,0xff,0x8f,0x82,0x80,0x20, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x80,0x20,0x8f,0xbf,0x00,0x1c, +0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x8e,0x44,0x00,0x1c,0x86,0x47,0x00,0x06,0x97,0x86,0x8c,0x82,0x8c,0x82,0x00,0x08, +0x00,0x07,0x3c,0x00,0x8f,0x85,0x8c,0x78,0x00,0x02,0x11,0x02,0x30,0x42,0x40,0x00, +0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x8c,0x82,0x00,0x04,0x82,0x43,0x00,0x15, +0x01,0x49,0x88,0x24,0x00,0x02,0x14,0xc2,0x00,0x03,0x1a,0x00,0x00,0x02,0x14,0x00, +0x00,0x62,0x80,0x25,0xae,0x30,0x00,0x00,0x92,0x43,0x00,0x13,0x92,0x44,0x00,0x10, +0x96,0x50,0x00,0x1a,0x00,0x03,0x1c,0x00,0x00,0x04,0x26,0x00,0x02,0x03,0x80,0x25, +0x26,0x22,0x00,0x04,0x00,0x49,0x88,0x24,0x02,0x04,0x80,0x25,0xae,0x30,0x00,0x00, +0x92,0x42,0x00,0x0f,0x92,0x43,0x00,0x11,0x26,0x24,0x00,0x04,0x00,0x02,0x12,0x00, +0x00,0x89,0x88,0x24,0x00,0x62,0x80,0x25,0x02,0x07,0x80,0x25,0x26,0x22,0x00,0x04, +0xae,0x30,0x00,0x00,0x00,0x49,0x88,0x24,0xae,0x20,0x00,0x00,0x8f,0x82,0x80,0x1c, +0x24,0xc6,0x00,0x01,0x24,0xa5,0x00,0x14,0x30,0xc8,0xff,0xff,0x3c,0x0b,0xb0,0x03, +0x00,0xa9,0x28,0x24,0x24,0x42,0x00,0x01,0x2d,0x08,0x00,0x0a,0xaf,0x85,0x8c,0x78, +0xa7,0x8c,0x8c,0x80,0xaf,0x82,0x80,0x1c,0xa7,0x86,0x8c,0x82,0x11,0x00,0x00,0x07, +0x35,0x6b,0x01,0x08,0x8f,0x82,0x8c,0x84,0x8d,0x63,0x00,0x00,0x24,0x42,0x04,0x00, +0x00,0x62,0x18,0x2b,0x14,0x60,0xff,0xc1,0x00,0x00,0x00,0x00,0x0c,0x00,0x05,0xbd, +0x00,0x00,0x00,0x00,0x08,0x00,0x05,0xf3,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8, +0xaf,0xbf,0x00,0x10,0x0c,0x00,0x06,0x78,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe0, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c, +0x8f,0x90,0x8c,0x78,0x0c,0x00,0x06,0x78,0x00,0x80,0x90,0x21,0x97,0x82,0x8c,0x80, +0x24,0x11,0x8f,0xff,0x2c,0x42,0x04,0x01,0x14,0x40,0x00,0x06,0x26,0x03,0x00,0x04, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x71,0x80,0x24, +0xae,0x00,0x00,0x00,0x8e,0x44,0x00,0x08,0x26,0x02,0x00,0x04,0x0c,0x00,0x06,0x86, +0x00,0x51,0x80,0x24,0x97,0x86,0x8c,0x82,0x8f,0x83,0x8c,0x78,0xae,0x02,0x00,0x00, +0x97,0x82,0x8c,0x80,0x24,0xc6,0x00,0x01,0x8e,0x47,0x00,0x0c,0x24,0x63,0x00,0x10, +0x30,0xc5,0xff,0xff,0x26,0x04,0x00,0x04,0x3c,0x08,0xb0,0x03,0x00,0x71,0x18,0x24, +0x00,0x91,0x80,0x24,0x24,0x42,0x00,0x10,0x2c,0xa5,0x00,0x0a,0x35,0x08,0x01,0x08, +0xae,0x07,0x00,0x00,0xaf,0x83,0x8c,0x78,0xa7,0x82,0x8c,0x80,0xa7,0x86,0x8c,0x82, +0x10,0xa0,0x00,0x07,0x00,0x00,0x00,0x00,0x8f,0x82,0x8c,0x84,0x8d,0x03,0x00,0x00, +0x24,0x42,0x04,0x00,0x00,0x62,0x18,0x2b,0x14,0x60,0xff,0xd9,0x00,0x00,0x00,0x00, +0x0c,0x00,0x05,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x06,0x4c,0x00,0x00,0x00,0x00, +0x97,0x82,0x8c,0x82,0x3c,0x03,0xb0,0x03,0x14,0x40,0x00,0x09,0x34,0x63,0x01,0x08, +0x8c,0x62,0x00,0x00,0x8f,0x83,0x8c,0x7c,0xa7,0x80,0x8c,0x80,0xaf,0x82,0x8c,0x84, +0xac,0x60,0x00,0x00,0x8f,0x82,0x8c,0x7c,0x00,0x00,0x00,0x00,0xac,0x40,0x00,0x04, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00, +0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24, +0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08, +0x00,0x44,0x10,0x25,0x80,0x82,0x00,0x00,0x90,0x83,0x00,0x00,0x10,0x40,0x00,0x0c, +0x00,0x80,0x28,0x21,0x24,0x62,0xff,0x9f,0x30,0x42,0x00,0xff,0x2c,0x42,0x00,0x1a, +0x10,0x40,0x00,0x02,0x24,0x63,0xff,0xe0,0xa0,0xa3,0x00,0x00,0x24,0xa5,0x00,0x01, +0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xf6,0x00,0x40,0x18,0x21, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x80,0x82,0x00,0x00,0x90,0x83,0x00,0x00, +0x10,0x40,0x00,0x0c,0x00,0x80,0x28,0x21,0x24,0x62,0xff,0xbf,0x30,0x42,0x00,0xff, +0x2c,0x42,0x00,0x1a,0x10,0x40,0x00,0x02,0x24,0x63,0x00,0x20,0xa0,0xa3,0x00,0x00, +0x24,0xa5,0x00,0x01,0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xf6, +0x00,0x40,0x18,0x21,0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x27,0xbd,0xff,0xe8, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x24,0x10,0xff,0xff,0x0c,0x00,0x2d,0x94, +0x00,0x00,0x00,0x00,0x10,0x50,0xff,0xfd,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03, +0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x27,0xbd,0xff,0xc8,0xaf,0xb3,0x00,0x1c,0x00,0x00,0x98,0x21,0xaf,0xb1,0x00,0x14, +0x02,0x65,0x88,0x2b,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x34,0xaf,0xbe,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb4,0x00,0x20, +0xaf,0xb2,0x00,0x18,0x00,0xa0,0xb0,0x21,0xaf,0xa4,0x00,0x38,0x00,0xc0,0xa8,0x21, +0x12,0x20,0x00,0x17,0x00,0x80,0x80,0x21,0x24,0x17,0xff,0xff,0x24,0x1e,0x00,0x0a, +0x0c,0x00,0x2d,0x94,0x00,0x00,0x00,0x00,0x10,0x57,0x00,0x0f,0x00,0x02,0x16,0x00, +0x00,0x02,0x26,0x03,0x10,0x9e,0x00,0x0e,0x24,0x02,0x00,0x0d,0x10,0x82,0x00,0x34, +0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x25,0x24,0x02,0x00,0x09,0x10,0x82,0x00,0x13, +0x00,0x00,0x90,0x21,0xa2,0x04,0x00,0x00,0x26,0x73,0x00,0x01,0x16,0xa0,0x00,0x0b, +0x26,0x10,0x00,0x01,0x02,0x76,0x88,0x2b,0x16,0x20,0xff,0xed,0x00,0x00,0x00,0x00, +0x7b,0xbe,0x01,0xbc,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x0c,0x00,0x2d,0x87, +0x02,0x76,0x88,0x2b,0x08,0x00,0x06,0xe6,0x00,0x00,0x00,0x00,0x24,0x14,0x00,0x20, +0xa2,0x14,0x00,0x00,0x26,0x52,0x00,0x01,0x24,0x04,0x00,0x20,0x26,0x73,0x00,0x01, +0x16,0xa0,0x00,0x06,0x26,0x10,0x00,0x01,0x2a,0x42,0x00,0x08,0x10,0x40,0xff,0xea, +0x02,0x76,0x88,0x2b,0x08,0x00,0x06,0xf5,0xa2,0x14,0x00,0x00,0x0c,0x00,0x2d,0x87, +0x00,0x00,0x00,0x00,0x08,0x00,0x06,0xfb,0x2a,0x42,0x00,0x08,0x8f,0xa2,0x00,0x38, +0x00,0x00,0x00,0x00,0x12,0x02,0xff,0xe0,0x00,0x00,0x00,0x00,0x26,0x10,0xff,0xff, +0x12,0xa0,0xff,0xdc,0x26,0x73,0xff,0xff,0x0c,0x00,0x2d,0x87,0x24,0x04,0x00,0x08, +0x0c,0x00,0x2d,0x87,0x24,0x04,0x00,0x20,0x08,0x00,0x06,0xef,0x24,0x04,0x00,0x08, +0x08,0x00,0x06,0xe8,0xa2,0x00,0x00,0x00,0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x1e,0x00,0x10,0x60,0x00,0x16,0x00,0x00,0x30,0x21,0x24,0x07,0x00,0x20, +0x00,0x03,0x1e,0x03,0x10,0x67,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x15, +0x00,0x00,0x00,0x00,0x10,0x67,0x00,0x0b,0x24,0xc6,0x00,0x01,0x10,0x60,0x00,0x0a, +0x00,0x02,0x1e,0x00,0x24,0x05,0x00,0x20,0x24,0x84,0x00,0x01,0x80,0x83,0x00,0x00, +0x90,0x82,0x00,0x00,0x10,0x65,0x00,0x03,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xfa, +0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,0x14,0x60,0xff,0xed,0x00,0x00,0x00,0x00, +0x28,0xc3,0x00,0x08,0x24,0x02,0x00,0x07,0x00,0x43,0x30,0x0a,0x03,0xe0,0x00,0x08, +0x00,0xc0,0x10,0x21,0x24,0x84,0x00,0x01,0x90,0x82,0x00,0x00,0x08,0x00,0x07,0x2a, +0x00,0x02,0x1e,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb1,0x00,0x14,0x27,0x91,0x8c,0x88, +0xaf,0xb0,0x00,0x10,0x24,0x06,0x00,0x20,0x00,0x80,0x80,0x21,0x00,0x00,0x28,0x21, +0xaf,0xbf,0x00,0x18,0x0c,0x00,0x30,0xce,0x02,0x20,0x20,0x21,0x82,0x02,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1f,0x00,0x00,0x30,0x21,0x02,0x20,0x20,0x21, +0x24,0x09,0x00,0x20,0x24,0x08,0x00,0x20,0x24,0x07,0x00,0x08,0xac,0x90,0x00,0x00, +0x82,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x49,0x00,0x0a,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x08,0x24,0x03,0x00,0x20,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x03,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfa, +0x00,0x00,0x00,0x00,0xa2,0x00,0x00,0x00,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00, +0x92,0x03,0x00,0x00,0x10,0x48,0x00,0x0c,0x24,0x05,0x00,0x20,0x24,0xc6,0x00,0x01, +0x10,0xc7,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x03,0x16,0x00,0x14,0x40,0xff,0xe7, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x27,0x82,0x8c,0x88, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00, +0x92,0x03,0x00,0x00,0x10,0x45,0xff,0xfc,0x00,0x00,0x00,0x00,0x08,0x00,0x07,0x5c, +0x24,0xc6,0x00,0x01,0x00,0x80,0x30,0x21,0x90,0x84,0x00,0x00,0x00,0x00,0x38,0x21, +0x10,0x80,0x00,0x19,0x24,0xc6,0x00,0x01,0x24,0x82,0xff,0xd0,0x30,0x42,0x00,0xff, +0x2c,0x43,0x00,0x0a,0x14,0x60,0x00,0x0c,0x00,0x07,0x19,0x00,0x24,0x83,0xff,0x9f, +0x24,0x82,0xff,0xa9,0x24,0x88,0xff,0xc9,0x2c,0x63,0x00,0x06,0x24,0x84,0xff,0xbf, +0x2c,0x84,0x00,0x06,0x14,0x60,0x00,0x03,0x30,0x42,0x00,0xff,0x10,0x80,0x00,0x0e, +0x31,0x02,0x00,0xff,0x00,0x07,0x19,0x00,0x00,0x62,0x18,0x21,0x00,0x67,0x10,0x2b, +0x14,0x40,0x00,0x07,0x00,0x00,0x20,0x21,0x90,0xc4,0x00,0x00,0x00,0x60,0x38,0x21, +0x14,0x80,0xff,0xe9,0x24,0xc6,0x00,0x01,0xac,0xa7,0x00,0x00,0x24,0x04,0x00,0x01, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x07,0x8c,0x00,0x00,0x20,0x21, +0x00,0x00,0x20,0x21,0x27,0x85,0x94,0xc0,0x24,0x82,0x00,0x01,0x00,0x04,0x18,0x80, +0x30,0x44,0x00,0xff,0x00,0x65,0x18,0x21,0x2c,0x82,0x00,0x0b,0x14,0x40,0xff,0xfa, +0xac,0x60,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x84,0x8d,0x08, +0xaf,0x85,0x8d,0x0c,0xaf,0x86,0x8d,0x10,0xaf,0x87,0x8d,0x14,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x98,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, +0x2c,0x43,0x00,0x64,0x24,0x42,0x00,0x01,0x27,0x84,0x8c,0xa8,0xaf,0x82,0x84,0x98, +0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0xaf,0x80,0x84,0x98,0x0c,0x00,0x07,0xf6, +0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,0x28,0x44,0x00,0x08,0x24,0x02,0x00,0x07, +0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x80,0xff,0xf3,0x24,0x02,0x00,0x08, +0x27,0x84,0x8c,0xa8,0x14,0x62,0xff,0xf0,0x00,0x00,0x00,0x00,0x0c,0x00,0x1a,0x7e, +0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0xa8,0x0c,0x00,0x08,0x54,0x00,0x00,0x00,0x00, +0x8f,0x83,0x84,0x9c,0x3c,0x04,0x80,0x01,0x00,0x60,0x28,0x21,0x24,0x63,0x00,0x01, +0xaf,0x83,0x84,0x9c,0x0c,0x00,0x1a,0x6b,0x24,0x84,0x04,0x90,0x08,0x00,0x07,0xaa, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xbf,0x00,0x38,0x8c,0x85,0x00,0x0c, +0x8c,0x88,0x00,0x08,0x18,0xa0,0x00,0x0e,0x00,0x00,0x30,0x21,0x24,0x87,0x00,0x08, +0x27,0xa9,0x00,0x10,0x00,0x06,0x10,0x80,0x00,0x06,0x19,0x00,0x00,0x49,0x10,0x21, +0x14,0xc0,0x00,0x1f,0x00,0x83,0x18,0x21,0xaf,0xa7,0x00,0x10,0x24,0xc2,0x00,0x01, +0x30,0x46,0x00,0xff,0x00,0xc5,0x18,0x2a,0x14,0x60,0xff,0xf7,0x00,0x06,0x10,0x80, +0x29,0x02,0x00,0x0a,0x14,0x40,0x00,0x05,0x00,0x08,0x18,0x40,0x8f,0xbf,0x00,0x38, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x00,0x68,0x18,0x21, +0x27,0x82,0x83,0x94,0x00,0x03,0x18,0xc0,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x10, +0x01,0x00,0x20,0x21,0x00,0x40,0xf8,0x09,0x27,0xa6,0x00,0x10,0x8f,0x83,0x84,0xb0, +0x3c,0x04,0x80,0x01,0x00,0x60,0x28,0x21,0x24,0x63,0x00,0x01,0xaf,0x83,0x84,0xb0, +0x0c,0x00,0x1a,0x6b,0x24,0x84,0x04,0xa4,0x08,0x00,0x07,0xdf,0x00,0x00,0x00,0x00, +0x08,0x00,0x07,0xd7,0xac,0x43,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb1,0x00,0x14, +0xaf,0xbf,0x00,0x18,0x00,0x80,0x88,0x21,0x0c,0x00,0x1a,0xa2,0xaf,0xb0,0x00,0x10, +0x00,0x40,0x20,0x21,0x24,0x02,0xff,0xff,0x10,0x82,0x00,0x1f,0x24,0x03,0x00,0x06, +0x8f,0x85,0x84,0xc4,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x0a,0x24,0x02,0x00,0x08, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x3b,0x28,0x82,0x00,0x03,0x10,0x40,0x00,0x32, +0x24,0x02,0x00,0x1b,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x13,0x24,0x03,0x00,0x08, +0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x23,0x24,0x02,0x00,0x0d,0x10,0x82,0x00,0x18, +0x02,0x25,0x10,0x21,0x24,0xa3,0x00,0x01,0xa0,0x44,0x00,0x00,0xaf,0x83,0x84,0xc4, +0x18,0x60,0x00,0x08,0x24,0x02,0x00,0x43,0x82,0x23,0x00,0x00,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x0a,0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x0c,0x00,0x1a,0x9e, +0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x06,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x04,0x80,0x01, +0x0c,0x00,0x1a,0x7e,0x24,0x84,0x04,0xb8,0x08,0x00,0x08,0x1e,0x24,0x03,0x00,0x06, +0xa0,0x40,0x00,0x00,0x24,0xa5,0x00,0x01,0xaf,0x85,0x84,0xc4,0x0c,0x00,0x1a,0x9e, +0x24,0x04,0x00,0x0d,0x24,0x03,0x00,0x07,0xaf,0x80,0x84,0xc4,0x08,0x00,0x08,0x1e, +0x00,0x00,0x00,0x00,0x18,0xa0,0xff,0xeb,0x24,0xa5,0xff,0xff,0xaf,0x85,0x84,0xc4, +0x0c,0x00,0x1a,0x9e,0x24,0x04,0x00,0x08,0x0c,0x00,0x1a,0x9e,0x24,0x04,0x00,0x20, +0x08,0x00,0x08,0x1b,0x24,0x04,0x00,0x08,0x14,0x82,0xff,0xd2,0x24,0x02,0x00,0x08, +0x0c,0x00,0x07,0x90,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0xc4,0x08,0x00,0x08,0x0c, +0x24,0x04,0x00,0x0d,0x0c,0x00,0x30,0x54,0x02,0x20,0x20,0x21,0xaf,0x82,0x84,0xc4, +0x04,0x40,0x00,0x0d,0x00,0x00,0x80,0x21,0x02,0x30,0x10,0x21,0x90,0x44,0x00,0x00, +0x26,0x10,0x00,0x01,0x00,0x04,0x26,0x00,0x00,0x04,0x26,0x03,0x0c,0x00,0x1a,0x9e, +0x30,0x84,0xff,0xff,0x8f,0x83,0x84,0xc4,0x00,0x00,0x00,0x00,0x00,0x70,0x18,0x2a, +0x10,0x60,0xff,0xf6,0x02,0x30,0x10,0x21,0x08,0x00,0x08,0x2e,0x24,0x03,0x00,0x06, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x27,0x83,0x8c,0xe8,0x24,0x02,0x00,0x07, +0x24,0x42,0xff,0xff,0xac,0x60,0x00,0x00,0x04,0x41,0xff,0xfd,0x24,0x63,0x00,0x04, +0x0c,0x00,0x08,0x66,0x00,0x00,0x00,0x00,0x8f,0x84,0x8c,0xe8,0x27,0x86,0x8c,0xe8, +0x0c,0x00,0x08,0x83,0x00,0x40,0x28,0x21,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe0,0x00,0x80,0x28,0x21, +0x27,0x84,0x8c,0xc8,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0x0c,0x00,0x30,0xe5, +0xaf,0xb0,0x00,0x10,0x8f,0x85,0x83,0x34,0x27,0x84,0x8c,0xc8,0x0c,0x00,0x30,0xa9, +0x00,0x00,0x88,0x21,0x10,0x40,0x00,0x0c,0x00,0x00,0x00,0x00,0x27,0x90,0x8c,0xe8, +0x8f,0x85,0x83,0x34,0x00,0x00,0x20,0x21,0xae,0x02,0x00,0x00,0x0c,0x00,0x30,0xa9, +0x26,0x31,0x00,0x01,0x26,0x10,0x00,0x04,0x10,0x40,0x00,0x03,0x2a,0x23,0x00,0x64, +0x14,0x60,0xff,0xf7,0x00,0x00,0x00,0x00,0x02,0x20,0x10,0x21,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd0, +0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xbf,0x00,0x2c, +0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x00,0xa0,0xa8,0x21,0x00,0x80,0xa0,0x21,0x00,0xc0,0xb0,0x21,0x10,0xa0,0x00,0x1d, +0x24,0x02,0x00,0x05,0x3c,0x02,0x80,0x00,0x24,0x43,0x2c,0x80,0x8f,0x82,0x83,0xa4, +0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x1e,0x00,0x00,0x88,0x21,0x00,0x60,0x98,0x21, +0x00,0x00,0x90,0x21,0x27,0x90,0x83,0xa4,0x8e,0x05,0xff,0xec,0x02,0x80,0x20,0x21, +0x0c,0x00,0x30,0xed,0x26,0x10,0x00,0x18,0x10,0x40,0x00,0x06,0x02,0x51,0x18,0x21, +0x8e,0x02,0x00,0x00,0x26,0x31,0x00,0x01,0x14,0x53,0xff,0xf7,0x00,0x11,0x90,0x40, +0x02,0x51,0x18,0x21,0x27,0x82,0x83,0x94,0x00,0x03,0x18,0xc0,0x00,0x62,0x18,0x21, +0x8c,0x62,0x00,0x10,0x02,0x20,0x20,0x21,0x02,0xa0,0x28,0x21,0x00,0x40,0xf8,0x09, +0x02,0xc0,0x30,0x21,0x8f,0xbf,0x00,0x2c,0x8f,0xb6,0x00,0x28,0x7b,0xb4,0x01,0x3c, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x08,0x00,0x08,0xa4,0x00,0x00,0x90,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xb5,0x00,0x34, +0xaf,0xb3,0x00,0x2c,0xaf,0xb1,0x00,0x24,0xaf,0xbf,0x00,0x38,0xaf,0xb4,0x00,0x30, +0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,0x00,0xc0,0x98,0x21,0x30,0xa5,0x00,0xff, +0xac,0xc0,0x00,0x00,0x24,0x15,0x00,0x0a,0x00,0x00,0x88,0x21,0x27,0xa8,0x00,0x10, +0x00,0x91,0x18,0x21,0x80,0x62,0x00,0x00,0x26,0x27,0x00,0x01,0x10,0x40,0x00,0x0c, +0x01,0x11,0x30,0x21,0x90,0x63,0x00,0x00,0x30,0xf1,0x00,0xff,0x2e,0x22,0x00,0x0a, +0x14,0x40,0xff,0xf7,0xa0,0xc3,0x00,0x00,0x8f,0xbf,0x00,0x38,0x7b,0xb4,0x01,0xbc, +0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40, +0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x23,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x1f, +0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x1a,0x00,0x00,0x00,0x00,0x02,0x20,0x90,0x21, +0x12,0x40,0xff,0xf1,0x00,0x00,0x88,0x21,0x27,0xb4,0x00,0x10,0x02,0x91,0x10,0x21, +0x90,0x44,0x00,0x00,0x0c,0x00,0x09,0x0a,0x00,0x00,0x00,0x00,0x02,0x51,0x20,0x23, +0x24,0x84,0xff,0xff,0x30,0x84,0x00,0xff,0x02,0xa0,0x28,0x21,0x0c,0x00,0x08,0xfb, +0x00,0x40,0x80,0x21,0x02,0x02,0x00,0x18,0x8e,0x63,0x00,0x00,0x26,0x22,0x00,0x01, +0x30,0x51,0x00,0xff,0x02,0x32,0x20,0x2b,0x00,0x00,0x80,0x12,0x00,0x70,0x18,0x21, +0x14,0x80,0xff,0xee,0xae,0x63,0x00,0x00,0x08,0x00,0x08,0xce,0x00,0x00,0x00,0x00, +0x80,0x82,0x00,0x00,0x08,0x00,0x08,0xce,0xae,0x62,0x00,0x00,0x08,0x00,0x08,0xdb, +0x24,0x15,0x00,0x10,0x08,0x00,0x08,0xdb,0x24,0x15,0x00,0x0a,0x30,0x84,0x00,0xff, +0x30,0xa5,0x00,0xff,0x24,0x06,0x00,0x01,0x10,0x80,0x00,0x09,0x00,0x00,0x10,0x21, +0x00,0xc5,0x00,0x18,0x24,0x42,0x00,0x01,0x30,0x42,0x00,0xff,0x00,0x44,0x18,0x2b, +0x00,0x00,0x30,0x12,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xfa,0x00,0xc5,0x00,0x18, +0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x30,0x84,0x00,0xff,0x24,0x83,0xff,0xd0, +0x30,0x62,0x00,0xff,0x2c,0x42,0x00,0x0a,0x14,0x40,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0x82,0xff,0xbf,0x2c,0x42,0x00,0x06,0x14,0x40,0x00,0x02,0x24,0x83,0xff,0xc9, +0x24,0x83,0xff,0xa9,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xc8, +0x24,0x02,0x00,0x01,0xaf,0xbf,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, +0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x10,0xa2,0x00,0x3e, +0xaf,0xb0,0x00,0x18,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08,0x24,0x05,0x00,0x01, +0x00,0x00,0x10,0x21,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, +0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8c,0xc4,0x00,0x04, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x10,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00, +0x28,0x42,0x00,0x65,0x14,0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x04,0x80,0x01, +0x0c,0x00,0x1a,0x7e,0x24,0x84,0x04,0xbc,0x08,0x00,0x09,0x25,0x24,0x02,0x00,0x01, +0x3c,0x04,0x80,0x01,0x0c,0x00,0x1a,0x7e,0x24,0x84,0x04,0xc8,0x8f,0x83,0x83,0xa4, +0x3c,0x02,0x80,0x00,0x24,0x42,0x2c,0x80,0x10,0x62,0xff,0xe5,0x00,0x40,0x90,0x21, +0x3c,0x13,0x80,0x01,0x27,0x95,0x83,0x90,0x3c,0x14,0x80,0x01,0x27,0x90,0x83,0x94, +0x00,0x00,0x88,0x21,0x8e,0x03,0x00,0x08,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x08,0x26,0x64,0x04,0xd4,0x26,0x10,0x00,0x18,0x8e,0x02,0x00,0x10, +0x00,0x00,0x00,0x00,0x14,0x52,0xff,0xf7,0x26,0x31,0x00,0x18,0x08,0x00,0x09,0x25, +0x00,0x00,0x10,0x21,0x0c,0x00,0x1a,0x7e,0x00,0x00,0x00,0x00,0x02,0x35,0x10,0x21, +0x8c,0x44,0x00,0x00,0x0c,0x00,0x1a,0x7e,0x00,0x00,0x00,0x00,0x0c,0x00,0x1a,0x7e, +0x26,0x84,0x04,0xd8,0x8e,0x04,0x00,0x00,0x0c,0x00,0x1a,0x7e,0x26,0x10,0x00,0x18, +0x08,0x00,0x09,0x4b,0x00,0x00,0x00,0x00,0x3c,0x04,0x80,0x01,0x0c,0x00,0x1a,0x7e, +0x24,0x84,0x04,0xdc,0x3c,0x04,0x80,0x01,0x0c,0x00,0x1a,0x6b,0x24,0x84,0x04,0xec, +0x24,0x11,0x00,0x05,0x3c,0x12,0x80,0x01,0x27,0x90,0x88,0x0e,0x86,0x05,0x00,0x00, +0x26,0x44,0x05,0x0c,0x0c,0x00,0x1a,0x6b,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xfb, +0x26,0x10,0xff,0xfe,0x08,0x00,0x09,0x25,0x00,0x00,0x10,0x21,0x27,0xbd,0xff,0xd0, +0x28,0xa2,0x00,0x02,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x2c, +0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0x00,0xa0,0x80,0x21, +0x14,0x40,0x00,0x51,0x00,0xc0,0x88,0x21,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x02, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x10,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x48, +0x24,0x05,0x00,0x01,0x8e,0x24,0x00,0x08,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x14, +0x8f,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x30,0x42,0x0f,0xff,0xaf,0xa2,0x00,0x14, +0x7b,0xa4,0x00,0xbc,0x0c,0x00,0x0a,0x06,0x24,0x06,0x00,0x04,0x24,0x03,0x00,0x04, +0x10,0x43,0x00,0x2a,0x24,0x04,0x00,0x04,0x8f,0xa2,0x00,0x10,0x3c,0x04,0x80,0x01, +0x24,0x84,0x05,0x10,0x00,0x02,0x19,0x02,0x00,0x03,0x81,0x00,0x8f,0xa3,0x00,0x14, +0x00,0x50,0x10,0x23,0x00,0x02,0x10,0x82,0x00,0x62,0x18,0x21,0x0c,0x00,0x1a,0x7e, +0xaf,0xa3,0x00,0x14,0x3c,0x04,0x80,0x01,0x0c,0x00,0x1a,0x7e,0x24,0x84,0x05,0x38, +0x8f,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x00,0x00,0x88,0x21, +0x3c,0x13,0x80,0x01,0x3c,0x12,0x80,0x01,0x3c,0x14,0x80,0x01,0x0c,0x00,0x2e,0x24, +0x24,0x04,0x27,0x10,0x32,0x23,0x00,0x03,0x02,0x00,0x28,0x21,0x10,0x60,0x00,0x1c, +0x26,0x64,0x05,0x64,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x23, +0x28,0x42,0xff,0xfd,0x10,0x40,0x00,0x10,0x26,0x44,0x05,0x70,0x0c,0x00,0x1a,0x7e, +0x26,0x10,0x00,0x04,0x8f,0xa2,0x00,0x14,0x26,0x31,0x00,0x01,0x02,0x22,0x10,0x2b, +0x14,0x40,0xff,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x21,0x8f,0xbf,0x00,0x2c, +0x8f,0xb4,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x00,0x80,0x10,0x21, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x8e,0x05,0x00,0x00,0x26,0x84,0x05,0x74, +0x0c,0x00,0x1a,0x6b,0x26,0x10,0x00,0x04,0x08,0x00,0x09,0xb1,0x00,0x00,0x00,0x00, +0x0c,0x00,0x1a,0x6b,0x00,0x00,0x00,0x00,0x08,0x00,0x09,0xa9,0x00,0x00,0x00,0x00, +0x08,0x00,0x09,0x87,0x24,0x02,0x00,0x01,0x0c,0x00,0x0b,0x2b,0x00,0x00,0x00,0x00, +0x08,0x00,0x09,0xb7,0x24,0x04,0x00,0x04,0x27,0xbd,0xff,0xd0,0x28,0xa2,0x00,0x03, +0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0xaf,0xbf,0x00,0x28,0x00,0xa0,0x88,0x21, +0x10,0x40,0x00,0x09,0x00,0xc0,0x80,0x21,0x0c,0x00,0x0b,0x2b,0x00,0x00,0x00,0x00, +0x24,0x04,0x00,0x04,0x8f,0xbf,0x00,0x28,0x7b,0xb0,0x01,0x3c,0x00,0x80,0x10,0x21, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x02, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x10,0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x02, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x14,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x1b, +0x24,0x05,0x00,0x01,0x8e,0x04,0x00,0x0c,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x18, +0x8f,0xa4,0x00,0x10,0x8f,0xa5,0x00,0x18,0x0c,0x00,0x0a,0x06,0x24,0x06,0x00,0x04, +0x24,0x03,0x00,0x04,0x10,0x43,0xff,0xe7,0x24,0x04,0x00,0x04,0x8f,0xa2,0x00,0x18, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,0x00,0x00,0x28,0x21,0x8f,0xa2,0x00,0x10, +0x8f,0xa4,0x00,0x14,0x24,0xa5,0x00,0x01,0xac,0x44,0x00,0x00,0x8f,0xa3,0x00,0x10, +0x8f,0xa2,0x00,0x18,0x24,0x63,0x00,0x04,0x00,0xa2,0x10,0x2b,0x14,0x40,0xff,0xf7, +0xaf,0xa3,0x00,0x10,0x08,0x00,0x09,0xd9,0x00,0x00,0x20,0x21,0x24,0x02,0x00,0x01, +0x08,0x00,0x09,0xec,0xaf,0xa2,0x00,0x18,0x30,0xc6,0x00,0xff,0x00,0xa6,0x00,0x18, +0x00,0x00,0x28,0x12,0x04,0x81,0x00,0x07,0x00,0x00,0x30,0x21,0x3c,0x02,0x80,0x01, +0x00,0x85,0x18,0x21,0x34,0x42,0x7f,0xff,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x0b, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xaf,0xff,0x34,0x42,0xff,0xff,0x00,0x44,0x10,0x2b, +0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x0a,0x00,0x85,0x18,0x21,0x34,0x42,0xff,0xff, +0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0xff,0xff, +0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x06,0x3c,0x02,0xb0,0x07,0x3c,0x02,0xb0,0x04, +0x34,0x42,0xff,0xff,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x09,0x3c,0x02,0xb0,0x07, +0x34,0x42,0x00,0x3f,0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x06,0x3c,0x02,0xb0,0x07, +0x34,0x42,0xff,0xff,0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x02,0x00,0x00,0x00,0x00, +0x24,0x06,0x00,0x01,0x14,0xc0,0x00,0x11,0x24,0x02,0x00,0x04,0x3c,0x02,0xb0,0x08, +0x34,0x42,0x0f,0xff,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x08,0x3c,0x02,0x4f,0xf7, +0x00,0x85,0x20,0x21,0x34,0x42,0xf0,0x00,0x00,0x82,0x20,0x21,0x34,0x03,0xef,0xff, +0x00,0x64,0x18,0x2b,0x14,0x60,0x00,0x02,0x00,0x00,0x00,0x00,0x24,0x06,0x00,0x02, +0x10,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,0x24,0x02,0x00,0x02,0xaf,0xb0,0x00,0x18, +0xaf,0xbf,0x00,0x1c,0x10,0xa2,0x00,0x23,0x00,0xc0,0x80,0x21,0x28,0xa2,0x00,0x03, +0x10,0x40,0x00,0x0c,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x04, +0x00,0x00,0x18,0x21,0x0c,0x00,0x0b,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21, +0x8f,0xbf,0x00,0x1c,0x8f,0xb0,0x00,0x18,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x14,0xa2,0xff,0xf7,0x24,0x05,0x00,0x01,0x8c,0xc4,0x00,0x04, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x10,0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x02, +0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x14,0x8f,0xa4,0x00,0x10,0x00,0x00,0x00,0x00, +0x2c,0x82,0x00,0x0b,0x10,0x40,0xff,0xee,0x24,0x03,0x00,0x04,0x00,0x04,0x10,0x80, +0x8f,0xa4,0x00,0x14,0x27,0x83,0x94,0xc0,0x00,0x43,0x10,0x21,0x08,0x00,0x0a,0x4f, +0xac,0x44,0x00,0x00,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6, +0x27,0xa6,0x00,0x10,0x8f,0xa5,0x00,0x10,0x27,0x83,0x94,0xc0,0x3c,0x04,0x80,0x01, +0x00,0x05,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x46,0x00,0x00,0x0c,0x00,0x1a,0x6b, +0x24,0x84,0x05,0x7c,0x08,0x00,0x0a,0x50,0x00,0x00,0x18,0x21,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xb8,0x28,0xa5,0x00,0x04,0xaf,0xb0,0x00,0x20, +0xaf,0xbf,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,0xaf,0xb5,0x00,0x34, +0xaf,0xb4,0x00,0x30,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb1,0x00,0x24, +0x10,0xa0,0x00,0x0b,0x00,0xc0,0x80,0x21,0x0c,0x00,0x0b,0x2b,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x40,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc, +0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48, +0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x10, +0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x14, +0x8e,0x04,0x00,0x0c,0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x18, +0x8f,0xa3,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x3a,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x33,0x3c,0x04,0x80,0x01,0x97,0xb0,0x00,0x12,0x8f,0xa2,0x00,0x14, +0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x2b,0x10,0x40,0xff,0xe2,0x3c,0x15,0x80,0x01, +0x3c,0x02,0x80,0x01,0x24,0x52,0x05,0xbc,0x3c,0x14,0xb0,0x06,0x24,0x13,0x00,0x01, +0x3c,0x17,0xb0,0x08,0x3c,0x16,0x80,0x01,0x32,0x02,0x00,0x01,0x02,0x00,0x28,0x21, +0x10,0x40,0x00,0x1f,0x26,0xa4,0x05,0xb0,0x8f,0xa3,0x00,0x18,0x00,0x10,0x10,0xc0, +0x00,0x54,0x10,0x21,0x10,0x60,0x00,0x14,0x02,0x40,0x20,0x21,0x00,0x10,0x10,0xc0, +0x00,0x57,0x10,0x21,0x10,0x73,0x00,0x09,0x26,0xc4,0x05,0xc4,0x8f,0xa2,0x00,0x14, +0x26,0x03,0x00,0x01,0x30,0x70,0xff,0xff,0x02,0x02,0x10,0x2b,0x14,0x40,0xff,0xee, +0x00,0x00,0x00,0x00,0x08,0x00,0x0a,0x8d,0x00,0x00,0x00,0x00,0x8c,0x51,0x00,0x00, +0x00,0x00,0x00,0x00,0x32,0x25,0x00,0xff,0x0c,0x00,0x1a,0x6b,0x00,0x00,0x00,0x00, +0x08,0x00,0x0a,0xbf,0x00,0x00,0x00,0x00,0x8c,0x51,0x00,0x00,0x0c,0x00,0x1a,0x6b, +0x00,0x11,0x2c,0x02,0x32,0x25,0x00,0xff,0x08,0x00,0x0a,0xca,0x02,0x40,0x20,0x21, +0x0c,0x00,0x1a,0x6b,0x00,0x00,0x00,0x00,0x08,0x00,0x0a,0xb6,0x00,0x00,0x00,0x00, +0x24,0x84,0x05,0x90,0x0c,0x00,0x1a,0x7e,0x00,0x00,0x00,0x00,0x08,0x00,0x0a,0xa6, +0x00,0x00,0x00,0x00,0x3c,0x04,0x80,0x01,0x08,0x00,0x0a,0xd9,0x24,0x84,0x05,0xd0, +0x00,0xa0,0x10,0x21,0x27,0xbd,0xff,0xd8,0x28,0x42,0x00,0x04,0xaf,0xb0,0x00,0x20, +0xaf,0xbf,0x00,0x24,0x00,0xc0,0x80,0x21,0x24,0x05,0x00,0x01,0x10,0x40,0x00,0x08, +0x27,0xa6,0x00,0x10,0x0c,0x00,0x0b,0x2b,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04, +0x8f,0xbf,0x00,0x24,0x8f,0xb0,0x00,0x20,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x8e,0x04,0x00,0x04,0x0c,0x00,0x08,0xb6,0x00,0x00,0x00,0x00,0x8e,0x04,0x00,0x08, +0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x14,0x8e,0x04,0x00,0x0c, +0x24,0x05,0x00,0x01,0x0c,0x00,0x08,0xb6,0x27,0xa6,0x00,0x18,0x08,0x00,0x0a,0xec, +0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x01,0x00,0x65,0x10,0x2a,0x27,0xbd,0xff,0xd8, +0x00,0xa0,0x40,0x21,0x10,0x40,0x00,0x0b,0x00,0xc0,0x38,0x21,0x00,0x03,0x20,0x80, +0x00,0x87,0x10,0x21,0x8c,0x45,0x00,0x00,0x24,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x8c,0xa6,0x00,0x00,0x00,0x9d,0x20,0x21,0x00,0x68,0x10,0x2a,0x14,0x40,0xff,0xf7, +0xac,0x86,0xff,0xfc,0x8f,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x0b, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x93,0xa2,0x00,0x07,0x00,0x00,0x00,0x00, +0xa3,0x82,0x87,0x6c,0x08,0x00,0x0b,0x14,0x00,0x00,0x00,0x00,0x93,0xa2,0x00,0x07, +0x00,0x00,0x00,0x00,0xa3,0x82,0x94,0xb0,0x08,0x00,0x0b,0x14,0x00,0x00,0x00,0x00, +0x27,0xbd,0xff,0xe8,0x3c,0x04,0x80,0x01,0xaf,0xbf,0x00,0x10,0x18,0xa0,0x00,0x03, +0x24,0x84,0x05,0xf8,0x0c,0x00,0x1a,0x7e,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe8, +0xaf,0xb0,0x00,0x10,0x00,0x80,0x80,0x21,0x3c,0x04,0x80,0x01,0xaf,0xbf,0x00,0x14, +0x0c,0x00,0x1a,0x7e,0x24,0x84,0x06,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x27,0x83,0x83,0x90,0x00,0x02,0x10,0xc0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08, +0x0c,0x00,0x1a,0x7e,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x2c,0xf8,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00, +0x34,0x84,0x00,0x2c,0x8c,0x86,0x00,0x00,0x3c,0x05,0xb0,0x0a,0x34,0xa5,0x1a,0x00, +0x00,0x06,0x1a,0x02,0x30,0x63,0x0f,0xff,0x00,0x06,0x25,0x02,0x24,0x02,0xff,0xff, +0xac,0xa2,0x00,0x00,0xa7,0x83,0xc5,0x4a,0xa7,0x84,0xc5,0x4c,0xa3,0x86,0xc5,0x48, +0xa7,0x80,0xc5,0x40,0xa7,0x80,0xc5,0x42,0xa7,0x80,0xc5,0x44,0xa7,0x80,0xc5,0x46, +0x00,0xa0,0x38,0x21,0x24,0x03,0x00,0x01,0x8c,0xe2,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x0a,0x00,0x8c,0x45,0x00,0x00, +0x3c,0x04,0xb0,0x0a,0x34,0x84,0x1a,0x00,0xa0,0x45,0x00,0x00,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x0a,0x00,0x3c,0x04,0xb0,0x0a,0xa0,0x45,0x00,0x00,0x34,0x84,0x1a,0x00, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x34,0x63,0x01,0x08, +0x34,0x84,0x01,0x18,0x8c,0x65,0x00,0x00,0x8c,0x82,0x00,0x00,0xaf,0x85,0xc5,0x50, +0x30,0x42,0x02,0x00,0x10,0x40,0x00,0x06,0x3c,0x02,0x00,0x0f,0x3c,0x02,0x00,0x4c, +0x34,0x42,0x4b,0x40,0xaf,0x82,0xc5,0x54,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x08,0x00,0x0b,0x79,0x34,0x42,0x42,0x40,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x2d,0xf8,0x30,0x84,0x00,0xff,0xac,0x62,0x00,0x00, +0x14,0x80,0x02,0xb3,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x1b,0x40, +0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x0b,0x40,0x8c,0x46,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x1b,0x48, +0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x00,0x06,0x54,0x02, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x0b,0x48,0x8c,0x46,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x34,0x63,0x1b,0x50,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21, +0x00,0x06,0x64,0x02,0x30,0xcb,0xff,0xff,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x0b,0x50, +0x8c,0x46,0x00,0x00,0x97,0x84,0xc5,0x40,0x97,0x82,0xc5,0x42,0x97,0x83,0xc5,0x46, +0x01,0x44,0x20,0x23,0x01,0x62,0x10,0x23,0x00,0x82,0x20,0x21,0x97,0x82,0xc5,0x44, +0x30,0xcd,0xff,0xff,0x01,0xa3,0x18,0x23,0x01,0x82,0x10,0x23,0x00,0x82,0x20,0x21, +0x93,0x82,0xc5,0x48,0x00,0x83,0x20,0x21,0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b, +0x10,0x40,0x00,0xec,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x18,0xa0,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xa0, +0x8c,0x46,0x00,0x00,0x24,0x02,0x00,0x20,0x30,0xc8,0x00,0x7f,0x11,0x02,0x00,0x4d, +0x2d,0x02,0x00,0x21,0x14,0x40,0x00,0x2b,0x24,0x02,0xff,0x80,0x00,0xc2,0x10,0x24, +0x25,0x08,0xff,0xff,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x08,0xa0,0x00,0x48,0x30,0x25, +0x3c,0x04,0xb0,0x0a,0xac,0x66,0x00,0x00,0x34,0x84,0x18,0xa0,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x08,0xb0,0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xb0, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xc0,0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00, +0x34,0x84,0x18,0xc0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xd0,0x3c,0x04,0xb0,0x0a, +0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xd0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x24,0x02,0x00,0x20,0x11,0x02,0x00,0x07, +0x24,0x02,0xff,0xff,0xa7,0x8a,0xc5,0x40,0xa7,0x8b,0xc5,0x42,0xa7,0x8c,0xc5,0x44, +0xa7,0x8d,0xc5,0x46,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x34,0x63,0x14,0x58,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x04,0x58,0x8c,0x69,0x00,0x00,0x3c,0x02,0xff,0xff, +0x34,0x42,0x3f,0xff,0x01,0x22,0x10,0x24,0x34,0x49,0x80,0x00,0x3c,0x04,0xb0,0x0a, +0xac,0x69,0x00,0x00,0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0xf9, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x58,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x58, +0x8c,0x49,0x00,0x00,0x3c,0x04,0xb0,0x0a,0x34,0x84,0x14,0x58,0x35,0x29,0x40,0x00, +0xac,0x49,0x00,0x00,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x24,0x02,0xff,0xff,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0xb0, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0xb0, +0x8c,0x47,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0xb8,0x3c,0x05,0xb0,0x0a, +0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x34,0xa5,0x14,0xb8,0x00,0x07,0x1e,0x02, +0x24,0x04,0x00,0x01,0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0xb8,0x8c,0x47,0x00,0x00,0x00,0x03,0x1a,0x00, +0x30,0xe2,0x00,0xff,0x00,0x62,0x18,0x25,0x2c,0x62,0x00,0x04,0x10,0x40,0x00,0x3a, +0x2c,0x62,0x00,0x11,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x10,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x10, +0x8c,0x47,0x00,0x00,0x24,0x02,0x00,0x03,0x00,0x07,0x1d,0x82,0x30,0x64,0x00,0x03, +0x10,0x82,0x00,0x1a,0x3c,0x02,0xff,0x3f,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x04,0x58,0x01,0x22,0x48,0x24,0x3c,0x04,0xb0,0x0a, +0xac,0x69,0x00,0x00,0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x35,0x29,0x80,0x00, +0x34,0x42,0x04,0x58,0x3c,0x04,0xb0,0x0a,0xac,0x49,0x00,0x00,0x34,0x84,0x14,0x58, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x2d,0x02,0x00,0x21,0x08,0x00,0x0b,0xcd,0x00,0x00,0x00,0x00,0x34,0x42,0xff,0xff, +0x3c,0x03,0x00,0x80,0x00,0xe2,0x10,0x24,0x00,0x43,0x38,0x25,0x3c,0x04,0xb0,0x0a, +0x3c,0x01,0xb0,0x0a,0xac,0x27,0x04,0x10,0x34,0x84,0x14,0x10,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xff,0xff, +0x08,0x00,0x0c,0x60,0x34,0x42,0x3f,0xff,0x14,0x40,0xff,0xd8,0x3c,0x02,0xff,0xff, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x10,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x10,0x8c,0x47,0x00,0x00, +0x3c,0x05,0x00,0xc0,0x24,0x03,0x00,0x02,0x00,0xe5,0x10,0x24,0x00,0x02,0x25,0x82, +0x14,0x83,0xff,0xc6,0x3c,0x02,0xff,0xff,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xe2,0x10,0x24,0x00,0x45,0x38,0x25,0x3c,0x04,0xb0,0x0a,0x3c,0x01,0xb0,0x0a, +0xac,0x27,0x04,0x10,0x34,0x84,0x14,0x10,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xff,0xff,0x08,0x00,0x0c,0x60, +0x34,0x42,0x3f,0xff,0x97,0x82,0xc5,0x4c,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b, +0x10,0x40,0x00,0x74,0x34,0x63,0x18,0xa0,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xa0,0x8c,0x46,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0xc8,0x00,0x7f,0x2d,0x02,0x00,0x32,0x10,0x40,0xff,0x3d, +0x24,0x02,0x00,0x20,0x11,0x02,0x00,0x2b,0x24,0x02,0xff,0x80,0x00,0xc2,0x10,0x24, +0x25,0x08,0x00,0x02,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x08,0xa0,0x00,0x48,0x30,0x25, +0x3c,0x04,0xb0,0x0a,0xac,0x66,0x00,0x00,0x34,0x84,0x18,0xa0,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x08,0xb0,0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xb0, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xc0,0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00, +0x34,0x84,0x18,0xc0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xd0,0x3c,0x04,0xb0,0x0a, +0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xd0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0xf9, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x10,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x10, +0x8c,0x47,0x00,0x00,0x3c,0x05,0x00,0xc0,0x24,0x03,0x00,0x03,0x00,0xe5,0x10,0x24, +0x00,0x02,0x25,0x82,0x10,0x83,0x00,0x0d,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xe2,0x10,0x24,0x00,0x45,0x38,0x25,0x3c,0x04,0xb0,0x0a,0x3c,0x01,0xb0,0x0a, +0xac,0x27,0x04,0x10,0x34,0x84,0x14,0x10,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x34,0x63,0x14,0x58,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x04,0x58,0x8c,0x69,0x00,0x00, +0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x01,0x22,0x48,0x24,0x3c,0x04,0xb0,0x0a, +0xac,0x69,0x00,0x00,0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x24,0x02,0xff,0x80,0x08,0x00,0x0c,0xc0, +0x00,0xc2,0x10,0x24,0x97,0x82,0xc5,0x4a,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b, +0x10,0x40,0x00,0x75,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x18,0xa0,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xa0, +0x8c,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc8,0x00,0x7f,0x2d,0x02,0x00,0x32, +0x10,0x40,0xfe,0xc4,0x24,0x02,0x00,0x20,0x11,0x02,0x00,0x2b,0x24,0x02,0xff,0x80, +0x00,0xc2,0x10,0x24,0x25,0x08,0x00,0x01,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x08,0xa0, +0x00,0x48,0x30,0x25,0x3c,0x04,0xb0,0x0a,0xac,0x66,0x00,0x00,0x34,0x84,0x18,0xa0, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xb0,0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00, +0x34,0x84,0x18,0xb0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xc0,0x3c,0x04,0xb0,0x0a, +0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xc0,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xd0, +0x3c,0x04,0xb0,0x0a,0xac,0x46,0x00,0x00,0x34,0x84,0x18,0xd0,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00, +0x08,0x00,0x0b,0xf9,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x10, +0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x04,0x10,0x8c,0x47,0x00,0x00,0x3c,0x05,0x00,0xc0,0x24,0x03,0x00,0x03, +0x00,0xe5,0x10,0x24,0x00,0x02,0x25,0x82,0x10,0x83,0x00,0x0d,0x3c,0x02,0xff,0x3f, +0x34,0x42,0xff,0xff,0x00,0xe2,0x10,0x24,0x00,0x45,0x38,0x25,0x3c,0x04,0xb0,0x0a, +0x3c,0x01,0xb0,0x0a,0xac,0x27,0x04,0x10,0x34,0x84,0x14,0x10,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x58,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x04,0x58, +0x8c,0x69,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x01,0x22,0x48,0x24, +0x3c,0x04,0xb0,0x0a,0xac,0x69,0x00,0x00,0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x24,0x02,0xff,0x80, +0x08,0x00,0x0d,0x39,0x00,0xc2,0x10,0x24,0x34,0x63,0x18,0xa0,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x08,0xa0, +0x8c,0x46,0x00,0x00,0x24,0x02,0x00,0x20,0x30,0xc8,0x00,0x7f,0x15,0x02,0xfe,0x51, +0x24,0x02,0xff,0xff,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x58,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x58,0x8c,0x49,0x00,0x00, +0x3c,0x04,0xb0,0x0a,0x34,0x84,0x14,0x58,0x35,0x29,0x40,0x00,0xac,0x49,0x00,0x00, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x24,0x02,0xff,0xff,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0xb0,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0xb0,0x8c,0x47,0x00,0x00, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0xb8,0x3c,0x05,0xb0,0x0a,0x24,0x02,0xff,0xff, +0xac,0x62,0x00,0x00,0x34,0xa5,0x14,0xb8,0x00,0x07,0x1e,0x02,0x24,0x04,0x00,0x01, +0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x34,0x42,0x04,0xb8,0x8c,0x47,0x00,0x00,0x00,0x03,0x1a,0x00,0x30,0xe2,0x00,0xff, +0x00,0x62,0x18,0x25,0x2c,0x62,0x00,0x04,0x10,0x40,0x00,0x3a,0x2c,0x62,0x00,0x11, +0x3c,0x03,0xb0,0x0a,0x34,0x63,0x14,0x10,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00, +0x00,0x60,0x20,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x10,0x8c,0x47,0x00,0x00, +0x24,0x02,0x00,0x03,0x00,0x07,0x1d,0x82,0x30,0x64,0x00,0x03,0x10,0x82,0x00,0x1a, +0x3c,0x02,0xff,0x3f,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x3c,0x03,0xb0,0x0a, +0x34,0x63,0x04,0x58,0x01,0x22,0x48,0x24,0x3c,0x04,0xb0,0x0a,0xac,0x69,0x00,0x00, +0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x35,0x29,0x80,0x00,0x34,0x42,0x04,0x58, +0x3c,0x04,0xb0,0x0a,0xac,0x49,0x00,0x00,0x34,0x84,0x14,0x58,0x24,0x03,0x00,0x01, +0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00, +0x08,0x00,0x0b,0xf9,0x00,0x00,0x00,0x00,0x34,0x42,0xff,0xff,0x3c,0x03,0x00,0x80, +0x00,0xe2,0x10,0x24,0x00,0x43,0x38,0x25,0x3c,0x03,0xb0,0x0a,0x3c,0x01,0xb0,0x0a, +0xac,0x27,0x04,0x10,0x34,0x63,0x14,0x10,0x24,0x04,0x00,0x01,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x3c,0x02,0xff,0xff,0x08,0x00,0x0d,0xef, +0x34,0x42,0x3f,0xff,0x14,0x40,0xff,0xd8,0x3c,0x02,0xff,0xff,0x3c,0x03,0xb0,0x0a, +0x34,0x63,0x14,0x10,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x3c,0x02,0xb0,0x0a,0x34,0x42,0x04,0x10,0x8c,0x47,0x00,0x00,0x3c,0x05,0x00,0xc0, +0x24,0x03,0x00,0x02,0x00,0xe5,0x10,0x24,0x00,0x02,0x25,0x82,0x14,0x83,0xff,0xc6, +0x3c,0x02,0xff,0xff,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xe2,0x10,0x24, +0x00,0x45,0x38,0x25,0x3c,0x03,0xb0,0x0a,0x3c,0x01,0xb0,0x0a,0xac,0x27,0x04,0x10, +0x34,0x63,0x14,0x10,0x24,0x04,0x00,0x01,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x44,0xff,0xfd,0x3c,0x02,0xff,0xff,0x08,0x00,0x0d,0xef,0x34,0x42,0x3f,0xff, +0x10,0x82,0x00,0x03,0x3c,0x03,0xb0,0x0a,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x34,0x63,0x1a,0x00,0x24,0x02,0xff,0xff,0xac,0x62,0x00,0x00,0x00,0x60,0x20,0x21, +0xa7,0x80,0xc5,0x40,0xa7,0x80,0xc5,0x42,0xa7,0x80,0xc5,0x44,0xa7,0x80,0xc5,0x46, +0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x34,0x63,0x0a,0x00,0x8c,0x66,0x00,0x00, +0x3c,0x02,0x08,0x00,0x3c,0x04,0xb0,0x0a,0x00,0xc2,0x10,0x25,0xac,0x62,0x00,0x00, +0x34,0x84,0x1a,0x00,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x3c,0x02,0xf7,0xff,0x3c,0x03,0xb0,0x0a,0x34,0x42,0xff,0xff, +0x34,0x63,0x0a,0x00,0x00,0xc2,0x10,0x24,0x3c,0x04,0xb0,0x0a,0xac,0x62,0x00,0x00, +0x34,0x84,0x1a,0x00,0x24,0x03,0x00,0x01,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x3a,0x00,0x00,0x00,0x00, +0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,0x3c,0x02,0xb0,0x0a, +0x00,0x82,0x20,0x21,0xac,0x85,0x00,0x00,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01, +0x2c,0x62,0x27,0x10,0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08, +0x24,0x63,0xff,0xff,0x30,0x86,0x00,0x03,0x00,0x04,0x28,0x40,0x3c,0x03,0xb0,0x0a, +0x00,0xa6,0x10,0x23,0x00,0x43,0x10,0x21,0x24,0x04,0xff,0xff,0xac,0x44,0x10,0x00, +0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x2c,0x62,0x27,0x10,0x14,0x40,0xff,0xfe, +0x24,0x63,0x00,0x01,0x24,0x63,0xff,0xff,0x00,0xa6,0x18,0x23,0x3c,0x02,0xb0,0x0a, +0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x3a,0x10,0x24,0x03,0x00,0x01, +0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00,0x34,0xc6,0x01,0x04, +0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,0xa0,0x80,0x00,0x06, +0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09,0xa0,0x80,0x00,0x0a, +0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49,0x94,0xc2,0x00,0x00, +0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x24,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03, +0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x83,0x00,0x46,0xa4,0x82,0x00,0x44, +0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34, +0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40, +0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x44,0x00,0x43,0x10,0x21, +0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00,0x24,0x42,0x3a,0xa0,0xac,0xe2,0x00,0x00, +0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13,0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02, +0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e,0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21, +0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05,0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01, +0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05,0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00, +0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24,0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01, +0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00,0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08, +0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xb0,0x00,0x07,0x60,0x80,0x27,0x82,0xbd,0x40, +0xaf,0xb7,0x00,0x44,0xaf,0xb6,0x00,0x40,0xaf,0xb5,0x00,0x3c,0xaf,0xb3,0x00,0x34, +0xaf,0xbf,0x00,0x4c,0xaf,0xbe,0x00,0x48,0xaf,0xb4,0x00,0x38,0xaf,0xb2,0x00,0x30, +0xaf,0xb1,0x00,0x2c,0xaf,0xb0,0x00,0x28,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00,0x94,0x71,0x00,0x14,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x20,0x24,0x42,0x3b,0x34,0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00, +0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00,0x00,0x11,0xa8,0xc0,0x02,0xb1,0x18,0x21, +0x27,0x82,0x99,0x44,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00, +0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03,0x00,0xc0,0x98,0x21,0xaf,0xa4,0x00,0x50, +0x00,0x05,0xb4,0x03,0x8c,0x68,0x00,0x18,0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x70, +0x00,0x07,0xbe,0x03,0x00,0xd7,0x10,0x07,0x30,0x57,0x00,0x01,0x01,0x71,0x10,0x21, +0x27,0x83,0x99,0x48,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06, +0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04,0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c, +0xaf,0xa2,0x00,0x1c,0x11,0xa0,0x01,0x60,0xaf,0xa3,0x00,0x18,0x27,0x82,0xbd,0x40, +0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,0x14,0x60,0x00,0x14,0x00,0x00,0xa0,0x21, +0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,0x90,0x43,0x00,0x00,0x2a,0x64,0x00,0x04, +0x10,0x80,0x01,0x43,0x30,0x65,0x00,0x01,0x8f,0xa3,0x00,0x50,0x00,0x00,0x00,0x00, +0x90,0x62,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x62,0x00,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x12,0xe0,0x00,0x03, +0x38,0xf4,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf4,0x00,0x01,0x01,0x71,0x10,0x21, +0x00,0x02,0x30,0x80,0x27,0x83,0x99,0x50,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00, +0x8f,0xa3,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x03,0x11,0xc3,0x2c,0xa3,0x00,0x04, +0x30,0x42,0x00,0x01,0x00,0x03,0xa0,0x0b,0x12,0x80,0x00,0xc7,0xaf,0xa2,0x00,0x20, +0x93,0x90,0xc5,0x2a,0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c, +0x10,0xc0,0x00,0xaf,0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04, +0x00,0x90,0x10,0x2b,0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b, +0x10,0x40,0x00,0x0b,0x01,0x71,0x10,0x21,0x27,0x85,0xc4,0x5c,0x00,0x10,0x10,0x40, +0x00,0x50,0x10,0x21,0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x90,0x18,0x2b,0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x71,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x48,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01, +0x10,0x80,0x00,0x94,0xa0,0x50,0x00,0x07,0x24,0x16,0x00,0x0e,0x24,0x11,0x01,0x06, +0x27,0x82,0xbd,0x40,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x1e,0x00,0x01, +0x00,0x11,0xa8,0xc0,0x90,0x62,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x04, +0xa0,0x62,0x00,0x16,0x8f,0xa5,0x00,0x1c,0x00,0x10,0x32,0x00,0x00,0x05,0x13,0x43, +0x30,0x47,0x00,0x01,0x8f,0xa2,0x00,0x18,0x8f,0xa5,0x00,0x20,0x00,0x02,0x22,0x02, +0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0,0x30,0x84,0x07,0xff,0x00,0x47,0x10,0x21, +0x00,0x1e,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x04,0x24,0x80,0x02,0x25,0x28,0x21, +0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21,0x00,0x16,0x1c,0x00,0x3c,0x04,0xc0,0x00, +0x00,0x43,0x30,0x21,0x16,0x60,0x00,0x2b,0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05, +0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00, +0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00, +0x8f,0xa2,0x00,0x50,0x30,0x86,0x00,0x01,0x90,0x43,0x00,0x09,0x00,0x00,0x00,0x00, +0x02,0x63,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21, +0x12,0xe0,0x00,0x03,0x02,0xb1,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb1,0x10,0x21, +0x27,0x83,0x99,0x48,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04, +0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x60,0x28,0x21,0x02,0x80,0x38,0x21, +0x0c,0x00,0x00,0x70,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0x7c,0x7b,0xb6,0x02,0x3c, +0x7b,0xb4,0x01,0xfc,0x7b,0xb2,0x01,0xbc,0x7b,0xb0,0x01,0x7c,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x50,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x3d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x02,0x12,0x62,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03, +0x12,0x62,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x62,0x00,0x19, +0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x62,0x00,0x0d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x12,0x16,0x62,0xff,0xcf,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05, +0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00, +0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x0f,0x74,0x24,0x02,0x00,0x20, +0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x0f,0x74, +0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, +0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80, +0x08,0x00,0x0f,0x74,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05, +0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28, +0x24,0x02,0x00,0x08,0x08,0x00,0x0f,0x74,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10, +0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14, +0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x0f,0x74,0xac,0x65,0x00,0x00, +0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x0f,0x74, +0xac,0x65,0x00,0x00,0x24,0x16,0x00,0x14,0x08,0x00,0x0f,0x4c,0x24,0x11,0x01,0x02, +0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c, +0x26,0x02,0x00,0x04,0x27,0x85,0xc4,0x5c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, +0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04, +0x08,0x00,0x0f,0x43,0x00,0x46,0x80,0x0a,0x27,0x82,0xbd,0x40,0x01,0x82,0x20,0x21, +0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x99,0x60,0x00,0xc2,0x10,0x21, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x12,0x00,0x00,0x00,0x00, +0x90,0xe3,0x00,0x16,0x27,0x82,0x99,0x48,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20, +0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x16,0x42, +0x30,0x52,0x00,0x3f,0x90,0x83,0x00,0x16,0x24,0x16,0x00,0x18,0x24,0x11,0x01,0x03, +0x30,0x63,0x00,0xfb,0x24,0x1e,0x00,0x01,0x24,0x15,0x08,0x18,0x08,0x00,0x0f,0x55, +0xa0,0x83,0x00,0x16,0x8d,0x02,0x00,0x04,0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10, +0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f,0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e,0x27,0x83,0x99,0x58,0x00,0xc3,0x18,0x21, +0x80,0x64,0x00,0x00,0x27,0x83,0xbe,0xb8,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24, +0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25,0x27,0x85,0xbd,0x40,0x01,0x85,0x28,0x21, +0x8c,0xa6,0x00,0x00,0x01,0x71,0x10,0x21,0x27,0x83,0x99,0x50,0x90,0xc4,0x00,0x16, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00, +0xa0,0xc4,0x00,0x16,0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0x80,0xde,0x00,0x12, +0x90,0x62,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06, +0xa0,0x62,0x00,0x16,0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04, +0x15,0xc2,0xff,0x14,0x00,0x00,0x00,0x00,0x32,0x42,0x00,0x02,0x2e,0x03,0x00,0x0c, +0x14,0x60,0x00,0x0d,0x00,0x02,0x20,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10, +0x00,0x04,0x19,0x00,0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xb8, +0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x01,0xfb,0xa0,0x43,0x00,0x00, +0x08,0x00,0x0f,0x55,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x4a,0x32,0x03,0x00,0xff, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xbf,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x50, +0x00,0x00,0x00,0x00,0x90,0x62,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x62,0x10,0x26, +0x08,0x00,0x0f,0x19,0x00,0x02,0x28,0x0b,0x08,0x00,0x0f,0x1f,0x00,0x00,0xa0,0x21, +0x24,0x02,0x00,0x10,0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x8e, +0x00,0x07,0x17,0x83,0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x8c,0x00,0x07,0x17,0x43, +0x08,0x00,0x0e,0xf7,0x30,0x57,0x00,0x01,0x08,0x00,0x0e,0xf7,0x00,0x07,0xbf,0xc2, +0x00,0x04,0x10,0x40,0x27,0x83,0x86,0x30,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21, +0x94,0x44,0x00,0x00,0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a, +0x00,0x86,0x00,0x18,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x41,0xc0,0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12, +0x00,0x04,0x22,0x42,0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b, +0x24,0x82,0x00,0x60,0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x01,0x00,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x00,0x44,0x20,0x04,0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28, +0x24,0x83,0x00,0x24,0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14, +0x00,0x60,0x20,0x21,0x08,0x00,0x10,0x87,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x42,0x5c, +0x00,0x80,0x80,0x21,0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37, +0x34,0x84,0x01,0x10,0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21, +0x8c,0x87,0x00,0x00,0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f, +0x34,0x42,0xf0,0x00,0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08, +0x32,0x02,0x00,0x07,0x27,0x83,0x86,0xe0,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00, +0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21, +0x32,0x02,0x00,0x0f,0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x07,0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xbd,0x90, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c, +0x14,0x40,0x00,0x05,0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x82,0x10,0x21,0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20, +0x24,0x06,0x00,0x0e,0x0c,0x00,0x10,0x70,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04, +0x24,0x02,0x00,0x10,0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01, +0x14,0x60,0x00,0x02,0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff, +0x00,0xc5,0x10,0x21,0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c, +0x32,0x02,0x00,0x07,0x27,0x83,0x86,0xd8,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00, +0x08,0x00,0x10,0xb5,0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80, +0x27,0x82,0xbd,0x40,0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c, +0xaf,0xbf,0x00,0x44,0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30, +0xaf,0xb2,0x00,0x28,0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21, +0x8c,0xe6,0x00,0x00,0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03, +0x34,0xa5,0x00,0x20,0x24,0x42,0x43,0xb8,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00, +0xa0,0xc3,0x00,0x12,0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16, +0xa4,0xc3,0x00,0x14,0x27,0x83,0x99,0x40,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16, +0x8c,0xe8,0x00,0x00,0xaf,0xa4,0x00,0x48,0x27,0x82,0x99,0x44,0x95,0x11,0x00,0x14, +0x00,0x00,0x00,0x00,0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80, +0x00,0x82,0x10,0x21,0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06, +0x8e,0x45,0x00,0x08,0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82, +0x00,0x06,0x31,0x42,0x27,0x82,0x99,0x50,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01, +0x00,0x82,0x20,0x21,0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18, +0xaf,0xa6,0x00,0x1c,0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06, +0x14,0xe0,0x00,0x47,0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x44,0x02,0x71,0x10,0x21,0x93,0x90,0xc5,0x29,0x00,0x00,0x00,0x00, +0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40, +0x00,0x43,0x10,0x21,0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04, +0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21, +0x00,0x80,0x80,0x21,0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21, +0x02,0xc0,0x28,0x21,0x0c,0x00,0x10,0x70,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21, +0x00,0x03,0x88,0x80,0x00,0x40,0xa0,0x21,0x27,0x82,0x99,0x60,0x02,0x22,0x10,0x21, +0x8c,0x44,0x00,0x00,0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21, +0x00,0x04,0x25,0xc2,0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40, +0x03,0xc4,0x20,0x24,0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03, +0x35,0x08,0x00,0x28,0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48, +0x27,0x82,0x99,0x48,0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21, +0xa4,0x54,0x00,0x04,0x00,0xc0,0x38,0x21,0x0c,0x00,0x0e,0xcd,0xad,0x03,0x00,0x00, +0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c, +0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c, +0x8f,0xa6,0x00,0x18,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x10,0x97,0xaf,0xa0,0x00,0x14,0x08,0x00,0x11,0x53,0x02,0x82,0xa0,0x21, +0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21, +0x90,0x50,0x00,0x00,0x08,0x00,0x11,0x3f,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8, +0xaf,0xb1,0x00,0x24,0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x45,0xdc,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c, +0xaf,0xb6,0x00,0x38,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c, +0x8f,0xb5,0x00,0x58,0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28, +0xaf,0xb0,0x00,0x20,0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21, +0x00,0x00,0xb8,0x21,0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xbd,0x40, +0x00,0x07,0x10,0x80,0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80, +0x00,0x65,0x18,0x21,0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03, +0x14,0x40,0x00,0x2d,0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05, +0x34,0x63,0x01,0x44,0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00, +0x8f,0xa3,0x00,0x4c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01, +0x10,0x40,0x00,0x04,0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09, +0x24,0x05,0x00,0x14,0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc, +0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x48,0x0c,0x00,0x0e,0xa8,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01, +0x08,0x00,0x11,0xb9,0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01, +0x10,0xc2,0x00,0x17,0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21, +0x12,0x20,0xff,0xed,0x02,0x20,0x10,0x21,0x27,0x83,0xbd,0x40,0x00,0x17,0x10,0x80, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28, +0x80,0x86,0x00,0x12,0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03, +0x00,0x46,0x10,0x21,0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21, +0x0c,0x00,0x0e,0xcd,0xac,0x62,0x00,0x00,0x08,0x00,0x11,0xb9,0xaf,0xd1,0x00,0x40, +0x96,0x74,0x00,0x1a,0x08,0x00,0x11,0xcc,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x08,0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x26,0x64, +0x02,0x00,0x28,0x21,0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21, +0x0c,0x00,0x26,0x64,0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00, +0x10,0x80,0x00,0xed,0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01, +0x96,0x63,0x00,0x14,0x96,0x44,0x00,0x14,0x27,0x85,0x99,0x40,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0, +0x8c,0x46,0x00,0x08,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21, +0x00,0x06,0x17,0x02,0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6, +0x00,0x03,0x17,0x02,0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b, +0x24,0x11,0x00,0x02,0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01, +0x12,0x22,0x00,0x5a,0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00, +0x96,0x49,0x00,0x14,0x27,0x82,0x99,0x44,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0, +0x01,0x49,0x18,0x21,0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04, +0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01, +0x14,0x40,0x00,0x41,0x30,0x87,0x00,0x01,0x27,0x82,0x99,0x58,0x01,0x02,0x10,0x21, +0x80,0x44,0x00,0x00,0x27,0x82,0xbe,0xb8,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23, +0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21, +0x90,0x45,0x00,0x05,0x27,0x84,0xbd,0xe0,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00, +0x10,0xa0,0x00,0x2b,0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21, +0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03, +0xa0,0x22,0x00,0xb9,0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40, +0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04, +0x01,0x49,0x10,0x21,0x27,0x83,0x99,0x50,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08, +0x12,0x02,0x00,0x0b,0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21, +0x0c,0x00,0x26,0xe0,0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16, +0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x25,0x08,0x00,0x11,0xcc,0xa2,0x42,0x00,0x16, +0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x26,0x91,0xaf,0xa0,0x00,0x10, +0x08,0x00,0x12,0x4f,0x30,0x54,0xff,0xff,0x08,0x00,0x12,0x37,0x00,0x60,0x10,0x21, +0x14,0x80,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21, +0x08,0x00,0x12,0x37,0x24,0x42,0x00,0x04,0x27,0x82,0x99,0x50,0x01,0x02,0x10,0x21, +0x90,0x43,0x00,0x00,0x08,0x00,0x12,0x47,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14, +0x02,0xc0,0xb8,0x21,0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21, +0x00,0x03,0x40,0x80,0x00,0x40,0x50,0x21,0x27,0x82,0x99,0x44,0x01,0x02,0x10,0x21, +0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c, +0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10, +0x30,0x66,0x00,0x01,0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x99,0x58, +0x01,0x02,0x10,0x21,0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00, +0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80, +0x27,0x83,0xbe,0xb0,0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f, +0x00,0x00,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x99,0x50, +0x00,0x85,0x10,0x21,0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42, +0x01,0x49,0x10,0x21,0x27,0x82,0x99,0x58,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00, +0x27,0x82,0xbe,0xb8,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80, +0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05, +0x27,0x84,0xbd,0xe0,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c, +0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00, +0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9, +0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21, +0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21, +0x27,0x83,0x99,0x50,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21, +0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08, +0x10,0x82,0x00,0x0c,0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21, +0x0c,0x00,0x26,0xe0,0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff, +0x92,0x62,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x11,0xcc, +0xa2,0x62,0x00,0x16,0x02,0x60,0x20,0x21,0x0c,0x00,0x26,0x91,0xaf,0xa0,0x00,0x10, +0x08,0x00,0x12,0xbe,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0xa6,0x00,0x60,0x10,0x21, +0x14,0x80,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21, +0x08,0x00,0x12,0xa6,0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21, +0x90,0x43,0x00,0x00,0x08,0x00,0x12,0xb6,0xa0,0x43,0x00,0x03,0x27,0x85,0x99,0x50, +0x08,0x00,0x12,0xd2,0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26, +0x08,0x00,0x12,0x07,0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01, +0x08,0x00,0x12,0x0c,0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x27,0xbd,0xff,0xd0,0x24,0x42,0x4b,0x88,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05, +0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28, +0xaf,0xb0,0x00,0x18,0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00, +0x00,0x80,0x90,0x21,0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10, +0x12,0x22,0x00,0xcf,0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1, +0x24,0x02,0x00,0x12,0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad, +0xae,0x43,0x00,0x40,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00, +0x3c,0x03,0x00,0x02,0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43, +0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x92,0x00,0x00,0x00,0x00,0x93,0x83,0x94,0x51,0x00,0x00,0x00,0x00, +0x30,0x62,0x00,0x02,0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3, +0x14,0x40,0x00,0x86,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21, +0x26,0x22,0x00,0x01,0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb, +0x24,0x03,0x00,0x02,0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03, +0x10,0x40,0x00,0x58,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b, +0x02,0x40,0x20,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21, +0x8f,0xbf,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x30,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07, +0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05, +0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec, +0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05, +0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05, +0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc, +0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03, +0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05, +0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc, +0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02, +0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05, +0x8c,0x42,0x02,0x2c,0x08,0x00,0x13,0x28,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04, +0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06, +0xaf,0xa2,0x00,0x10,0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0x08,0x00,0x13,0x21, +0xae,0x42,0x00,0x24,0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08, +0x16,0x62,0xff,0xa8,0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30, +0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x11,0x77, +0xaf,0xa2,0x00,0x14,0x08,0x00,0x13,0x21,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06, +0x8e,0x43,0x00,0x2c,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21, +0xaf,0xa2,0x00,0x10,0x0c,0x00,0x11,0x77,0xaf,0xa3,0x00,0x14,0x08,0x00,0x13,0x21, +0xae,0x42,0x00,0x2c,0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x11,0x77, +0xaf,0xa3,0x00,0x14,0x08,0x00,0x13,0x21,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x57, +0x24,0x04,0x00,0x01,0x08,0x00,0x13,0x12,0x00,0x00,0x00,0x00,0x8f,0x84,0xbd,0x80, +0xae,0x40,0x00,0x34,0x94,0x85,0x00,0x14,0x0c,0x00,0x22,0xe1,0x00,0x00,0x00,0x00, +0x93,0x83,0x94,0x51,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69, +0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x08,0x00,0x13,0x0a, +0x00,0x00,0x00,0x00,0x02,0x40,0x20,0x21,0x0c,0x00,0x10,0xee,0x02,0x20,0x28,0x21, +0x08,0x00,0x12,0xfe,0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00, +0x14,0x40,0xff,0x4a,0x00,0x00,0x00,0x00,0x8f,0x82,0xbd,0x88,0x00,0x00,0x00,0x00, +0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x12,0xfb, +0xae,0x43,0x00,0x3c,0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d, +0x24,0x02,0x00,0x12,0x8f,0x82,0xbd,0x84,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a, +0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x12,0xfb,0xae,0x43,0x00,0x38, +0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11, +0x8f,0x82,0xbd,0x80,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00, +0x00,0x02,0x18,0x2b,0x08,0x00,0x12,0xfb,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x4f,0x3c, +0x3c,0x08,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00, +0xaf,0xbf,0x00,0x18,0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21, +0x24,0x11,0x00,0x0a,0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a, +0x30,0x63,0x00,0x01,0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40, +0x02,0x20,0x40,0x21,0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x48, +0x00,0x43,0x10,0x21,0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06, +0x02,0x23,0x80,0x21,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x10,0x70,0x00,0x00,0x00,0x00, +0x02,0x11,0x18,0x21,0x08,0x00,0x13,0xf1,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0, +0xaf,0xbf,0x00,0x28,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0xaf,0xb5,0x00,0x24,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c, +0x3c,0x06,0xb0,0x03,0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x00,0x03,0x18,0x80,0x27,0x82,0x99,0x44,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18, +0x3c,0x02,0x80,0x00,0x24,0x42,0x4f,0xec,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08, +0x27,0x82,0x99,0x48,0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43, +0x32,0x10,0x00,0x01,0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21, +0x02,0x20,0x28,0x21,0x0c,0x00,0x13,0xcf,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21, +0x02,0x00,0x28,0x21,0x24,0x06,0x00,0x14,0x0c,0x00,0x10,0x70,0x00,0x40,0xa0,0x21, +0x86,0x43,0x00,0x0c,0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21, +0x80,0x43,0x00,0x06,0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00, +0x24,0x64,0x00,0x03,0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09, +0x00,0x03,0x18,0x80,0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14, +0x34,0xe7,0x01,0x20,0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11, +0x02,0xa3,0xa8,0x21,0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00, +0x00,0x03,0x1c,0x02,0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28, +0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x30,0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00, +0x8e,0xa4,0x00,0x08,0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c, +0x00,0x00,0x00,0x00,0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21, +0xac,0xe3,0x00,0x00,0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02, +0x08,0x00,0x14,0x43,0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c, +0x00,0x80,0x90,0x21,0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21, +0x00,0x04,0x20,0x80,0x27,0x82,0x99,0x44,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18, +0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x51,0x68,0x27,0x83,0x99,0x48, +0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07, +0x34,0x42,0x01,0x00,0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04, +0x24,0x02,0x00,0x10,0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43, +0x30,0x84,0x00,0x01,0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40, +0x02,0x00,0x10,0x21,0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x10,0x70, +0x30,0x50,0x00,0xff,0x86,0x44,0x00,0x0c,0x27,0x85,0x99,0x50,0x3c,0x06,0xb0,0x09, +0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21, +0x80,0x64,0x00,0x06,0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03, +0x28,0x83,0x00,0x00,0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80, +0xa4,0xc2,0x00,0x00,0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09, +0x34,0x42,0x01,0x10,0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09, +0x34,0x42,0x01,0x14,0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08, +0x3c,0x06,0xb0,0x09,0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21, +0x34,0xc6,0x01,0x20,0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09, +0x34,0xa5,0x01,0x24,0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a, +0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04, +0x30,0x42,0xff,0xff,0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x99,0x58, +0x8f,0xbf,0x00,0x1c,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00, +0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x52,0xf4, +0x00,0x05,0x2c,0x43,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00, +0x10,0xa0,0x00,0x05,0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0xaf,0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x47, +0x00,0x00,0x10,0x21,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x9c,0x2a,0x02,0x00,0x09, +0x10,0x40,0x00,0x84,0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x74, +0x2a,0x02,0x00,0x03,0x10,0x40,0x00,0x64,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01, +0x12,0x02,0x00,0x55,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x11,0x92,0x27,0x00,0x11, +0x10,0x40,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12, +0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xbd,0x40,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14, +0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10, +0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xbd,0x40, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12, +0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01, +0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12, +0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c, +0x27,0x84,0x99,0x50,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00, +0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04, +0xa2,0x20,0x00,0x15,0xa3,0x80,0x95,0x14,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x14,0x5a, +0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x15,0x05,0x00,0x07,0x16,0x00, +0x0c,0x00,0x13,0xfb,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x99,0x48, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21, +0x90,0x85,0x00,0x07,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13, +0x90,0x83,0x00,0x07,0x08,0x00,0x15,0x1d,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a, +0x08,0x00,0x14,0xe6,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00, +0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a, +0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x14,0xde,0xa2,0x22,0x00,0x04, +0x08,0x00,0x15,0x37,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9f,0x24,0x02,0x00,0x01, +0x8e,0x23,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08, +0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c, +0x08,0x00,0x14,0xde,0xa2,0x22,0x00,0x06,0x08,0x00,0x15,0x46,0xa2,0x20,0x00,0x0a, +0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07, +0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b, +0xae,0x20,0x00,0x28,0x08,0x00,0x14,0xde,0xa2,0x22,0x00,0x05,0x08,0x00,0x15,0x52, +0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x10,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x08, +0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7f,0x24,0x02,0x00,0x12, +0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x14,0xde,0xae,0x20,0x00,0x3c, +0x16,0x02,0xff,0x79,0x24,0x02,0x00,0x10,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08, +0x08,0x00,0x14,0xde,0xae,0x20,0x00,0x34,0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a, +0xa2,0x22,0x00,0x08,0x08,0x00,0x14,0xde,0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30, +0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01,0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08, +0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30, +0x08,0x00,0x14,0xde,0xa2,0x22,0x00,0x07,0x08,0x00,0x15,0x76,0xa2,0x24,0x00,0x0a, +0x8f,0x84,0xbd,0x80,0xae,0x20,0x00,0x34,0x94,0x85,0x00,0x14,0x0c,0x00,0x22,0xe1, +0x32,0x10,0x00,0xff,0x08,0x00,0x14,0xcf,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x24,0x42,0x56,0x0c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00, +0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05,0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54, +0x83,0x83,0x95,0x14,0x00,0x00,0x00,0x00,0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c,0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50, +0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01,0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01, +0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01, +0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8,0x34,0x63,0x00,0x20,0x24,0x42,0x56,0x9c, +0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18, +0x90,0xa6,0x00,0x0a,0x27,0x83,0xbd,0x40,0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80, +0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12, +0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15,0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda, +0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67, +0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12,0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x99,0x60,0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf,0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08, +0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45,0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04, +0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01, +0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17,0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff, +0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01, +0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08,0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06, +0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x96,0x02,0x00,0x00,0x08,0x00,0x15,0xf2, +0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xde,0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00, +0x96,0x05,0x00,0x06,0x27,0x86,0x99,0x40,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21, +0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21, +0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08, +0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24,0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24, +0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01, +0x00,0xa6,0x18,0x2b,0x08,0x00,0x15,0xde,0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd, +0x00,0xa6,0x18,0x2b,0x08,0x00,0x16,0x12,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09, +0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xd8,0xa2,0x20,0x00,0x07,0x08,0x00,0x15,0xd8, +0xa2,0x20,0x00,0x06,0x08,0x00,0x15,0xd8,0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69,0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49, +0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff, +0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04, +0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c, +0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80, +0x27,0x83,0x99,0x44,0x00,0xa3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18, +0x24,0x07,0x00,0x01,0x93,0x82,0x94,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24,0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03, +0x0c,0x00,0x22,0xe1,0x02,0x00,0x20,0x21,0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12, +0x30,0x42,0x00,0xe7,0x08,0x00,0x15,0xcf,0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06, +0x00,0x00,0x28,0x12,0x27,0x82,0x99,0x40,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49, +0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c,0x08,0x00,0x16,0x4f,0x00,0x06,0x2c,0x00, +0x27,0x83,0x99,0x50,0x27,0x82,0x99,0x58,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21, +0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21, +0x0c,0x00,0x29,0x0b,0xaf,0xa2,0x00,0x10,0x96,0x26,0x00,0x0c,0x08,0x00,0x16,0x49, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29, +0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x16,0x38, +0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c,0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72, +0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00,0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0, +0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09,0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c, +0x27,0x83,0x99,0x44,0x00,0x02,0x10,0x80,0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21, +0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20,0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08, +0x02,0x20,0x20,0x21,0x0c,0x00,0x16,0x9f,0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18, +0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20,0x02,0x20,0x20,0x21,0x0c,0x00,0x23,0xe3, +0xaf,0xa2,0x00,0x10,0x08,0x00,0x15,0xcf,0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08, +0x08,0x00,0x15,0xcf,0xa2,0x22,0x00,0x09,0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0, +0xac,0x40,0x00,0x00,0x08,0x00,0x15,0xcf,0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c, +0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03, +0x24,0x42,0x5a,0x7c,0xf1,0x43,0x00,0x06,0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12, +0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00,0x27,0x85,0x99,0x50,0x27,0x82,0x99,0x4f, +0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21,0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21, +0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21, +0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04,0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80, +0x27,0x83,0x99,0x44,0xa3,0xa7,0x00,0x00,0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18, +0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b,0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07, +0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08,0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a, +0x93,0xa7,0x00,0x00,0x27,0x82,0x99,0x58,0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0, +0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff,0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b, +0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00,0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f, +0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d,0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a, +0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02,0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21, +0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40,0x27,0x83,0xc4,0x5c,0x00,0x44,0x10,0x21, +0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c, +0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02,0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21, +0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00,0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff, +0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03, +0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f,0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40, +0x00,0x44,0x20,0x21,0x27,0x83,0xc4,0x5c,0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00, +0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21, +0x27,0x83,0xbd,0xe8,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06,0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40, +0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04, +0x08,0x00,0x17,0x00,0xa1,0x82,0x00,0x00,0x8f,0x8d,0x87,0x70,0x00,0x00,0x00,0x00, +0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1, +0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82,0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c, +0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21,0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c, +0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00,0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d, +0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40, +0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x27,0x84,0xbd,0xe8,0x00,0x44,0x10,0x21,0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00, +0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x44,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33,0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00, +0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,0x27,0x83,0xbe,0xb8, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05, +0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24,0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00, +0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f,0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x84,0x99,0x40,0x00,0x44,0x10,0x21,0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00, +0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04,0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f, +0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06, +0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04,0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21, +0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff, +0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad,0x30,0xe2,0x00,0xff,0x08,0x00,0x16,0xed, +0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x4e,0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48, +0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xdb, +0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05, +0x91,0x67,0x00,0x00,0x08,0x00,0x16,0xbb,0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x5e,0x1c,0x03,0xe0,0x00,0x08, +0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30, +0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20, +0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18, +0x84,0x82,0x00,0x0c,0x27,0x93,0x99,0x44,0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0, +0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18, +0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x5e,0x34,0xac,0xa2,0x00,0x00, +0x8f,0xd0,0x00,0x08,0x27,0x95,0x99,0x50,0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21, +0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00,0x0c,0x00,0x16,0x9f,0x00,0x80,0xb0,0x21, +0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42,0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21, +0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21,0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2, +0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18,0x27,0x83,0x99,0x40,0x00,0x43,0x10,0x21, +0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06,0x00,0x03,0x19,0x42,0x0c,0x00,0x10,0x70, +0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21,0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21, +0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21,0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x99,0x48, +0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc, +0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c,0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21, +0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2, +0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43,0x00,0x07,0x38,0x40,0x0c,0x00,0x10,0x97, +0x03,0xc7,0x38,0x21,0x08,0x00,0x17,0xce,0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,0x34,0x63,0x00,0x20,0x24,0x42,0x5f,0xbc, +0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00,0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24, +0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a, +0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0xbd,0x40, +0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff,0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12, +0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02,0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46, +0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21,0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15, +0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19, +0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x60,0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00, +0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf, +0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x0c,0x00,0x17,0x87,0x00,0x00,0x00,0x00, +0x08,0x00,0x18,0x1d,0x00,0x00,0x00,0x00,0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76, +0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21, +0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03,0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03, +0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21, +0x27,0x82,0x99,0x60,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80, +0x27,0x82,0x99,0x48,0x00,0xa2,0x10,0x21,0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06, +0x27,0x82,0x99,0x50,0x00,0x08,0x1d,0x02,0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00, +0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b,0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05, +0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02,0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28, +0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11,0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff,0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46, +0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04,0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00, +0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00,0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x27,0x84,0x99,0x50,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21, +0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21, +0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00,0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00, +0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03,0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04, +0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00,0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21, +0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c, +0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e, +0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c,0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21, +0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16,0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb, +0x08,0x00,0x18,0x22,0xa2,0x23,0x00,0x16,0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50, +0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05,0x86,0x45,0x00,0x0c,0x0c,0x00,0x26,0x5b, +0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c, +0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24, +0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff, +0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17, +0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x96,0x22,0x00,0x06,0x08,0x00,0x18,0x1d,0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00, +0x08,0x00,0x18,0x1d,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x18,0xac,0xa2,0x20,0x00,0x17, +0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x99,0x40,0x00,0x04,0x18,0xc0, +0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80, +0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, +0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08, +0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02, +0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x18,0xac,0xa2,0x23,0x00,0x17, +0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x18,0xcf,0x00,0x00,0x00,0x00, +0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00,0x08,0x00,0x18,0xa7,0xa2,0x40,0x00,0x07, +0x08,0x00,0x18,0xa7,0xa2,0x40,0x00,0x06,0x08,0x00,0x18,0xa7,0xa2,0x40,0x00,0x05, +0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x18,0x9e,0x00,0xa2,0x10,0x07, +0x0c,0x00,0x17,0x8d,0x02,0x40,0x20,0x21,0x08,0x00,0x18,0x1d,0x00,0x00,0x00,0x00, +0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04, +0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29, +0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27, +0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00, +0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80,0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04, +0x86,0x43,0x00,0x0c,0x27,0x93,0x99,0x44,0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10, +0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21,0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21, +0x8c,0x43,0x00,0x18,0x93,0x82,0x94,0x51,0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01, +0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d,0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00, +0x00,0x05,0x2c,0x03,0x0c,0x00,0x22,0xe1,0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06, +0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff,0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0, +0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42, +0x0c,0x00,0x22,0xe1,0x30,0x50,0x00,0x01,0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef, +0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d, +0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16, +0x08,0x00,0x18,0x1c,0x30,0x42,0x00,0xc3,0x96,0x22,0x00,0x00,0x08,0x00,0x19,0x43, +0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x08,0x00,0x19,0x3e,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00, +0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21, +0x00,0x65,0x18,0x21,0x27,0x84,0x99,0x40,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21, +0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08,0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08, +0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24,0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24, +0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01, +0x00,0x85,0x18,0x2b,0x08,0x00,0x19,0x3e,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd, +0x00,0x85,0x18,0x2b,0x08,0x00,0x19,0x62,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24, +0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x99,0x40,0x00,0xa2,0x28,0x21, +0x0c,0x00,0x01,0x49,0x00,0x00,0x20,0x21,0x96,0x47,0x00,0x0c,0x08,0x00,0x19,0x20, +0x00,0x07,0x2c,0x00,0x27,0x83,0x99,0x50,0x27,0x82,0x99,0x58,0x00,0xa2,0x10,0x21, +0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10, +0x24,0x07,0x00,0x01,0x0c,0x00,0x29,0x0b,0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c, +0x08,0x00,0x19,0x13,0x00,0x07,0x1c,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02, +0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00, +0x08,0x00,0x19,0x04,0xa2,0x40,0x00,0x07,0x08,0x00,0x19,0x04,0xa2,0x40,0x00,0x06, +0x08,0x00,0x19,0x04,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80, +0x08,0x00,0x18,0xfb,0x00,0xa2,0x10,0x07,0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80, +0x08,0x00,0x18,0x56,0x00,0xa2,0x10,0x07,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x44, +0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08, +0x0c,0x00,0x16,0x9f,0x00,0x00,0x00,0x00,0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21, +0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21,0x0c,0x00,0x23,0xe3,0xaf,0xa2,0x00,0x10, +0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b,0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08, +0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40,0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04, +0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01, +0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00, +0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0, +0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16, +0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16,0x08,0x00,0x18,0x1c, +0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00,0x08,0x00,0x19,0xc5,0xa6,0x22,0x00,0x14, +0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x19,0xbe,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06, +0x27,0x86,0x99,0x40,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0, +0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80, +0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00, +0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04, +0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b, +0x08,0x00,0x19,0xbe,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b, +0x08,0x00,0x19,0xed,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02, +0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00, +0x08,0x00,0x19,0xb8,0xa2,0x40,0x00,0x07,0x08,0x00,0x19,0xb8,0xa2,0x40,0x00,0x06, +0x08,0x00,0x19,0xb8,0xa2,0x40,0x00,0x05,0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24, +0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24,0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21, +0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01,0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd,0x00,0xa4,0x10,0x2b,0x08,0x00,0x1a,0x08, +0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x27,0x84,0x99,0x50,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06, +0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00,0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21, +0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21,0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c, +0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41,0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04, +0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00,0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08, +0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20,0x08,0x00,0x1a,0x2e,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff,0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21, +0x8f,0x85,0x99,0x20,0x00,0x40,0x30,0x21,0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00, +0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02,0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00, +0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08,0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00, +0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00, +0x27,0x92,0xbd,0x40,0x24,0x11,0x00,0x12,0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff, +0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04, +0x0c,0x00,0x20,0x48,0x00,0x00,0x00,0x00,0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf, +0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03,0x0c,0x00,0x1a,0xe6,0xac,0x30,0x00,0x00, +0x08,0x00,0x1a,0x2e,0x00,0x00,0x00,0x00,0x8f,0x85,0x99,0x20,0x08,0x00,0x1a,0x44, +0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95,0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24, +0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03,0xac,0x30,0x00,0x00,0x0c,0x00,0x1a,0xaf, +0xac,0x60,0x00,0x00,0x08,0x00,0x1a,0x2e,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x50,0x08,0x00,0x1a,0x2e,0xac,0x46,0x00,0x00,0xaf,0xa7,0x00,0x0c, +0xaf,0xa4,0x00,0x00,0xaf,0xa5,0x00,0x04,0xaf,0xa6,0x00,0x08,0x27,0xbd,0xfe,0xe8, +0x00,0x80,0x28,0x21,0x27,0xa6,0x01,0x1c,0x27,0xa4,0x00,0x10,0xaf,0xbf,0x01,0x14, +0x0c,0x00,0x2e,0x2c,0xaf,0xb0,0x01,0x10,0x00,0x40,0x80,0x21,0x0c,0x00,0x1a,0x7e, +0x27,0xa4,0x00,0x10,0x02,0x00,0x10,0x21,0x8f,0xbf,0x01,0x14,0x8f,0xb0,0x01,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x01,0x18,0x93,0x83,0x87,0x6c,0x27,0xbd,0xff,0xe8, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x14,0x60,0x00,0x14,0x00,0x80,0x80,0x21, +0x80,0x82,0x00,0x00,0x90,0x84,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x00,0x04,0x26,0x00,0x00,0x04,0x26,0x03,0x30,0x84,0xff,0xff,0x0c,0x00,0x1a,0x9e, +0x26,0x10,0x00,0x01,0x92,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xf8, +0x00,0x60,0x20,0x21,0x08,0x00,0x1a,0x88,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x14,0x43,0xff,0xef,0x00,0x00,0x00,0x00,0x0c,0x00,0x05,0x52,0x00,0x00,0x00,0x00, +0x08,0x00,0x1a,0x88,0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x48,0x84,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, +0x0c,0x00,0x2d,0x94,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x02,0x14,0x00, +0x00,0x02,0x14,0x03,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x03,0xe0,0x00,0x08, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x3c,0x0a,0x80,0x00, +0x25,0x4a,0x6a,0xbc,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01, +0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01,0x25,0x29,0x0b,0x90,0x11,0x09,0x00,0x10, +0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x6a,0xe4,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06,0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01, +0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01,0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00, +0x3c,0x0a,0x80,0x00,0x25,0x4a,0x6b,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40, +0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00, +0x25,0x4a,0x6b,0x4c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01, +0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01,0x24,0x63,0x0b,0x90,0x3c,0x04,0xb0,0x00, +0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04, +0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00, +0x0c,0x00,0x1a,0xe6,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x6b,0x98, +0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x0b,0x90, +0x3c,0x03,0x80,0x01,0x24,0x63,0x48,0x64,0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04, +0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c,0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a, +0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x6b,0xd8, +0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0, +0x27,0x9d,0x95,0x20,0x00,0x00,0x00,0x00,0x27,0x9d,0x99,0x08,0x3c,0x0a,0x80,0x00, +0x25,0x4a,0x6b,0xfc,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00, +0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00,0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00, +0x00,0x00,0x00,0x00,0x0c,0x00,0x1d,0x15,0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00, +0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40,0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a, +0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff,0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14, +0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18,0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21, +0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00, +0x0c,0x00,0x1b,0x63,0x02,0x20,0x20,0x21,0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06, +0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21, +0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c,0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21,0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00, +0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40,0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21, +0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00, +0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01,0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00, +0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a,0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21, +0x8e,0x30,0x00,0x00,0x0c,0x00,0x1b,0x63,0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27, +0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04,0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00, +0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40, +0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a,0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00, +0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd, +0x00,0x00,0x00,0x00,0x08,0x00,0x1b,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21, +0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20,0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c, +0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21,0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc, +0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x03, +0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x03, +0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00,0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05, +0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09,0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20, +0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05,0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01, +0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28,0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c, +0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00,0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x01,0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06, +0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50,0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04, +0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14,0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c, +0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c, +0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38, +0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10,0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48, +0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c,0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00, +0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00,0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25, +0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80,0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08, +0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03,0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22, +0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67,0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00, +0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa,0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23, +0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23,0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01, +0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0,0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08, +0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00,0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00, +0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef,0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef, +0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00,0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00, +0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14,0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c, +0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04,0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10, +0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14,0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09, +0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09,0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09, +0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09,0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09, +0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00,0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00, +0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee,0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20, +0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28,0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30, +0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38,0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00, +0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00,0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00, +0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00,0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00, +0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00,0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00, +0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00,0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09, +0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x70,0x70, +0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34,0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a, +0x14,0x40,0x00,0xed,0x00,0x80,0x28,0x21,0x8c,0x84,0x00,0x08,0x24,0x02,0x00,0x03, +0x10,0x82,0x00,0xe0,0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x2c,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x47,0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xc6, +0xac,0xa2,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0xc5,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0xb3,0x00,0x00,0x00,0x00,0x8c,0xa6,0x00,0x04, +0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0xa9,0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x14, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09,0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09, +0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x10,0x40,0x00,0x05,0xac,0xa2,0x00,0x14,0x24,0x02,0x00,0x01,0xac,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x14,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0, +0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x61,0x00,0x16,0x3c,0x03,0xb0,0x05, +0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x10,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0b,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x50, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x05, +0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08, +0xa0,0xa3,0x00,0x50,0x80,0xa2,0x00,0x31,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a, +0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00, +0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09, +0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x00,0x8c,0xa2,0x00,0x40,0x00,0x00,0x00,0x00, +0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02, +0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80, +0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x8c,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00, +0xac,0xa3,0x00,0x10,0x3c,0x02,0xb0,0x03,0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x0f,0xac,0xa2,0x00,0x0c,0x90,0xa3,0x00,0x0f,0x24,0x02,0x00,0x0d, +0x3c,0x01,0xb0,0x03,0x08,0x00,0x1c,0x74,0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09, +0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00, +0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15,0xa0,0xa4,0x00,0x44,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x0c,0xac,0xa3,0x00,0x00, +0x24,0x03,0x00,0x04,0xac,0xa2,0x00,0x10,0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x0c, +0x24,0x02,0x00,0x0d,0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06, +0xac,0xa3,0x00,0x10,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x0c,0x8c,0xa3,0x00,0x38, +0x24,0x04,0x00,0x01,0x10,0x64,0x00,0x2d,0x24,0x02,0x00,0x02,0x10,0x60,0x00,0x19, +0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x10,0x24,0x02,0x00,0x04,0x10,0x62,0x00,0x04, +0x00,0x00,0x00,0x00,0xac,0xa0,0x00,0x38,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x00, +0x10,0xc4,0x00,0x07,0x24,0x02,0x00,0x03,0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00, +0x00,0x02,0x18,0x0b,0xac,0xa3,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x38, +0x08,0x00,0x1c,0xc6,0xac,0xa2,0x00,0x00,0x10,0xc4,0x00,0x02,0x24,0x02,0x00,0x03, +0x24,0x02,0x00,0x0c,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08, +0xac,0xa2,0x00,0x38,0x10,0xc4,0x00,0x0e,0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24, +0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x06, +0xac,0xa2,0x00,0x18,0x24,0x02,0x00,0x02,0xac,0xa2,0x00,0x00,0xac,0xa0,0x00,0x18, +0x08,0x00,0x1c,0xcf,0x24,0x02,0x00,0x01,0x08,0x00,0x1c,0xdc,0xac,0xa0,0x00,0x00, +0x24,0x02,0x00,0x03,0x08,0x00,0x1c,0xdc,0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x0b, +0xac,0xa2,0x00,0x38,0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x00,0x80,0xa2,0x00,0x30, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x55,0x24,0x02,0x00,0x04,0x08,0x00,0x1c,0x74, +0x00,0x00,0x00,0x00,0x84,0xa2,0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x84, +0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, +0x14,0x40,0xff,0x42,0xa4,0xa3,0x00,0x20,0x08,0x00,0x1c,0x74,0x24,0x02,0x00,0x06, +0x8c,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x75,0x24,0x02,0x00,0x05, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x32,0xac,0xa2,0x00,0x1c,0x08,0x00,0x1c,0x74, +0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x65,0x24,0x02,0x00,0x06, +0x08,0x00,0x1c,0x2a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xc8,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x27,0x91,0x91,0xf8,0x27,0x90,0x8f,0x38,0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c, +0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c, +0x0c,0x00,0x2d,0x21,0xaf,0xb2,0x00,0x18,0x0c,0x00,0x07,0x90,0x00,0x00,0x00,0x00, +0xaf,0x91,0x95,0x10,0xaf,0x90,0x99,0x20,0x48,0x02,0x00,0x00,0x0c,0x00,0x1b,0xba, +0x00,0x00,0x00,0x00,0x0c,0x00,0x1f,0x97,0x02,0x00,0x20,0x21,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x3a,0x94,0x43,0x00,0x00,0x3a,0x54,0xff,0xff,0xa3,0x83,0x99,0x24, +0x0c,0x00,0x00,0x34,0x02,0x80,0xa8,0x21,0x0c,0x00,0x1b,0xc5,0x02,0x80,0xb0,0x21, +0x27,0x84,0x8d,0x78,0x0c,0x00,0x32,0x44,0x02,0x80,0xb8,0x21,0x93,0x84,0x80,0x10, +0x0c,0x00,0x28,0xb0,0x00,0x00,0x00,0x00,0x0c,0x00,0x0e,0x84,0x02,0x20,0x20,0x21, +0x0c,0x00,0x01,0x39,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x20,0x0c,0x00,0x1b,0xa3, +0x00,0x00,0x00,0x00,0x27,0x82,0x92,0x2c,0xaf,0x82,0x8d,0x60,0x0c,0x00,0x00,0x5f, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09, +0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00,0x34,0x84,0x01,0x68,0x24,0x02,0xc8,0x80, +0x34,0xa5,0x01,0x40,0x24,0x03,0x00,0x0a,0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00, +0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0xaf,0x86,0x8d,0x18,0x34,0x42,0x00,0x20, +0xac,0x82,0x00,0x00,0x0c,0x00,0x07,0xa1,0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x05, +0x0c,0x00,0x2d,0x39,0x34,0x84,0x00,0x04,0x8f,0x83,0x8d,0x20,0x00,0x00,0x00,0x00, +0x2c,0x62,0x00,0x11,0x10,0x40,0xff,0xf7,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01, +0x24,0x63,0x08,0xac,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x78,0x0c,0x00,0x31,0x79, +0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x20,0x0c,0x00,0x1c,0x1c,0x00,0x00,0x00,0x00, +0x93,0x83,0x88,0x6d,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0x00,0x00,0x00,0x00, +0x8f,0x82,0x8d,0x54,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x8d,0x54, +0x08,0x00,0x1d,0x55,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x78,0x0c,0x00,0x31,0xf8, +0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x78, +0x0c,0x00,0x33,0xda,0x00,0x00,0x00,0x00,0xa3,0x82,0x8d,0x51,0xaf,0x80,0x8d,0x20, +0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x27,0x84,0x8f,0x38,0x0c,0x00,0x20,0xd3, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05, +0xaf,0x80,0x8d,0x20,0xaf,0x80,0x8d,0x24,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00, +0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0xaf,0x82,0x8d,0x4c,0x14,0x40,0x00,0x1e,0x24,0x02,0x00,0x01,0x8f,0x84,0x8d,0x28, +0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x1d,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x8d,0x34, +0x14,0x40,0x00,0x13,0x24,0x02,0x00,0x01,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07, +0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x03,0xaf,0x82,0x8d,0x24, +0xaf,0x83,0x8d,0x20,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x34,0x42,0x02,0x2e, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x00,0x60,0x10,0x21,0xa7,0x83,0x8d,0x40,0x14,0x40,0xff,0xf3,0x24,0x02,0x00,0x01, +0xaf,0x82,0x8d,0x24,0x08,0x00,0x1d,0x7f,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x05, +0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0xaf,0x82,0x8d,0x3c,0x14,0x40,0xff,0xf6,0x24,0x02,0x00,0x01,0x08,0x00,0x1d,0x97, +0x3c,0x03,0xb0,0x09,0x27,0x84,0x8f,0x38,0x0c,0x00,0x22,0x4c,0x00,0x00,0x00,0x00, +0x83,0x82,0x8d,0x50,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xed,0x24,0x02,0x00,0x02, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0xaf,0x82,0x8d,0x4c,0x14,0x40,0xff,0xe5,0x24,0x02,0x00,0x02, +0x8f,0x84,0x8d,0x28,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x12,0x24,0x02,0x00,0x02, +0x10,0x82,0x00,0x05,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x02,0xaf,0x82,0x8d,0x24, +0x08,0x00,0x1d,0xa4,0x24,0x03,0x00,0x04,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, +0xa7,0x83,0x8d,0x40,0x14,0x40,0xff,0xf4,0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0xb0, +0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x8d,0x3c,0x14,0x40,0xff,0xf7, +0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0xd0,0x24,0x02,0x00,0x02,0x27,0x84,0x91,0xf8, +0x0c,0x00,0x12,0xe2,0x00,0x00,0x00,0x00,0x8f,0x83,0x8d,0x24,0xaf,0x82,0x8d,0x3c, +0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,0xaf,0x83,0x8d,0x24,0x14,0x40,0x00,0x08, +0x24,0x02,0x00,0x05,0x8f,0x82,0x92,0x38,0xaf,0x80,0x8d,0x20,0x10,0x40,0xff,0x78, +0x24,0x04,0x00,0x01,0xaf,0x84,0x8d,0x28,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00, +0xaf,0x82,0x8d,0x20,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x83,0x82,0x8d,0x70, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x8d,0x3c, +0x8f,0x85,0x8d,0x3c,0x27,0x84,0x91,0xf8,0x0c,0x00,0x14,0xbd,0x00,0x00,0x00,0x00, +0x00,0x02,0x1e,0x00,0xa3,0x82,0x8d,0x50,0xaf,0x80,0x8d,0x3c,0x10,0x60,0xff,0x73, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x8d,0x40, +0x10,0x40,0xff,0xe7,0x24,0x02,0x00,0x06,0x24,0x04,0x00,0x02,0xaf,0x84,0x8d,0x28, +0x08,0x00,0x1d,0x7f,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x20,0x27,0x85,0x91,0xf8, +0x0c,0x00,0x15,0x83,0x00,0x00,0x00,0x00,0x8f,0x82,0x8d,0x44,0xaf,0x80,0x8d,0x4c, +0x14,0x40,0x00,0x18,0x00,0x40,0x18,0x21,0x8f,0x82,0x8d,0x48,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x14,0x24,0x02,0x00,0x02,0x8f,0x83,0x8d,0x28,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x01,0x8f,0x83,0x8d,0x24,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x06,0xaf,0x82,0x8d,0x20, +0x08,0x00,0x1d,0xf9,0x24,0x04,0x00,0x03,0x3c,0x02,0x40,0x00,0x34,0x42,0x00,0x14, +0x3c,0x01,0xb0,0x05,0xac,0x22,0x00,0x00,0xaf,0x80,0x8d,0x20,0x08,0x00,0x1d,0xf9, +0x24,0x04,0x00,0x03,0x10,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x20, +0x27,0x85,0x91,0xf8,0x0c,0x00,0x15,0xa7,0x00,0x00,0x00,0x00,0x8f,0x83,0x8d,0x24, +0x24,0x02,0x00,0x01,0xa3,0x80,0x8d,0x50,0xaf,0x80,0x8d,0x28,0x10,0x62,0x00,0x02, +0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x04,0xaf,0x82,0x8d,0x20,0xaf,0x80,0x8d,0x44, +0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x83,0x82,0x8d,0x70,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x27,0x84,0x91,0xf8,0x0c,0x00,0x17,0xef, +0x00,0x00,0x00,0x00,0x8f,0x82,0x8d,0x24,0xa3,0x80,0x8d,0x50,0xaf,0x80,0x8d,0x20, +0xaf,0x80,0x8d,0x28,0x14,0x40,0x00,0x02,0x24,0x02,0x00,0x02,0xaf,0x82,0x8d,0x24, +0xaf,0x80,0x8d,0x48,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x20, +0x27,0x85,0x91,0xf8,0x0c,0x00,0x15,0xa7,0x00,0x00,0x00,0x00,0x8f,0x82,0x8d,0x24, +0xa3,0x80,0x8d,0x50,0xaf,0x80,0x8d,0x20,0xaf,0x80,0x8d,0x28,0x14,0x40,0xff,0x0c, +0x24,0x02,0x00,0x02,0xaf,0x82,0x8d,0x24,0x08,0x00,0x1d,0x70,0x00,0x00,0x00,0x00, +0x27,0x84,0x91,0xf8,0x0c,0x00,0x17,0xef,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0x5f, +0x00,0x00,0x00,0x00,0x27,0x84,0x8d,0x78,0x0c,0x00,0x34,0x70,0x00,0x00,0x00,0x00, +0x08,0x00,0x1d,0x7e,0x00,0x00,0x00,0x00,0x0c,0x00,0x2b,0x15,0x00,0x00,0x00,0x00, +0x0c,0x00,0x31,0xea,0x00,0x00,0x00,0x00,0x0c,0x00,0x1f,0x89,0x00,0x00,0x00,0x00, +0x93,0x83,0xc5,0x58,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x1c,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xc5,0x50,0x8f,0x82,0xc5,0x54, +0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x14,0x2e,0xa3,0x00,0x01, +0x2e,0x82,0x00,0x01,0x00,0x43,0x10,0x25,0x2e,0xc4,0x00,0x01,0x00,0x44,0x10,0x25, +0x2e,0xe3,0x00,0x01,0x3c,0x05,0xb0,0x03,0x00,0x43,0x10,0x25,0x34,0xa5,0x01,0x18, +0x8c,0xa3,0x00,0x00,0x14,0x40,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21, +0x0c,0x00,0x0b,0x7e,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08, +0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0xc5,0x50,0x0c,0x00,0x01,0xe9, +0x00,0x00,0x00,0x00,0xaf,0x80,0x8d,0x20,0xaf,0x80,0x8d,0x54,0x08,0x00,0x1d,0x55, +0x00,0x00,0x00,0x00,0x27,0x90,0xbd,0x40,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00, +0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x20,0x48,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff, +0x06,0x21,0xff,0xf6,0x26,0x10,0x00,0x04,0x08,0x00,0x1d,0x7f,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x8d,0x18, +0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xfe,0xcc,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05,0xaf,0x84,0x8d,0x18, +0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21,0x36,0x52,0x02,0x2c, +0x27,0x90,0xbd,0x40,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06,0x30,0x62,0x00,0x1c, +0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x8d,0x18,0x0c,0x00,0x26,0x05, +0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x14,0x40,0xfe,0xae,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01,0x2a,0x22,0x00,0x13, +0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x1d,0x7f,0x00,0x00,0x00,0x00, +0x8f,0x84,0x8d,0x2c,0x27,0x85,0x91,0xf8,0x0c,0x00,0x1f,0x1c,0x00,0x00,0x00,0x00, +0x8f,0x83,0x8d,0x2c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa0,0x24,0x02,0x00,0x05, +0x08,0x00,0x1d,0xfc,0x00,0x00,0x00,0x00,0x27,0x84,0x91,0xf8,0x0c,0x00,0x2b,0x3c, +0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0xa4,0x24,0x03,0x00,0x05,0x8f,0x82,0x92,0x2c, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xbd,0x80, +0xaf,0x80,0x92,0x2c,0x94,0x85,0x00,0x14,0x0c,0x00,0x22,0xe1,0x00,0x00,0x00,0x00, +0x93,0x82,0x94,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x8f,0x84,0xbd,0x80, +0x0c,0x00,0x20,0x48,0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x7f,0x00,0x00,0x00,0x00, +0x3c,0x02,0xff,0x90,0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01, +0x27,0x84,0x91,0xf8,0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x0e,0x84, +0x00,0x00,0x00,0x00,0x27,0x84,0x8f,0x38,0x0c,0x00,0x1f,0x97,0x00,0x00,0x00,0x00, +0x27,0x84,0x8d,0x20,0x0c,0x00,0x1b,0xa3,0x00,0x00,0x00,0x00,0x08,0x00,0x1f,0x03, +0x00,0x00,0x00,0x00,0x8f,0x82,0x92,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05, +0x00,0x00,0x18,0x21,0x8f,0x82,0x8d,0x28,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02, +0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x34,0xc6,0x00,0x5f,0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x5d,0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01, +0xa0,0xc3,0x00,0x00,0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21, +0x35,0x29,0x00,0x5e,0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00, +0x91,0x03,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01, +0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c, +0x24,0x05,0x0f,0x00,0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x02,0x08,0x00,0x1f,0x3d,0x3c,0x02,0xb0,0x03, +0x24,0x04,0x08,0x8c,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80, +0x24,0x05,0x1e,0x00,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x1b,0x29,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30, +0x24,0x06,0x00,0x03,0x0c,0x00,0x1b,0x29,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21, +0x24,0x05,0x00,0x14,0x0c,0x00,0x1b,0x6e,0x24,0x06,0x01,0x07,0x08,0x00,0x1f,0x3d, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0xa3,0x80,0x87,0x6d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0xa3,0x82,0x87,0x6d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x7e,0x5c, +0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xb8, +0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21, +0xa7,0x82,0x99,0x30,0x27,0x88,0x99,0x40,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08, +0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21, +0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21, +0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4, +0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c, +0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xbd,0x1c, +0xac,0x43,0x00,0x00,0xaf,0x84,0xbd,0x40,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xbd,0x40,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03, +0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xbd,0x44, +0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xbd,0x44,0x25,0xc4,0x00,0x54, +0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xbd,0x48,0xa0,0x88,0x00,0x18, +0x94,0x65,0x00,0x00,0x8f,0x82,0xbd,0x48,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01, +0xa0,0x45,0x00,0x21,0xaf,0x87,0xbd,0x4c,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00, +0x8f,0x82,0xbd,0x4c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21, +0xaf,0x88,0xbd,0x50,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xbd,0x50, +0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xbd,0x54, +0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xbd,0x54,0x25,0xc4,0x00,0xe4, +0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xbd,0x58,0xa0,0x80,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xbd,0x58,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c, +0xa0,0x45,0x00,0x21,0xaf,0x83,0xbd,0x5c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00, +0x8f,0x82,0xbd,0x5c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21, +0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04, +0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03, +0xaf,0x87,0xbd,0x60,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xbd,0x64, +0xa0,0x80,0x00,0x18,0xaf,0x85,0xbd,0x68,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xbd,0x6c, +0xa0,0xc0,0x00,0x18,0xaf,0x89,0xbd,0x70,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xbd,0x74, +0xa1,0x40,0x00,0x18,0xaf,0x8b,0xbd,0x78,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xbd,0x7c, +0xa1,0x80,0x00,0x18,0xaf,0x8d,0xbd,0x80,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00, +0x8f,0x82,0xbd,0x80,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21, +0x24,0x02,0x00,0x11,0xaf,0x85,0xbd,0x84,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18, +0x94,0x64,0x00,0x00,0x8f,0x82,0xbd,0x84,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03, +0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xbd,0x88,0x34,0x63,0x00,0x6c, +0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xbd,0x88,0x24,0x05,0xff,0xff, +0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xbd,0x40, +0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00, +0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14, +0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20, +0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x81,0x20, +0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x80,0x60,0x21,0x10,0x40,0x00,0x56, +0x00,0x00,0x70,0x21,0x97,0x82,0x99,0x30,0x94,0x8a,0x00,0x0c,0x27,0x87,0x99,0x40, +0x00,0x02,0x40,0xc0,0x01,0x02,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21, +0x90,0x8b,0x00,0x18,0xa4,0x4a,0x00,0x00,0x94,0x83,0x00,0x0e,0x39,0x64,0x00,0x10, +0x2c,0x84,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x34,0x85,0x00,0x02, +0x39,0x63,0x00,0x11,0x00,0x83,0x28,0x0b,0x34,0xa3,0x00,0x08,0x39,0x64,0x00,0x12, +0x00,0x02,0x10,0x80,0x00,0xa4,0x18,0x0b,0x00,0x47,0x10,0x21,0x94,0x49,0x00,0x04, +0x34,0x64,0x00,0x20,0x00,0x6b,0x20,0x0b,0x34,0x83,0x00,0x40,0x39,0x62,0x00,0x01, +0x00,0x82,0x18,0x0b,0x00,0x09,0x30,0xc0,0x34,0x64,0x00,0x80,0x00,0xc9,0x28,0x21, +0x39,0x62,0x00,0x02,0x00,0x60,0x68,0x21,0x00,0x82,0x68,0x0a,0x00,0x05,0x28,0x80, +0x3c,0x02,0xb0,0x08,0x00,0xa7,0x28,0x21,0x00,0xc2,0x30,0x21,0x01,0x02,0x40,0x21, +0x34,0x03,0xff,0xff,0x35,0xa4,0x01,0x00,0x39,0x62,0x00,0x03,0x2d,0x67,0x00,0x13, +0xad,0x0a,0x00,0x00,0xa4,0xa3,0x00,0x00,0xac,0xc3,0x00,0x00,0xa7,0x89,0x99,0x30, +0x10,0xe0,0x00,0x0f,0x00,0x82,0x68,0x0a,0x3c,0x03,0x80,0x01,0x00,0x0b,0x10,0x80, +0x24,0x63,0x08,0xf0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x60, +0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,0x00,0x02,0x74,0x03, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x44,0x00,0x00,0x93,0x83,0x99,0x24, +0x91,0x82,0x00,0x21,0x01,0xc4,0x20,0x21,0x91,0x85,0x00,0x10,0x00,0x04,0x24,0x00, +0x00,0x62,0x18,0x21,0x00,0x04,0x74,0x03,0x00,0x6e,0x18,0x23,0x00,0x65,0x10,0x2a, +0x00,0xa2,0x18,0x0a,0x00,0x0d,0x24,0x00,0x3c,0x02,0xb0,0x06,0x24,0x05,0xff,0xff, +0x00,0x64,0x18,0x25,0x34,0x42,0x80,0x20,0xac,0x43,0x00,0x00,0xa5,0x85,0x00,0x0e, +0xa1,0x80,0x00,0x10,0xa5,0x85,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x20,0x8c,0x34,0x63,0x00,0x62,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x20,0x8c,0x34,0x63,0x00,0x64,0x3c,0x03,0xb0,0x03,0x08,0x00,0x20,0x8c, +0x34,0x63,0x00,0x66,0x3c,0x03,0xb0,0x03,0x08,0x00,0x20,0x8c,0x34,0x63,0x00,0x38, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x20,0x8c,0x34,0x63,0x00,0x6e,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x20,0x8c,0x34,0x63,0x00,0x6c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x63,0x00,0x20,0x24,0x42,0x82,0xe8,0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00, +0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21, +0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10, +0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,0x00,0x02,0x11,0x00,0x08,0x00,0x20,0xc7, +0x00,0x47,0x18,0x21,0x08,0x00,0x20,0xc7,0x24,0xa3,0x00,0x50,0x27,0xbd,0xff,0xc8, +0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24, +0xaf,0xb0,0x00,0x10,0x00,0x80,0x90,0x21,0x84,0x84,0x00,0x08,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20,0x24,0x42,0x83,0x4c,0x3c,0x03,0xb0,0x06, +0x00,0x04,0x20,0x80,0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x06,0xb0,0x06, +0x8c,0x82,0x00,0x00,0x34,0xc6,0x80,0x24,0x8c,0x88,0x00,0x00,0x8c,0xc4,0x00,0x00, +0x96,0x45,0x00,0x08,0x30,0x53,0xff,0xff,0x00,0x08,0x44,0x02,0x34,0x84,0x01,0x00, +0x3c,0x02,0xb0,0x00,0x00,0x08,0x18,0xc0,0x00,0x13,0x3a,0x00,0xac,0xc4,0x00,0x00, +0x00,0xe2,0x38,0x21,0xae,0x53,0x02,0xb8,0x00,0x68,0x18,0x21,0x24,0xa5,0x00,0x02, +0x8c,0xf6,0x00,0x00,0x30,0xa5,0x01,0xff,0x8c,0xf5,0x00,0x04,0x27,0x86,0x99,0x40, +0x00,0x03,0x18,0x80,0x00,0x13,0xa0,0xc0,0xa6,0x45,0x00,0x08,0x00,0x66,0x18,0x21, +0x02,0x93,0x10,0x21,0x00,0x02,0x48,0x80,0x94,0x65,0x00,0x00,0x01,0x26,0x30,0x21, +0x24,0x02,0xff,0xff,0x00,0x15,0x1a,0x02,0x27,0x84,0x99,0x50,0xa4,0xc2,0x00,0x02, +0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,0x01,0x24,0x20,0x21,0xa4,0xc8,0x00,0x04, +0x8c,0xf0,0x00,0x08,0xa6,0x43,0x00,0x06,0xa6,0x45,0x00,0x0a,0xa0,0x82,0x00,0x06, +0x86,0x43,0x00,0x06,0x27,0x82,0x99,0x44,0x01,0x22,0x88,0x21,0x24,0x02,0x00,0x13, +0x10,0x62,0x00,0xee,0xae,0x27,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, +0xa6,0x40,0x00,0x02,0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08, +0x8c,0x45,0x00,0x00,0x00,0x10,0x1b,0xc2,0x00,0x04,0x20,0x82,0x30,0x63,0x00,0x01, +0xac,0xc5,0x00,0x08,0x10,0x60,0x00,0xc7,0x30,0x97,0x00,0x01,0x00,0x10,0x16,0x82, +0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,0x00,0x10,0x26,0x02, +0x00,0x10,0x2e,0x42,0x30,0x48,0x00,0x7f,0x24,0x02,0x00,0x01,0x30,0x71,0x00,0x01, +0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xb3,0x30,0xa3,0x00,0x01,0x00,0x60,0x28,0x21, +0x0c,0x00,0x20,0xba,0x01,0x00,0x38,0x21,0x02,0x93,0x18,0x21,0x00,0x03,0x18,0x80, +0x2c,0x46,0x00,0x54,0x27,0x85,0x99,0x50,0x27,0x84,0x99,0x48,0x00,0x06,0x10,0x0a, +0x00,0x65,0x28,0x21,0x26,0x26,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02, +0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x93,0x28,0x21, +0x00,0x05,0x28,0x80,0x27,0x82,0x99,0x44,0x00,0xa2,0x58,0x21,0x8d,0x64,0x00,0x18, +0x00,0x10,0x15,0xc2,0x30,0x42,0x00,0x01,0x8c,0x83,0x00,0x0c,0x27,0x84,0x99,0x60, +0x00,0xa4,0x48,0x21,0xa6,0x42,0x00,0x00,0xa6,0x56,0x00,0x04,0x8d,0x26,0x00,0x00, +0x00,0x03,0x19,0x42,0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01, +0x00,0xc2,0x40,0x24,0x00,0x03,0x1d,0x00,0x01,0x03,0x40,0x25,0x00,0x08,0x15,0x02, +0x00,0x10,0x34,0x42,0x00,0x10,0x3c,0x82,0x00,0x15,0x19,0x82,0x00,0x15,0x25,0x82, +0x00,0x10,0x2c,0x02,0x30,0x42,0x00,0x01,0x30,0xcd,0x00,0x01,0x30,0x6c,0x00,0x01, +0x30,0xe6,0x00,0x01,0x30,0x8a,0x00,0x03,0x32,0xb1,0x00,0x07,0x30,0xa5,0x00,0x01, +0xad,0x28,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,0x8d,0x64,0x00,0x18, +0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,0x01,0x03,0x18,0x24, +0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,0x00,0x62,0x18,0x25, +0xad,0x23,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x6a,0x00,0x00,0x00,0x00, +0x15,0x80,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x5b,0x24,0x02,0x00,0x01, +0x96,0x42,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,0xa6,0x42,0x00,0x04, +0x00,0xa0,0x20,0x21,0x0c,0x00,0x20,0xba,0x01,0xa0,0x28,0x21,0x02,0x93,0x18,0x21, +0x00,0x03,0x40,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x99,0x50,0x01,0x04,0x20,0x21, +0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, +0x96,0x43,0x00,0x04,0x27,0x82,0x99,0x40,0x01,0x02,0x10,0x21,0xa4,0x43,0x00,0x06, +0x27,0x82,0x99,0x44,0x92,0x46,0x00,0x01,0x01,0x02,0x10,0x21,0x8c,0x45,0x00,0x18, +0x27,0x83,0x99,0x60,0x01,0x03,0x18,0x21,0xa0,0x60,0x00,0x00,0xa0,0x86,0x00,0x07, +0x94,0xa2,0x00,0x10,0x24,0x03,0x00,0x04,0x30,0x42,0x00,0x0f,0x10,0x43,0x00,0x36, +0x24,0xa5,0x00,0x10,0x94,0xa3,0x00,0x16,0x27,0x87,0x99,0x58,0x01,0x07,0x10,0x21, +0xa4,0x43,0x00,0x02,0x94,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x24,0x02,0x93,0x20,0x21,0x94,0xa2,0x00,0x00,0x24,0x03,0x00,0xa4, +0x30,0x42,0x00,0xff,0x10,0x43,0x00,0x1f,0x00,0x00,0x00,0x00,0x94,0xa2,0x00,0x00, +0x24,0x03,0x00,0x88,0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x14,0x02,0x93,0x18,0x21, +0x27,0x84,0x99,0x60,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00, +0x3c,0x04,0x00,0x80,0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x93,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa0,0x51,0x00,0x00,0x8f,0xbf,0x00,0x30, +0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x94,0xa2,0x00,0x18, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xe9,0x02,0x93,0x18,0x21, +0x02,0x93,0x20,0x21,0x27,0x82,0x99,0x60,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21, +0x8c,0x83,0x00,0x00,0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24, +0x08,0x00,0x21,0xaf,0xac,0x83,0x00,0x00,0x27,0x87,0x99,0x58,0x01,0x07,0x10,0x21, +0x08,0x00,0x21,0x99,0xa4,0x40,0x00,0x02,0x11,0x42,0x00,0x07,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x02,0x14,0x40,0xff,0xa7,0x00,0xa0,0x20,0x21,0x96,0x42,0x00,0x04, +0x08,0x00,0x21,0x77,0x24,0x42,0x00,0x0c,0x96,0x42,0x00,0x04,0x08,0x00,0x21,0x77, +0x24,0x42,0x00,0x08,0x16,0xe6,0xff,0x96,0x3c,0x02,0xff,0xfb,0x8d,0x63,0x00,0x18, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x21,0x70, +0x00,0x00,0x30,0x21,0x16,0xe6,0xff,0x4e,0x00,0x60,0x28,0x21,0x3c,0x02,0xfb,0xff, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0xe2,0x00,0x08,0x08,0x00,0x21,0x2f, +0x00,0x00,0x30,0x21,0x93,0x87,0xc4,0x54,0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82, +0x27,0x82,0x99,0x48,0x2c,0xe5,0x00,0x0c,0x01,0x22,0x48,0x21,0x30,0x63,0x00,0x01, +0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,0x00,0xe0,0x40,0x21,0x00,0x03,0x10,0x40, +0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0xe2,0x10,0x21,0x24,0x48,0x00,0x04, +0x02,0x93,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x99,0x50,0x27,0x83,0x99,0x48, +0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,0xa1,0x28,0x00,0x07,0xa0,0x40,0x00,0x06, +0xa0,0x80,0x00,0x02,0x08,0x00,0x21,0x3f,0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01, +0x00,0xe0,0x20,0x21,0x0c,0x00,0x01,0xc2,0xa6,0x42,0x00,0x02,0x8e,0x24,0x00,0x18, +0x0c,0x00,0x05,0x39,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xb3,0x00,0x00,0x00,0x00, +0x30,0xa7,0xff,0xff,0x00,0x07,0x18,0xc0,0x00,0x67,0x18,0x21,0x3c,0x06,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x24,0x42,0x88,0x30,0x27,0x85,0x99,0x50,0x00,0x03,0x18,0x80, +0x34,0xc6,0x00,0x20,0x00,0x65,0x18,0x21,0xac,0xc2,0x00,0x00,0x80,0x62,0x00,0x07, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x29,0x00,0x80,0x28,0x21,0x90,0x82,0x00,0x16, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01,0x14,0x60,0x00,0x02, +0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x90,0xa2,0x00,0x04,0x3c,0x03,0xb0,0x03, +0x27,0x86,0x99,0x40,0x14,0x40,0x00,0x06,0x34,0x63,0x00,0x20,0x24,0x02,0x00,0x01, +0xa0,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,0x03,0xe0,0x00,0x08,0xa4,0xa7,0x00,0x00, +0x94,0xa4,0x00,0x02,0x3c,0x02,0x80,0x01,0x24,0x42,0xa0,0x30,0xac,0x62,0x00,0x00, +0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21, +0x94,0x62,0x00,0x04,0xa4,0x67,0x00,0x02,0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0, +0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x00,0x83,0x20,0x21, +0xa4,0x47,0x00,0x00,0xac,0x87,0x00,0x00,0x90,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02, +0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x04,0x90,0x82,0x00,0x16, +0x24,0x85,0x00,0x06,0x34,0x42,0x00,0x01,0x30,0x43,0x00,0x02,0x14,0x60,0xff,0xda, +0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,0x08,0x00,0x22,0x22,0xa0,0x82,0x00,0x17, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0x80,0x38,0x21,0x84,0x84,0x00,0x02, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x3c,0x0a,0xb0,0x06,0x34,0x63,0x00,0x20, +0x24,0x42,0x89,0x30,0x3c,0x0b,0xb0,0x08,0x27,0x89,0x99,0x40,0x34,0x0c,0xff,0xff, +0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,0xac,0x62,0x00,0x00,0x97,0x82,0x99,0x30, +0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,0x00,0x6b,0x28,0x21,0xac,0xa6,0x00,0x00, +0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x04,0x10,0xc0, +0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x94,0x48,0x00,0x04, +0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,0x00,0x08,0x28,0xc0,0x00,0xab,0x10,0x21, +0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x27,0x82,0x99,0x44,0x00,0xa8,0x28,0x21, +0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21, +0x8c,0x46,0x00,0x18,0x27,0x84,0x99,0x50,0x00,0x64,0x18,0x21,0x8c,0xc2,0x00,0x00, +0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,0x30,0x42,0xff,0xff,0x00,0x47,0x10,0x21, +0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21, +0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,0x00,0x44,0x10,0x25,0xa4,0xac,0x00,0x00, +0xad,0x42,0x00,0x00,0xa7,0x88,0x99,0x30,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x84,0xe3,0x00,0x06,0x27,0x82,0xbd,0x40, +0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00, +0x0c,0x00,0x22,0x0c,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x86,0x00,0x00,0x00,0x00, +0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,0x27,0x8a,0x99,0x40,0x00,0x08,0x18,0xc0, +0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,0x00,0x03,0x18,0x80,0x3c,0x02,0x80,0x01, +0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x8a,0x50,0x30,0xa5,0xff,0xff, +0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,0x11,0x05,0x00,0x35,0x24,0x04,0x00,0x01, +0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x86,0x10,0x2a,0x10,0x40,0x00,0x10, +0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,0x01,0x40,0x60,0x21,0x35,0xad,0x00,0x20, +0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21, +0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,0x00,0x4a,0x10,0x21,0x00,0x86,0x18,0x2a, +0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,0x14,0x60,0xff,0xf5,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x00,0x08,0x20,0xc0,0x00,0x88,0x20,0x21, +0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,0xa1,0x62,0x00,0x04,0x00,0x8c,0x20,0x21, +0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,0x94,0x46,0x00,0x02,0x00,0xa3,0x18,0x21, +0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,0xa4,0x66,0x00,0x00,0xa4,0x86,0x00,0x02, +0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,0x3c,0x02,0x80,0x01,0x00,0xa3,0x28,0x21, +0x24,0x42,0xa0,0x30,0xad,0xa2,0x00,0x00,0x10,0x87,0x00,0x03,0xac,0xa6,0x00,0x00, +0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x08,0x00,0x22,0xd4,0xa5,0x68,0x00,0x02, +0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,0x24,0x42,0xff,0xff,0x30,0x43,0x00,0xff, +0x14,0x60,0xff,0xf7,0xa1,0x62,0x00,0x04,0x24,0x02,0xff,0xff,0x08,0x00,0x22,0xd4, +0xa5,0x62,0x00,0x02,0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,0x27,0xbd,0xff,0xd8, +0x00,0x06,0x30,0x80,0x27,0x82,0x99,0x44,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,0x00,0xc2,0x10,0x21, +0x8c,0x47,0x00,0x18,0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x01,0x3c,0x05,0xb0,0x03, +0x34,0xa5,0x00,0x20,0x24,0x42,0x8b,0x84,0xac,0xa2,0x00,0x00,0x27,0x83,0x99,0x50, +0x00,0xc3,0x30,0x21,0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,0x00,0x80,0x88,0x21, +0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x02, +0x00,0x02,0x12,0x02,0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,0x01,0x12,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x50,0x00,0x43,0x10,0x21,0x80,0x44,0x00,0x07, +0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,0x32,0x50,0xff,0xff, +0x02,0x20,0x20,0x21,0x0c,0x00,0x22,0x94,0x02,0x00,0x28,0x21,0x92,0x22,0x00,0x10, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,0x3c,0x09,0x80,0x01, +0x27,0x88,0x99,0x40,0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,0x00,0x90,0x20,0x21, +0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08, +0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x48,0x10,0x21,0x00,0xa3,0x28,0x21,0x25,0x26,0xa0,0x30,0x34,0x03,0xff,0xff, +0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00, +0xac,0xa3,0x00,0x00,0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,0xa6,0x32,0x00,0x0e, +0x02,0x62,0x10,0x21,0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,0x92,0x22,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,0x92,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x20, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x96,0x22,0x00,0x0e,0x27,0x88,0x99,0x40,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21, +0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x06,0xb0,0x03, +0x3c,0x09,0x80,0x01,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0xa3,0x28,0x21,0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,0x25,0x23,0xa0,0x30, +0xac,0xc3,0x00,0x00,0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,0x08,0x00,0x23,0x12, +0xa4,0x90,0x00,0x02,0x08,0x00,0x23,0x09,0x32,0x50,0xff,0xff,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x24,0x42,0x8d,0x4c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00, +0x90,0x82,0x00,0x04,0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,0x30,0xa8,0xff,0xff, +0x00,0x4a,0x20,0x23,0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,0x30,0xee,0xff,0xff, +0x11,0x09,0x00,0x73,0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,0x00,0x08,0x10,0xc0, +0x00,0x48,0x10,0x21,0x03,0x0e,0x20,0x21,0x27,0x8d,0x99,0x40,0x00,0x04,0x20,0x80, +0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,0x94,0x86,0x00,0x02, +0x94,0x43,0x00,0x04,0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,0x00,0x03,0x28,0xc0, +0x00,0xa3,0x18,0x21,0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,0x00,0x03,0x18,0x80, +0x00,0xa2,0x28,0x21,0x00,0x6d,0x18,0x21,0x27,0x22,0xa0,0x30,0x3c,0x01,0xb0,0x03, +0xac,0x22,0x00,0x20,0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,0xac,0xa6,0x00,0x00, +0x01,0xe0,0x30,0x21,0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,0x01,0x40,0x38,0x21, +0x27,0x8b,0x99,0x44,0x27,0x8a,0x99,0x50,0x00,0x06,0x40,0xc0,0x01,0x06,0x18,0x21, +0x00,0x03,0x18,0x80,0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x6a,0x18,0x21, +0x80,0x65,0x00,0x06,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0xff,0xff, +0x00,0x45,0x10,0x21,0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,0x01,0x22,0x18,0x21, +0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,0x30,0x69,0x00,0xff, +0x01,0x06,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x24,0xe7,0xff,0xff, +0x94,0x46,0x00,0x02,0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,0x91,0x82,0x00,0x10, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,0xa5,0x8f,0x00,0x0c, +0x03,0x0e,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04, +0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,0x27,0x26,0xa0,0x30, +0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02, +0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,0x91,0x83,0x00,0x04, +0xa5,0x8e,0x00,0x0e,0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,0xa1,0x82,0x00,0x10, +0x91,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa1,0x82,0x00,0x16, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,0x3c,0x03,0xb0,0x08, +0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21, +0x94,0x82,0x00,0x04,0x34,0xc6,0x00,0x20,0x27,0x27,0xa0,0x30,0x00,0x02,0x28,0xc0, +0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x4d,0x10,0x21, +0xac,0xc7,0x00,0x00,0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,0xac,0xaf,0x00,0x00, +0x08,0x00,0x23,0xa1,0x03,0x0e,0x20,0x21,0x08,0x00,0x23,0x7c,0xa5,0x88,0x00,0x02, +0x00,0x0e,0xc0,0xc0,0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8d,0x99,0x40, +0x00,0x4d,0x10,0x21,0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x05, +0xa5,0x83,0x00,0x00,0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,0x08,0x00,0x23,0x7c, +0xa5,0x82,0x00,0x02,0x08,0x00,0x23,0x7c,0x3c,0x19,0x80,0x01,0x3c,0x08,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20,0x24,0x42,0x8f,0x8c, +0xaf,0xb2,0x00,0x68,0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60,0xad,0x02,0x00,0x00, +0xaf,0xbf,0x00,0x84,0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c,0xaf,0xb6,0x00,0x78, +0xaf,0xb5,0x00,0x74,0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c,0xaf,0xa4,0x00,0x88, +0x90,0x83,0x00,0x0a,0x27,0x82,0xbd,0x40,0xaf,0xa6,0x00,0x90,0x00,0x03,0x18,0x80, +0x00,0x62,0x18,0x21,0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94,0x27,0x86,0x99,0x44, +0xaf,0xa3,0x00,0x1c,0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff,0x24,0x08,0x00,0x01, +0x00,0x03,0x20,0xc0,0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21,0xaf,0xa4,0x00,0x54, +0x00,0x03,0x18,0x80,0x27,0x84,0x99,0x50,0x00,0x64,0x20,0x21,0x80,0x82,0x00,0x06, +0x00,0x66,0x18,0x21,0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2, +0x8c,0xc4,0x00,0x08,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0x04,0x2f,0xc2,0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21,0x00,0x04,0x24,0x42, +0x8f,0xa2,0x00,0x1c,0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01,0xaf,0xa5,0x00,0x3c, +0xaf,0xa3,0x00,0x34,0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40,0xaf,0xa0,0x00,0x44, +0xaf,0xa0,0x00,0x50,0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12,0x8f,0xb2,0x00,0x18, +0xaf,0xa2,0x00,0x28,0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xda,0x00,0x60,0x30,0x21, +0x00,0x10,0x10,0x82,0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,0xaf,0xa0,0x00,0x30, +0x8f,0xa4,0x00,0x98,0x27,0x82,0x86,0x30,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x21, +0x24,0xa2,0x00,0x05,0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,0x00,0x45,0x10,0x04, +0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, +0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x10,0x30,0x42,0xff,0xfc,0xaf,0xa2,0x00,0x30, +0x8f,0xa3,0x00,0x18,0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,0xaf,0xa0,0x00,0x2c, +0xaf,0xa2,0x00,0x48,0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21,0x00,0x00,0xb8,0x21, +0x18,0x80,0x00,0x4e,0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,0xaf,0xb1,0x00,0x58, +0x00,0x80,0xa8,0x21,0x00,0x12,0x10,0xc0,0x00,0x52,0x20,0x21,0x00,0x04,0x20,0x80, +0x00,0x40,0xa0,0x21,0x27,0x82,0x99,0x58,0x00,0x82,0x10,0x21,0x94,0x43,0x00,0x02, +0x8f,0xa6,0x00,0x58,0x27,0x85,0x99,0x40,0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23, +0x30,0x63,0x0f,0xff,0x00,0x85,0x20,0x21,0x28,0x62,0x00,0x20,0x94,0x96,0x00,0x02, +0x10,0x40,0x01,0xa1,0x28,0x62,0x00,0x40,0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00, +0x00,0x68,0x10,0x06,0x30,0x43,0x00,0x01,0x24,0x02,0x00,0x01,0x10,0x62,0x01,0x7b, +0x3c,0x02,0xb0,0x03,0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,0x84,0xc5,0x00,0x0c, +0x02,0x92,0x18,0x21,0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,0x00,0x85,0x20,0x21, +0x00,0x03,0x18,0x80,0x27,0x82,0x99,0x50,0x27,0x85,0x99,0x48,0x00,0x65,0x28,0x21, +0x00,0x62,0x18,0x21,0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,0x8f,0xa3,0x00,0x88, +0x30,0xd0,0xff,0xff,0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,0x27,0x82,0x99,0x60, +0x00,0x04,0x20,0x80,0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,0xa4,0x67,0x00,0x44, +0xa4,0x68,0x00,0x46,0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,0x01,0x00,0x80,0x21, +0x00,0x04,0x15,0x02,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,0x00,0xe6,0x80,0x0a, +0x00,0x04,0x14,0x02,0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,0x02,0x40,0x20,0x21, +0x02,0x71,0x10,0x21,0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,0x02,0x92,0x10,0x21, +0x93,0x82,0x94,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0xe0, +0x02,0x92,0x28,0x21,0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,0x02,0x40,0xf0,0x21, +0x26,0xb5,0xff,0xff,0x16,0xa0,0xff,0xb7,0x02,0xc0,0x90,0x21,0x16,0xe0,0x00,0xd0, +0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x10, +0x10,0x40,0x00,0x2e,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,0x00,0x00,0x00,0x00, +0x18,0x80,0x00,0x2a,0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,0x27,0x84,0x99,0x44, +0x94,0xb2,0x00,0x14,0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,0x00,0x12,0x10,0xc0, +0x00,0x52,0x10,0x21,0x00,0x02,0x80,0x80,0x27,0x82,0x99,0x50,0x02,0x02,0x10,0x21, +0x80,0x43,0x00,0x06,0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,0x24,0x63,0x00,0x02, +0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40, +0x14,0xc0,0x00,0x0e,0x00,0xa3,0x38,0x21,0x27,0x82,0x99,0x40,0x02,0x02,0x10,0x21, +0x94,0x43,0x00,0x06,0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,0xa5,0x03,0x00,0x1a, +0x7b,0xbe,0x04,0x3c,0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,0x7b,0xb2,0x03,0x7c, +0x7b,0xb0,0x03,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,0x8f,0xa4,0x00,0x98, +0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x10,0x97, +0xaf,0xa0,0x00,0x14,0x08,0x00,0x24,0xae,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x44, +0x93,0x82,0x87,0x6d,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,0x30,0x69,0x00,0x03, +0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x85,0x10,0x2a, +0x10,0x40,0x00,0x8f,0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,0x00,0x00,0x00,0x00, +0x90,0xc4,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x00,0xa3,0x10,0x2a, +0x10,0x40,0x00,0x87,0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,0x00,0x00,0x00,0x00, +0x11,0x00,0x00,0x83,0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,0x00,0x62,0x10,0x2a, +0x14,0x40,0x00,0x7d,0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,0x30,0x42,0x00,0xff, +0xaf,0xa2,0x00,0x50,0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x73, +0x00,0x00,0xa8,0x21,0x27,0x8c,0x99,0x40,0x3c,0x0b,0x80,0xff,0x24,0x10,0x00,0x04, +0x27,0x91,0x99,0x44,0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,0x27,0x8e,0x99,0x50, +0x01,0x80,0x78,0x21,0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x4c,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,0x8f,0xa4,0x00,0x30, +0xaf,0xa2,0x00,0x44,0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,0x02,0x09,0x10,0x23, +0x30,0x42,0x00,0x03,0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,0x24,0x42,0x00,0x04, +0x30,0x42,0xff,0xff,0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,0x00,0x62,0x18,0x21, +0x00,0x48,0x10,0x2b,0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,0x30,0xe7,0xff,0xff, +0x30,0xa4,0xff,0xff,0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x51,0x18,0x21,0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x80,0x00,0x8d,0x20,0x24, +0x8c,0xa8,0x00,0x04,0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,0x01,0x0b,0x40,0x24, +0x01,0x04,0x40,0x25,0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,0x8f,0xa2,0x00,0x50, +0x26,0xb5,0x00,0x01,0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,0x00,0x00,0x00,0x00, +0x04,0x81,0x00,0x0c,0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x00,0x02,0x10,0x40,0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,0x00,0x00,0x00,0x00, +0xa4,0xe5,0x00,0x00,0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,0x00,0x12,0x30,0xc0, +0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,0x8f,0xa3,0x00,0x2c, +0x00,0x85,0x80,0x21,0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03, +0x8f,0xa8,0x00,0x88,0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,0x85,0x03,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x99,0x44,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0xff,0x74, +0x02,0x00,0x10,0x21,0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,0x8f,0xa5,0x00,0x24, +0x00,0x64,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x99,0x58,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x00,0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,0x08,0x00,0x24,0xb4, +0x02,0x00,0x10,0x21,0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,0x00,0x00,0x38,0x21, +0x0c,0x00,0x29,0x0b,0xaf,0xa2,0x00,0x10,0x08,0x00,0x24,0xb4,0x02,0x00,0x10,0x21, +0x30,0x63,0xff,0xff,0x08,0x00,0x25,0x06,0xaf,0xa3,0x00,0x2c,0x8f,0xa8,0x00,0x44, +0x08,0x00,0x25,0x28,0x31,0x09,0x00,0x03,0x08,0x00,0x24,0xe1,0xaf,0xa3,0x00,0x50, +0x8f,0xa6,0x00,0x44,0xaf,0xa0,0x00,0x50,0x08,0x00,0x25,0x28,0x30,0xc9,0x00,0x03, +0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x03,0xc0,0x38,0x21, +0x0c,0x00,0x23,0x53,0xaf,0xb7,0x00,0x10,0x08,0x00,0x24,0x91,0x00,0x00,0x00,0x00, +0x00,0x05,0x28,0x80,0x27,0x82,0x99,0x40,0x00,0xa2,0x28,0x21,0x00,0x00,0x20,0x21, +0x0c,0x00,0x01,0x49,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x8a,0x26,0xe2,0x00,0x01, +0x00,0x02,0x80,0x80,0x27,0x83,0x99,0x50,0x8f,0xa4,0x00,0x1c,0x02,0x03,0x18,0x21, +0x26,0x31,0x00,0x01,0x02,0x40,0x28,0x21,0x0c,0x00,0x26,0x5b,0xa0,0x71,0x00,0x05, +0x14,0x40,0xff,0x13,0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,0x03,0xc0,0x38,0x21, +0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,0x24,0x84,0x00,0x01, +0xaf,0xb2,0x00,0x48,0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,0x10,0xa2,0x00,0x41, +0xaf,0xa4,0x00,0x24,0x27,0x82,0x99,0x40,0x02,0x02,0x10,0x21,0x94,0x42,0x00,0x06, +0x8f,0xa4,0x00,0x30,0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,0x30,0x49,0x00,0x03, +0x8f,0xa8,0x00,0x44,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x01,0x02,0x10,0x21, +0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,0x10,0x60,0x00,0x2b, +0x00,0x00,0x00,0x00,0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,0x00,0xa4,0x18,0x21, +0x30,0x63,0xff,0xff,0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,0x02,0x92,0x28,0x21, +0x00,0x05,0x28,0x80,0x27,0x82,0x99,0x44,0x00,0xa2,0x10,0x21,0x8c,0x46,0x00,0x18, +0x3c,0x03,0x80,0xff,0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,0x00,0x04,0x25,0x80, +0x34,0x63,0xff,0xff,0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,0x01,0x04,0x40,0x25, +0xac,0xc8,0x00,0x04,0x8f,0xa8,0x00,0x98,0x27,0x82,0x99,0x50,0x00,0xa2,0x10,0x21, +0xa0,0x48,0x00,0x00,0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x27,0xc2, +0x10,0x80,0xfe,0xdb,0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x00,0x02,0x10,0x40,0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,0x00,0x00,0x00,0x00, +0xa4,0xe2,0x00,0x00,0x08,0x00,0x24,0x8d,0x26,0xb5,0xff,0xff,0x8f,0xa6,0x00,0x2c, +0x00,0x00,0x20,0x21,0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,0x08,0x00,0x25,0x9b, +0xaf,0xa2,0x00,0x2c,0x8f,0xa6,0x00,0x1c,0x08,0x00,0x25,0x85,0xa4,0xd2,0x00,0x14, +0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x0c,0x00,0x23,0x53, +0xaf,0xb7,0x00,0x10,0x08,0x00,0x25,0x7c,0x00,0x00,0xb8,0x21,0x0c,0x00,0x1a,0x11, +0x00,0x00,0x28,0x21,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x63,0x08,0x00, +0xa4,0x43,0x00,0x00,0x08,0x00,0x24,0x81,0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21, +0x00,0x03,0x80,0x80,0x27,0x82,0x99,0x44,0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10, +0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,0x93,0x82,0x94,0x51,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa3,0x3c,0x04,0x00,0x80,0x27,0x85,0x99,0x40, +0x08,0x00,0x25,0x6c,0x02,0x05,0x28,0x21,0x27,0x83,0x99,0x58,0x27,0x82,0x99,0x50, +0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05, +0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,0x0c,0x00,0x29,0x0b,0xaf,0xa3,0x00,0x10, +0x08,0x00,0x25,0xe2,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x8f,0xa4,0x00,0x94,0x08,0x00,0x24,0x59,0x00,0x64,0x10,0x06,0x08,0x00,0x24,0x5a, +0x00,0x00,0x18,0x21,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0xaf,0xa0,0x00,0x10, +0x0c,0x00,0x10,0x97,0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,0x08,0x00,0x24,0x24, +0xaf,0xa2,0x00,0x40,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe0, +0x34,0x42,0x00,0x20,0x24,0x63,0x98,0x14,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,0x00,0x80,0x80,0x21, +0x14,0x40,0x00,0x45,0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x3c,0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,0x00,0x00,0x00,0x00, +0x92,0x02,0x00,0x16,0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,0x10,0xa0,0x00,0x03, +0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x92,0x04,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00, +0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16, +0x10,0x60,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,0x00,0x00,0x00,0x00, +0x96,0x02,0x00,0x00,0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x14,0x80,0x00,0x05, +0x24,0x02,0x00,0x01,0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,0x08,0x00,0x26,0x2f, +0xa6,0x03,0x00,0x14,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x99,0x40, +0x00,0x04,0x10,0xc0,0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21, +0x00,0x02,0x10,0x80,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x46,0x10,0x21, +0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x0c,0x00,0x1a,0x02,0x00,0x00,0x00,0x00, +0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,0x96,0x02,0x00,0x06, +0x08,0x00,0x26,0x2f,0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,0x08,0x00,0x26,0x2f, +0xa6,0x02,0x00,0x14,0x96,0x05,0x00,0x00,0x0c,0x00,0x26,0x5b,0x02,0x00,0x20,0x21, +0x08,0x00,0x26,0x16,0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,0x0c,0x00,0x26,0x5b, +0x00,0x00,0x00,0x00,0x08,0x00,0x26,0x12,0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x99,0x6c,0x27,0xbd,0xff,0xf0, +0xac,0x62,0x00,0x00,0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x99,0x90, +0xac,0x62,0x00,0x00,0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,0x11,0x20,0x00,0x05, +0x00,0xa0,0x50,0x21,0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b, +0x00,0x00,0x00,0x00,0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0xe0,0x00,0x1b, +0x00,0x00,0x00,0x00,0x94,0xc8,0x00,0x00,0x27,0x83,0x99,0x40,0x93,0x85,0x94,0x50, +0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x08,0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,0x01,0x44,0x18,0x23, +0x8f,0x82,0x94,0x68,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x05, +0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x06, +0x24,0x03,0x00,0x08,0x08,0x00,0x26,0x87,0xa4,0xc2,0x00,0x14,0x08,0x00,0x26,0x87, +0x00,0x00,0x18,0x21,0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, +0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,0xaf,0xb2,0x00,0x20, +0xaf,0xb1,0x00,0x1c,0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,0x3c,0x02,0x80,0x01, +0x3c,0x04,0xb0,0x03,0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,0x24,0x42,0x9a,0x44, +0x02,0xb1,0x48,0x21,0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,0x24,0x03,0x00,0x01, +0x27,0x82,0x99,0x50,0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,0x27,0x84,0x99,0x44, +0x01,0x24,0x20,0x21,0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,0x27,0x83,0x99,0x60, +0x01,0x23,0x48,0x21,0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,0x8d,0x42,0x00,0x00, +0x8d,0x49,0x00,0x04,0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,0x01,0x02,0x40,0x21, +0x00,0x04,0x25,0xc2,0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x1f,0xc2, +0x00,0x08,0x40,0x40,0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,0x00,0x09,0x49,0x42, +0x01,0x48,0x10,0x21,0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,0x00,0x40,0x38,0x21, +0x02,0x00,0x28,0x21,0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,0x94,0x42,0x00,0x00, +0x02,0xb1,0x88,0x21,0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,0x27,0x90,0x99,0x40, +0x02,0x30,0x80,0x21,0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,0x02,0x60,0x20,0x21, +0x00,0x60,0x30,0x21,0xa6,0x83,0x00,0x1a,0x27,0x82,0x99,0x48,0x0c,0x00,0x10,0x70, +0x02,0x22,0x88,0x21,0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,0xa6,0x22,0x00,0x04, +0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xaf,0xa9,0x00,0x10, +0x0c,0x00,0x10,0x97,0xaf,0xa0,0x00,0x14,0x08,0x00,0x26,0xc5,0x02,0xb1,0x88,0x21, +0x27,0xbd,0xff,0xc0,0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30, +0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x3c, +0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,0x94,0x90,0x00,0x00, +0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,0x00,0x50,0x18,0x21, +0x00,0x40,0x88,0x21,0x3c,0x02,0x80,0x01,0x00,0x03,0x48,0x80,0x24,0x42,0x9b,0x80, +0x00,0x80,0x98,0x21,0x27,0x84,0x99,0x50,0x01,0x24,0x20,0x21,0x93,0xb7,0x00,0x53, +0xad,0x02,0x00,0x00,0x80,0x83,0x00,0x06,0x27,0x82,0x99,0x44,0x01,0x22,0x10,0x21, +0x8c,0x44,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x8c,0x88,0x00,0x08, +0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0xaf,0xa7,0x00,0x4c, +0x2c,0xa2,0x00,0x10,0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,0x00,0x08,0x47,0xc2, +0x00,0xc0,0x58,0x21,0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,0x14,0x40,0x00,0x13, +0x00,0x00,0xf0,0x21,0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,0x12,0x87,0x00,0x10, +0x02,0x30,0x10,0x21,0x27,0x83,0x99,0x58,0x01,0x23,0x18,0x21,0x80,0x64,0x00,0x00, +0x27,0x83,0xbe,0xb0,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80, +0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04, +0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,0x02,0x30,0x10,0x21, +0x00,0x02,0x80,0x80,0x24,0x04,0x00,0x01,0x27,0x83,0x99,0x60,0xa2,0x64,0x00,0x12, +0x02,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2, +0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,0x02,0xa0,0x20,0x21, +0x27,0x82,0x99,0x40,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x00,0x00,0x00,0x00, +0xa6,0x63,0x00,0x1a,0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc, +0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x40,0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,0x01,0x40,0x38,0x21, +0xaf,0xa0,0x00,0x10,0x0c,0x00,0x10,0x97,0xaf,0xa0,0x00,0x14,0x08,0x00,0x27,0x2c, +0x00,0x00,0x00,0x00,0x27,0x83,0x99,0x60,0x01,0x23,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24, +0x14,0x40,0x00,0xaf,0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,0x00,0x12,0x10,0x82, +0x25,0xe3,0x00,0x0d,0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,0x10,0xa0,0x00,0x0e, +0x00,0x00,0x90,0x21,0x27,0x82,0x86,0x30,0x00,0x15,0x18,0x40,0x00,0x62,0x18,0x21, +0x94,0x64,0x00,0x00,0x24,0xa2,0x00,0x05,0x00,0x54,0x10,0x04,0x00,0x44,0x00,0x1a, +0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12, +0x24,0x42,0x00,0x10,0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,0x27,0x83,0x99,0x50, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,0x00,0x00,0x00,0x00, +0x30,0x83,0x00,0xff,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,0x2c,0x62,0x00,0x19, +0x30,0x82,0x00,0x0f,0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,0x10,0x40,0x00,0x19, +0x24,0x0e,0x00,0x20,0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x15, +0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x11, +0x24,0x0e,0x00,0x08,0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,0x24,0x0e,0x00,0x02, +0x24,0x62,0xff,0xef,0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x24,0x0e,0x00,0x10, +0x24,0x62,0xff,0xf1,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,0x24,0x0e,0x00,0x08, +0x24,0x62,0xff,0xf3,0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,0x24,0x03,0x00,0x02, +0x00,0x62,0x70,0x0a,0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,0x00,0x00,0x68,0x21, +0x10,0x40,0x00,0x6d,0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,0x27,0x99,0x99,0x40, +0x01,0xf2,0xc0,0x23,0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,0x14,0x40,0x00,0x64, +0x24,0x03,0x00,0x04,0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x59,0x10,0x21,0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,0x32,0xcc,0x00,0x03, +0x00,0x6c,0x10,0x23,0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,0x24,0x42,0x00,0x04, +0x30,0x51,0xff,0xff,0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,0x01,0xf1,0x10,0x23, +0x02,0x51,0x10,0x23,0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,0x30,0x44,0xff,0xff, +0x29,0x22,0x00,0x40,0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,0x25,0x22,0x00,0x01, +0x00,0x02,0x16,0x00,0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,0x00,0x02,0x30,0x80, +0x27,0x82,0x99,0x44,0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,0x8c,0x67,0x00,0x18, +0x00,0x04,0x25,0x80,0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,0x00,0x83,0x20,0x24, +0x27,0x83,0x99,0x50,0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,0x00,0x44,0x10,0x25, +0xac,0xe2,0x00,0x04,0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,0xa0,0xb5,0x00,0x03, +0x27,0x84,0x99,0x60,0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,0x8c,0xe8,0x00,0x08, +0x00,0x02,0x15,0xc2,0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24, +0x10,0x40,0x00,0x0a,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x00,0x02,0x10,0x40,0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,0x92,0x62,0x00,0x04, +0x25,0xad,0x00,0x01,0x27,0x84,0x99,0x40,0x00,0xc4,0x18,0x21,0x01,0xa2,0x10,0x2a, +0x94,0x70,0x00,0x02,0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,0x96,0x63,0x00,0x14, +0x00,0x0c,0x10,0x23,0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,0x01,0x62,0x10,0x23, +0x00,0x03,0x80,0xc0,0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,0x02,0x03,0x80,0x21, +0x27,0x82,0x99,0x48,0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,0x02,0xa0,0x20,0x21, +0x01,0x60,0x30,0x21,0x01,0x60,0x88,0x21,0x0c,0x00,0x10,0x70,0x02,0x02,0x80,0x21, +0x00,0x5e,0x10,0x21,0xa6,0x02,0x00,0x04,0x08,0x00,0x27,0x32,0x02,0x20,0x10,0x21, +0x01,0x62,0x10,0x2b,0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,0x29,0x22,0x00,0x40, +0x10,0x40,0xff,0xe6,0x01,0x71,0x18,0x21,0x08,0x00,0x27,0xa8,0x25,0x22,0x00,0x01, +0x08,0x00,0x27,0xd7,0x32,0xcc,0x00,0x03,0x08,0x00,0x27,0xd7,0x00,0x00,0x60,0x21, +0x8f,0xa5,0x00,0x4c,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x10,0x97, +0xaf,0xb4,0x00,0x14,0x92,0x67,0x00,0x04,0x08,0x00,0x27,0x4a,0x30,0x5e,0xff,0xff, +0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,0x00,0x04,0x20,0x80, +0x27,0x82,0x99,0x40,0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,0x00,0x82,0x20,0x21, +0x00,0xc3,0x30,0x21,0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,0xa4,0x85,0x00,0x00, +0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,0x27,0x88,0x99,0x40, +0x00,0x06,0x30,0x80,0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,0x3c,0x02,0xb0,0x08, +0x3c,0x07,0xb0,0x03,0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x82,0x20,0x21,0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,0x00,0x68,0x18,0x21, +0x34,0xe7,0x00,0x20,0x24,0x42,0xa0,0x30,0xac,0xe2,0x00,0x00,0xa4,0xc5,0x00,0x02, +0xa4,0x65,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,0x30,0x84,0xff,0xff, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x27,0x89,0x99,0x40,0x00,0x02,0x10,0x80, +0x00,0x49,0x10,0x21,0x97,0x83,0x99,0x30,0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08, +0x00,0x03,0x38,0xc0,0x00,0x0a,0x40,0xc0,0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21, +0x00,0xe2,0x38,0x21,0x01,0x02,0x40,0x21,0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80, +0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x01,0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21, +0x34,0xc6,0x00,0x20,0x34,0x09,0xff,0xff,0x24,0x42,0xa0,0x8c,0xac,0xc2,0x00,0x00, +0xa4,0x64,0x00,0x00,0xac,0xe4,0x00,0x00,0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00, +0xa7,0x8a,0x99,0x30,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0xa1,0x0c,0x3c,0x04,0xb0,0x03, +0xac,0x62,0x00,0x00,0x34,0x84,0x01,0x10,0x8c,0x82,0x00,0x00,0x97,0x83,0x87,0x74, +0x30,0x42,0xff,0xff,0x10,0x62,0x00,0x16,0x24,0x0a,0x00,0x01,0xa7,0x82,0x87,0x74, +0xaf,0x80,0xbd,0x90,0x00,0x40,0x28,0x21,0x24,0x06,0x00,0x01,0x27,0x84,0xbd,0x94, +0x25,0x43,0xff,0xff,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07, +0x00,0x00,0x00,0x00,0x8c,0x83,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04, +0x00,0xa2,0x10,0x24,0x38,0x42,0x00,0x00,0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01, +0x2d,0x42,0x00,0x14,0xac,0x83,0x00,0x00,0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04, +0x3c,0x0b,0xb0,0x03,0x00,0x00,0x50,0x21,0x3c,0x0c,0x80,0x00,0x27,0x89,0xbd,0xe0, +0x35,0x6b,0x01,0x20,0x8d,0x68,0x00,0x00,0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24, +0x00,0x02,0x17,0xc2,0x11,0x03,0x00,0x37,0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5, +0xa1,0x20,0x00,0xd6,0x01,0x20,0x30,0x21,0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21, +0x01,0x20,0x20,0x21,0x00,0xa8,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10, +0xa0,0x82,0x00,0x0a,0x90,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31, +0x24,0xa2,0xff,0xff,0xa0,0x82,0x00,0x08,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0x40,0x00,0x43,0x10,0x21,0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09, +0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00, +0x14,0xe0,0x00,0x04,0x00,0x00,0x00,0x00,0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01, +0xa0,0x85,0x00,0x08,0xa0,0xc5,0x00,0xd6,0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c, +0x14,0x40,0xff,0xe0,0x24,0x84,0x00,0x03,0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21, +0x00,0xa4,0x10,0x2b,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21, +0xa0,0x64,0x00,0x08,0x90,0xc2,0x00,0xd5,0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09, +0x90,0xc4,0x00,0xd5,0x00,0x00,0x00,0x00,0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8, +0x24,0x63,0x00,0x03,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04, +0x25,0x6b,0x00,0x04,0x14,0x40,0xff,0xbf,0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x05,0x08,0x00,0x28,0x7e,0xa0,0x82,0x00,0x08, +0x97,0x85,0x94,0x5a,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x63,0x00,0x20,0x24,0x42,0xa2,0xc0,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x62,0x00,0x00,0x30,0x90,0x00,0xff,0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21, +0x27,0x8f,0xbd,0xe4,0x00,0x00,0x50,0x21,0x00,0x00,0x58,0x21,0x27,0x98,0xbe,0xc4, +0x27,0x99,0xbe,0xc0,0x27,0x8e,0xbe,0xbe,0x27,0x8c,0xbd,0xe8,0x27,0x8d,0xbe,0x40, +0x27,0x88,0xbe,0xb8,0x00,0x0a,0x18,0x80,0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00, +0xac,0x45,0x00,0x58,0x00,0x6e,0x20,0x21,0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc, +0xad,0x00,0x00,0x00,0xa1,0x00,0x00,0x04,0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8, +0x00,0x79,0x18,0x21,0x24,0x06,0x00,0x01,0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00, +0xa4,0x60,0x00,0x00,0xac,0x40,0x00,0x00,0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04, +0x04,0xc1,0xff,0xf9,0x24,0x84,0x00,0x01,0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21, +0x00,0x00,0x30,0x21,0x00,0x4c,0x18,0x21,0x27,0x87,0x87,0x78,0x8c,0xe2,0x00,0x00, +0x24,0xe7,0x00,0x04,0xac,0x82,0x00,0x00,0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01, +0x24,0xc6,0x00,0x01,0x28,0xc2,0x00,0x1c,0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04, +0x14,0x40,0xff,0xf6,0x24,0x63,0x00,0x03,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08, +0x25,0x4a,0x00,0x3b,0x25,0x08,0x00,0xec,0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec, +0xa7,0x80,0x87,0x74,0x00,0x00,0x48,0x21,0x27,0x83,0xbd,0x90,0xac,0x69,0x00,0x00, +0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x0c,0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04, +0x0c,0x00,0x28,0x43,0x00,0x00,0x00,0x00,0x2e,0x04,0x00,0x14,0x27,0x83,0xbd,0xe0, +0x24,0x09,0x00,0x07,0x10,0x80,0x00,0x0a,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5, +0x25,0x29,0xff,0xff,0xa0,0x62,0x00,0x00,0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec, +0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x90,0x62,0x00,0xd6,0x08,0x00,0x29,0x01,0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff, +0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x27,0x83,0xbd,0xe0,0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0x84,0x00,0x20,0x24,0x42,0xa4,0x2c,0x30,0xc6,0x00,0xff, +0x93,0xaa,0x00,0x13,0x30,0xa5,0x00,0xff,0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00, +0x10,0xc0,0x00,0xb8,0x25,0x8f,0x00,0xd0,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x24,0x42,0xff,0xfc,0x2c,0x43,0x00,0x18,0x10,0x60,0x00,0x9b,0x3c,0x03,0x80,0x01, +0x00,0x02,0x10,0x80,0x24,0x63,0x09,0x3c,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c, +0x14,0x40,0x00,0x1c,0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x17,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x11,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x06, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0, +0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c, +0x24,0x42,0xff,0xe8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x29,0x3c,0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c, +0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xec,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe9, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c,0x24,0x42,0xff,0xd0, +0x10,0xa0,0xff,0xf1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xeb, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe6,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0xe1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c, +0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x24,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xe1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xdb, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c, +0x24,0x42,0xff,0xf0,0x10,0xa0,0xff,0xd1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xcc,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xf7,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xd7,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x39, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x24,0x10,0x40,0xff,0xe5,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xc2,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x14,0xa2,0xff,0xca, +0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x5e,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x29, +0x10,0x40,0xff,0xdb,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x49,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x24,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xb6, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xb0,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xab,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xc6, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c,0x24,0x42,0xff,0xfa, +0x10,0xa0,0xff,0xa9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xa1, +0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0x94,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x5e, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x24,0x10,0x40,0xff,0xe8,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x9a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x95, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x90,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x51, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c,0x14,0x40,0xff,0xcd,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x91,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8b, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x86,0x00,0x00,0x00,0x00, +0x08,0x00,0x29,0x5e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x87,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x81,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x7c,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x97,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x29,0x3c,0x24,0x42,0xff,0xfc,0x2d,0x42,0x00,0x24, +0x14,0x40,0xff,0xa4,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x54,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x24,0x14,0x40,0xff,0x9f,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0x2e, +0x00,0x00,0x00,0x00,0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,0x25,0x8d,0x00,0x5c, +0x30,0xc4,0x00,0xff,0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,0x00,0x04,0x48,0x80, +0x01,0x82,0x58,0x21,0x01,0x89,0x40,0x21,0x25,0x78,0x00,0x08,0x10,0x60,0x00,0x36, +0x25,0x0e,0x00,0x60,0x10,0xa0,0x00,0x25,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,0x00,0x00,0x00,0x00,0x27,0x87,0x87,0x78, +0x01,0x27,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60, +0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00, +0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00, +0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,0x00,0x03,0x1a,0x80,0x00,0xa3,0x10,0x2b, +0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4, +0x27,0x87,0x87,0x78,0x08,0x00,0x29,0xf0,0xa1,0x80,0x00,0xdd,0x27,0x82,0x87,0xe8, +0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01, +0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x33,0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60, +0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,0x10,0xe0,0x00,0x1d,0x24,0x83,0xff,0xfc, +0x2c,0x62,0x00,0x18,0x10,0x40,0x00,0xe4,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01, +0x24,0x63,0x09,0x9c,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c,0x14,0x40,0x00,0x65, +0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x5a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0xad,0x82,0x00,0xd0, +0x8d,0xe3,0x00,0x00,0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xad,0xa2,0x00,0x00,0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00, +0x93,0x05,0x00,0x01,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05, +0x24,0x02,0x00,0x01,0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08, +0xad,0x80,0x00,0xd8,0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05, +0x00,0x00,0x00,0x00,0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08, +0xa1,0x83,0x00,0xdd,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43, +0xad,0xa2,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x87,0x78,0x8d,0xc5,0x00,0x00, +0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40, +0x00,0x04,0x1a,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x2a,0x02, +0xad,0xc5,0x00,0x00,0x97,0x82,0x94,0x5c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a, +0x10,0x40,0xfe,0xdc,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x15,0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x87,0x78, +0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21, +0xac,0x64,0x00,0x60,0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80, +0x01,0x82,0x10,0x21,0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0xa2,0x00,0x00,0x08,0x00,0x2a,0x77,0xa1,0x80,0x00,0xdd, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x2a,0x33,0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33, +0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xa3,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa0, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33,0x24,0x42,0xff,0xd0, +0x10,0xa0,0xff,0xf1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xeb, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x99,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0xe3,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33, +0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x24,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xe1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xdb, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x89,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33, +0x24,0x42,0xff,0xf0,0x10,0xa0,0xff,0xd1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x7f,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xf7,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xd7,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x30, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x24,0x10,0x40,0xff,0xe5,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xc2,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x14,0xa2,0xff,0xca, +0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x9e,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x29, +0x10,0x40,0xff,0xdb,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x89,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x24,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xb6, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xb0,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x5e,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xc6, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33,0x24,0x42,0xff,0xfa, +0x10,0xa0,0xff,0xa9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x54, +0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0x4b,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x9e, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x24,0x10,0x40,0xff,0xe8,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x9a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x48, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x92,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x91, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c,0x14,0x40,0xff,0xcd,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x91,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8b, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x39,0x00,0x00,0x00,0x00, +0x08,0x00,0x2a,0x9e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x87,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x81,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x2f,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x97,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x2a,0x33,0x24,0x42,0xff,0xfc,0x2d,0x42,0x00,0x24, +0x14,0x40,0xff,0xa4,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x94,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x24,0x14,0x40,0xff,0x9f,0x00,0x00,0x00,0x00,0x08,0x00,0x2a,0x25, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,0xaf,0xbf,0x00,0x14, +0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,0x8c,0x50,0x00,0x00, +0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,0xa3,0x82,0x80,0x10, +0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,0x14,0x40,0x00,0x09, +0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x01, +0xa3,0x82,0xc5,0x58,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x0b,0x3e,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0x00, +0xa3,0x80,0xc5,0x58,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x2b,0x26, +0x32,0x02,0x08,0x00,0x0c,0x00,0x28,0xb0,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0xff, +0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x2b,0x23,0x32,0x02,0x01,0x00, +0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xaf,0xbf,0x00,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,0x00,0x03,0x33,0x02, +0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,0x00,0x62,0x18,0x24, +0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,0x31,0x08,0x00,0xff, +0x01,0x00,0x30,0x21,0x0c,0x00,0x2b,0xe7,0xaf,0xa9,0x00,0x10,0x8f,0xbf,0x00,0x18, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x2c,0x39, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,0x08,0x00,0x2b,0x4f, +0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb6,0x00,0x30,0xaf,0xb3,0x00,0x24, +0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38, +0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20, +0x0c,0x00,0x1f,0x11,0x00,0x80,0x80,0x21,0x00,0x00,0xb0,0x21,0x00,0x00,0x88,0x21, +0x10,0x40,0x00,0x12,0x00,0x00,0x98,0x21,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03, +0x3c,0x04,0xb0,0x03,0x24,0x05,0x00,0x01,0x34,0x42,0x00,0xbc,0x34,0x63,0x00,0xbb, +0x34,0x84,0x00,0xba,0xa4,0x40,0x00,0x00,0xa0,0x65,0x00,0x00,0xa0,0x85,0x00,0x00, +0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, +0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x47,0x90,0x44,0x00,0x00,0x00,0x10,0x1a,0x02,0x3c,0x15,0xfd,0xff, +0x30,0x84,0x00,0xff,0xa0,0x50,0x00,0x00,0x30,0x74,0x00,0x0f,0xaf,0xa4,0x00,0x10, +0x00,0x00,0x90,0x21,0x3c,0x17,0x02,0x00,0x36,0xb5,0xff,0xff,0x3c,0x1e,0xb0,0x03, +0x0c,0x00,0x0e,0x71,0x24,0x04,0x00,0x78,0x00,0x57,0x10,0x25,0x00,0x40,0x28,0x21, +0x0c,0x00,0x0e,0x64,0x24,0x04,0x00,0x78,0x00,0x00,0x80,0x21,0x0c,0x00,0x2d,0x0a, +0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x30,0x70,0x00,0xff,0x10,0x40,0x00,0x47, +0x2e,0x03,0x00,0x02,0x14,0x60,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x0e,0x71, +0x24,0x04,0x00,0x78,0x00,0x55,0x10,0x24,0x00,0x40,0x28,0x21,0x0c,0x00,0x0e,0x64, +0x24,0x04,0x00,0x78,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x38,0x24,0x04,0x00,0xe0, +0x12,0x80,0x00,0x36,0x24,0x04,0x00,0xe4,0x32,0x22,0x00,0x60,0x32,0x23,0x0c,0x00, +0x00,0x03,0x1a,0x02,0x3c,0x05,0x00,0x60,0x00,0x02,0x11,0x42,0x02,0x25,0x20,0x24, +0x00,0x43,0x10,0x25,0x3c,0x03,0x04,0x00,0x02,0x23,0x28,0x24,0x00,0x04,0x24,0x42, +0x00,0x44,0x10,0x25,0x00,0x05,0x2d,0x02,0x00,0x45,0x88,0x25,0x12,0x20,0x00,0x05, +0x26,0x42,0x00,0x01,0x26,0xc2,0x00,0x01,0x30,0x56,0x00,0xff,0x02,0x71,0x98,0x21, +0x26,0x42,0x00,0x01,0x02,0x5e,0x20,0x21,0x30,0x52,0x00,0xff,0x2e,0x43,0x00,0x05, +0xa0,0x91,0x00,0xd8,0x14,0x60,0xff,0xce,0x3c,0x02,0xb0,0x03,0x8f,0xa5,0x00,0x10, +0x34,0x42,0x01,0x47,0xa0,0x45,0x00,0x00,0x12,0x60,0x00,0x0e,0x3c,0x02,0xb0,0x03, +0x12,0xc0,0x00,0x0d,0x34,0x42,0x00,0xbc,0x00,0x13,0x10,0x40,0x00,0x53,0x10,0x21, +0x00,0x02,0x10,0xc0,0x00,0x53,0x10,0x21,0x00,0x02,0x98,0x80,0x02,0x76,0x00,0x1b, +0x16,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x98,0x12, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xbc,0x3c,0x03,0xb0,0x03,0x3c,0x04,0xb0,0x03, +0xa4,0x53,0x00,0x00,0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,0x24,0x02,0x00,0x01, +0xa0,0x60,0x00,0x00,0x08,0x00,0x2b,0x74,0xa0,0x82,0x00,0x00,0x0c,0x00,0x0e,0x71, +0x00,0x00,0x00,0x00,0x08,0x00,0x2b,0xa2,0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x00,0xbc,0x3c,0x04,0xb0,0x03,0x3c,0x05,0xb0,0x03,0xa4,0x60,0x00,0x00, +0x34,0x84,0x00,0xbb,0x34,0xa5,0x00,0xba,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x01, +0xa0,0x82,0x00,0x00,0x08,0x00,0x2b,0x74,0xa0,0xa3,0x00,0x00,0x27,0xbd,0xff,0xd8, +0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0x30,0xb1,0x00,0xff, +0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x1b,0x6e,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x38, +0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,0x3c,0x04,0xb0,0x09, +0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,0x90,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x2a, +0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x20, +0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,0x16,0x60,0xff,0xe2, +0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0d, +0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,0x16,0x22,0xff,0xda, +0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,0x0c,0x00,0x1b,0x29, +0x3c,0x06,0x0c,0xb8,0x08,0x00,0x2b,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x2c,0x1a, +0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x2c,0x1a, +0x24,0x04,0x08,0x40,0x08,0x00,0x2c,0x1a,0x24,0x04,0x08,0x44,0x24,0x04,0x08,0x4c, +0x0c,0x00,0x1b,0x29,0x24,0x05,0xff,0xff,0x08,0x00,0x2c,0x0f,0x00,0x00,0x00,0x00, +0x08,0x00,0x2c,0x28,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,0x00,0x00,0x00,0x00, +0x08,0x00,0x2c,0x28,0x24,0x04,0x08,0x40,0x08,0x00,0x2c,0x28,0x24,0x04,0x08,0x44, +0x02,0x40,0x20,0x21,0x0c,0x00,0x2c,0x75,0x02,0x20,0x28,0x21,0x08,0x00,0x2b,0xfd, +0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,0xaf,0xb3,0x00,0x1c, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb2,0x00,0x18, +0x00,0xc0,0x88,0x21,0x30,0xb0,0x00,0xff,0x00,0x80,0x98,0x21,0x14,0x40,0x00,0x07, +0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x32,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x1b,0x6e,0x24,0x06,0x01,0x07,0x12,0x40,0x00,0x1f, +0x02,0x20,0x10,0x21,0x30,0x45,0x00,0x3f,0x0c,0x00,0x2c,0xb2,0x02,0x00,0x20,0x21, +0x16,0x40,0x00,0x0a,0x00,0x40,0x88,0x21,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x15, +0x2a,0x02,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x0b, +0x24,0x02,0x00,0x03,0x12,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x2c,0x45, +0x02,0x20,0x18,0x21,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,0x0c,0x00,0x1b,0x29, +0x3c,0x06,0x0c,0xb8,0x08,0x00,0x2c,0x45,0x02,0x20,0x18,0x21,0x08,0x00,0x2c,0x62, +0x24,0x04,0x08,0x48,0x16,0x00,0xff,0xf5,0x00,0x00,0x00,0x00,0x08,0x00,0x2c,0x62, +0x24,0x04,0x08,0x40,0x08,0x00,0x2c,0x62,0x24,0x04,0x08,0x44,0x02,0x60,0x20,0x21, +0x02,0x20,0x30,0x21,0x0c,0x00,0x2c,0x75,0x02,0x00,0x28,0x21,0x08,0x00,0x2c,0x52, +0x30,0x45,0x00,0x3f,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,0x30,0xa5,0x00,0xff, +0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x12, +0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x07, +0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x05,0xff,0xff, +0x0c,0x00,0x1b,0x29,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x2c,0x86,0x26,0x10,0xff,0xe2, +0x08,0x00,0x2c,0x8b,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,0x24,0x04,0x08,0x40, +0x08,0x00,0x2c,0x8c,0x24,0x05,0xff,0xff,0x08,0x00,0x2c,0x8b,0x24,0x04,0x08,0x44, +0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x14, +0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0a, +0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,0x08,0x00,0x2c,0x86, +0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x1b,0x29,0x3c,0x06,0x0d,0xb8, +0x08,0x00,0x2c,0x86,0x26,0x10,0xff,0xf1,0x08,0x00,0x2c,0xa5,0x24,0x04,0x08,0x48, +0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x2c,0xa6,0x24,0x05,0xff,0xff, +0x08,0x00,0x2c,0xa5,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe0,0x00,0x80,0x10,0x21, +0x24,0x04,0x00,0x50,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0x00,0xa0,0x88,0x21,0x0c,0x00,0x01,0x31,0x30,0x50,0x00,0xff,0x24,0x03,0x00,0x01, +0x12,0x03,0x00,0x3e,0x02,0x20,0x30,0x21,0x2a,0x02,0x00,0x02,0x14,0x40,0x00,0x2a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x19,0x24,0x04,0x08,0x34, +0x24,0x02,0x00,0x03,0x12,0x02,0x00,0x05,0x24,0x04,0x08,0x3c,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x1b,0x29, +0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x1b,0x29, +0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01,0x0c,0x00,0x1b,0x29, +0x24,0x04,0x08,0x3c,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28,0x24,0x04,0x08,0xac, +0x0c,0x00,0x1b,0x0b,0x24,0x05,0x0f,0xff,0x08,0x00,0x2c,0xc7,0x00,0x00,0x00,0x00, +0x0c,0x00,0x1b,0x29,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x1b,0x29,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01, +0x0c,0x00,0x1b,0x29,0x24,0x04,0x08,0x34,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28, +0x08,0x00,0x2c,0xd8,0x24,0x04,0x08,0xa8,0x16,0x00,0xff,0xdc,0x02,0x20,0x30,0x21, +0x24,0x04,0x08,0x24,0x0c,0x00,0x1b,0x29,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24, +0x3c,0x05,0x80,0x00,0x0c,0x00,0x1b,0x29,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00, +0x24,0x06,0x00,0x01,0x0c,0x00,0x1b,0x29,0x24,0x04,0x08,0x24,0x0c,0x00,0x01,0x31, +0x24,0x04,0x00,0x28,0x08,0x00,0x2c,0xd8,0x24,0x04,0x08,0xa0,0x24,0x04,0x08,0x2c, +0x0c,0x00,0x1b,0x29,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x1b,0x29,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01, +0x0c,0x00,0x1b,0x29,0x24,0x04,0x08,0x2c,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28, +0x08,0x00,0x2c,0xd8,0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05, +0x34,0x42,0x04,0x20,0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, +0x34,0xa5,0x17,0x09,0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24, +0x34,0x84,0x02,0x28,0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00, +0x34,0xe7,0x04,0x50,0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x03,0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x0c,0x00,0x2d,0xcf, +0x00,0x00,0x00,0x00,0x0c,0x00,0x2d,0xd1,0x00,0x00,0x00,0x00,0x0c,0x00,0x2d,0xf8, +0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x04,0x0c,0x00,0x2d,0xd8, +0x34,0x05,0x9c,0x40,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, +0x24,0x02,0x00,0x01,0x97,0x82,0x88,0x10,0x00,0x00,0x00,0x00,0x2c,0x43,0x00,0x64, +0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x10,0x14,0x60,0x00,0x28,0x00,0x80,0x30,0x21, +0x8c,0x82,0x00,0x00,0x3c,0x03,0x20,0x00,0xa7,0x80,0x88,0x10,0x00,0x43,0x10,0x24, +0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00, +0x00,0x43,0x10,0x25,0x97,0x83,0x88,0x04,0xac,0x82,0x00,0x00,0x8c,0x85,0x00,0x00, +0x24,0x63,0x00,0x01,0x3c,0x02,0x40,0x64,0x34,0x42,0x64,0x00,0x00,0x03,0x24,0x00, +0x00,0xa2,0x28,0x25,0x00,0x04,0x24,0x03,0x24,0x02,0x00,0x64,0xac,0xc5,0x00,0x00, +0xa7,0x83,0x88,0x04,0x10,0x82,0x00,0x2b,0x00,0x00,0x00,0x00,0x87,0x82,0x88,0x06, +0x24,0x03,0x00,0x3c,0x10,0x43,0x00,0x21,0x00,0x00,0x00,0x00,0x87,0x82,0x88,0x08, +0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x17,0x00,0x00,0x00,0x00,0x87,0x83,0x88,0x0a, +0x24,0x02,0x00,0x18,0x10,0x62,0x00,0x0d,0x00,0x00,0x00,0x00,0x87,0x83,0x88,0x0c, +0x24,0x02,0x01,0x6d,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x0e,0xa7,0x80,0x88,0x0c,0x24,0x42,0x00,0x01, +0xa7,0x82,0x88,0x0e,0x08,0x00,0x2d,0x67,0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x0c, +0xa7,0x80,0x88,0x0a,0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x0c,0x08,0x00,0x2d,0x63, +0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x0a,0xa7,0x80,0x88,0x08,0x24,0x42,0x00,0x01, +0xa7,0x82,0x88,0x0a,0x08,0x00,0x2d,0x5f,0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x08, +0xa7,0x80,0x88,0x06,0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x08,0x08,0x00,0x2d,0x5b, +0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x06,0xa7,0x80,0x88,0x04,0x24,0x42,0x00,0x01, +0xa7,0x82,0x88,0x06,0x08,0x00,0x2d,0x57,0x00,0x00,0x00,0x00,0x00,0x04,0x24,0x00, +0x3c,0x03,0xb0,0x07,0x00,0x04,0x24,0x03,0x34,0x63,0x00,0x28,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x40,0x10,0x40,0xff,0xfc,0x00,0x00,0x00,0x00, +0x3c,0x01,0xb0,0x07,0xa0,0x24,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21, +0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x28,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x63,0x00,0x01,0x10,0x60,0x00,0x06,0x24,0x02,0xff,0xff,0x3c,0x02,0xb0,0x07, +0x90,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb0,0x00,0x10, +0x3c,0x10,0x04,0xc4,0x00,0x04,0x11,0x00,0x36,0x10,0xb4,0x00,0x02,0x02,0x00,0x1b, +0xaf,0xb1,0x00,0x14,0x3c,0x11,0xb0,0x07,0x36,0x31,0x00,0x18,0x24,0x04,0x00,0x0a, +0xaf,0xbf,0x00,0x18,0x14,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, +0x00,0x00,0x80,0x12,0x0c,0x00,0x2e,0x24,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x00, +0x24,0x03,0xff,0x80,0x24,0x04,0x00,0x0a,0x00,0x43,0x10,0x25,0x0c,0x00,0x2e,0x24, +0xa2,0x22,0x00,0x00,0x24,0x04,0x00,0x0a,0x3c,0x01,0xb0,0x07,0xa0,0x30,0x00,0x00, +0x0c,0x00,0x2e,0x24,0x00,0x10,0x82,0x03,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08, +0xa0,0x50,0x00,0x00,0x0c,0x00,0x2e,0x24,0x24,0x04,0x00,0x0a,0x92,0x22,0x00,0x00, +0x8f,0xbf,0x00,0x18,0x8f,0xb0,0x00,0x10,0x30,0x42,0x00,0x7f,0xa2,0x22,0x00,0x00, +0x8f,0xb1,0x00,0x14,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x58,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x34,0x42,0x07,0xa4,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00, +0x27,0xbd,0xff,0xf8,0x00,0x80,0x38,0x21,0x00,0xa0,0x30,0x21,0x00,0x00,0x18,0x21, +0x00,0x63,0x00,0x18,0x00,0x00,0x10,0x12,0x00,0xc2,0x10,0x2b,0x14,0x40,0x00,0x05, +0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x01,0x00,0x14,0x40,0xff,0xf9, +0x00,0x63,0x00,0x18,0x24,0x63,0xff,0xff,0x00,0x63,0x00,0x18,0x30,0x63,0x00,0xff, +0x8c,0xe4,0x00,0x00,0x00,0x03,0x2a,0x00,0x00,0x03,0x1c,0x00,0x00,0x00,0x10,0x12, +0x00,0xc2,0x10,0x23,0x30,0x42,0x00,0xff,0x00,0x45,0x10,0x21,0x00,0x43,0x10,0x21, +0x00,0x82,0x20,0x25,0xac,0xe4,0x00,0x00,0x8c,0xe2,0x00,0x00,0x3c,0x03,0x40,0x00, +0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08, +0x27,0xbd,0xff,0xe0,0xaf,0xbf,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0x3c,0x06,0xb0,0x03,0x34,0xc6,0x00,0x08, +0x34,0x42,0x40,0x00,0xac,0x82,0x00,0x00,0x8c,0x83,0x00,0x00,0x24,0x02,0xcf,0xff, +0x3c,0x11,0xb0,0x07,0x00,0x62,0x18,0x24,0xac,0x83,0x00,0x00,0x8c,0xc5,0x00,0x00, +0x3c,0x02,0x00,0xff,0x24,0x04,0x00,0x0a,0x00,0xa2,0x28,0x25,0xac,0xc5,0x00,0x00, +0x0c,0x00,0x2e,0x24,0x36,0x31,0x00,0x18,0x24,0x02,0xff,0x83,0x3c,0x04,0x00,0x01, +0xa2,0x22,0x00,0x00,0x0c,0x00,0x2d,0xa2,0x34,0x84,0xc2,0x00,0x0c,0x00,0x2e,0x24, +0x24,0x04,0x00,0x0a,0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x00,0x24,0x04,0x00,0x0a, +0x0c,0x00,0x2e,0x24,0x3c,0x10,0xb0,0x07,0x36,0x10,0x00,0x10,0x24,0x02,0x00,0x06, +0xa2,0x02,0x00,0x00,0x0c,0x00,0x2e,0x24,0x24,0x04,0x00,0x0a,0xa2,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x00,0x64,0x10,0x2b, +0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x27,0xbd,0xff,0xc0,0xaf,0xb5,0x00,0x34,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20, +0xaf,0xbf,0x00,0x38,0xaf,0xb4,0x00,0x30,0xaf,0xb3,0x00,0x2c,0xaf,0xb1,0x00,0x24, +0xaf,0xa5,0x00,0x44,0x90,0xa7,0x00,0x00,0x00,0x80,0xa8,0x21,0x00,0xc0,0x90,0x21, +0x00,0x07,0x1e,0x00,0x10,0x60,0x00,0x0f,0x00,0x80,0x80,0x21,0x00,0x03,0x1e,0x03, +0x24,0x02,0x00,0x25,0x10,0x62,0x00,0x13,0x00,0x00,0x88,0x21,0xa2,0x07,0x00,0x00, +0x8f,0xa5,0x00,0x44,0x26,0x10,0x00,0x01,0x24,0xa5,0x00,0x01,0xaf,0xa5,0x00,0x44, +0x90,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1e,0x00,0x14,0x60,0xff,0xf3, +0x00,0x00,0x00,0x00,0x02,0x15,0x10,0x23,0xa2,0x00,0x00,0x00,0x8f,0xbf,0x00,0x38, +0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x40,0x24,0xa5,0x00,0x01,0xaf,0xa5,0x00,0x44,0x80,0xa3,0x00,0x00, +0x00,0x00,0x00,0x00,0x24,0x63,0xff,0xe0,0x2c,0x62,0x00,0x11,0x10,0x40,0x00,0x11, +0x00,0xa0,0x38,0x21,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x09,0xfc, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08, +0x00,0x00,0x00,0x00,0x08,0x00,0x2e,0x51,0x36,0x31,0x00,0x10,0x08,0x00,0x2e,0x51, +0x36,0x31,0x00,0x08,0x08,0x00,0x2e,0x51,0x36,0x31,0x00,0x20,0x08,0x00,0x2e,0x51, +0x36,0x31,0x00,0x04,0x90,0xe4,0x00,0x00,0x3c,0x02,0x80,0x01,0x24,0x42,0x02,0x1c, +0x00,0x44,0x10,0x21,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04, +0x14,0x60,0x00,0xfd,0x24,0x14,0xff,0xff,0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03, +0x24,0x03,0x00,0x2a,0x10,0x43,0x00,0xee,0x26,0x42,0x00,0x03,0x80,0xa3,0x00,0x00, +0x24,0x02,0x00,0x2e,0x10,0x62,0x00,0xcc,0x24,0x08,0xff,0xff,0x80,0xa3,0x00,0x00, +0x24,0x02,0x00,0x68,0x10,0x62,0x00,0xc4,0x24,0x06,0xff,0xff,0x24,0x02,0x00,0x6c, +0x10,0x62,0x00,0xc1,0x24,0x02,0x00,0x4c,0x10,0x62,0x00,0xbf,0x24,0x02,0x00,0x5a, +0x10,0x62,0x00,0xbd,0x00,0x00,0x00,0x00,0x80,0xa3,0x00,0x00,0x00,0x00,0x00,0x00, +0x24,0x63,0xff,0xdb,0x2c,0x62,0x00,0x54,0x10,0x40,0x00,0xaa,0x24,0x09,0x00,0x0a, +0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x0a,0x40,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00, +0x32,0x22,0x00,0x10,0x14,0x40,0x00,0x09,0x24,0x02,0xff,0xfc,0x26,0x94,0xff,0xff, +0x1a,0x80,0x00,0x05,0x24,0x02,0x00,0x20,0x26,0x94,0xff,0xff,0xa2,0x02,0x00,0x00, +0x1e,0x80,0xff,0xfd,0x26,0x10,0x00,0x01,0x24,0x02,0xff,0xfc,0x26,0x44,0x00,0x03, +0x00,0x82,0x90,0x24,0x92,0x42,0x00,0x03,0x26,0x94,0xff,0xff,0x26,0x52,0x00,0x04, +0xa2,0x02,0x00,0x00,0x1a,0x80,0x00,0x06,0x26,0x10,0x00,0x01,0x24,0x02,0x00,0x20, +0x26,0x94,0xff,0xff,0xa2,0x02,0x00,0x00,0x1e,0x80,0xff,0xfd,0x26,0x10,0x00,0x01, +0x8f,0xa5,0x00,0x44,0x08,0x00,0x2e,0x43,0x24,0xa5,0x00,0x01,0x24,0x02,0x00,0x25, +0x08,0x00,0x2e,0x40,0xa2,0x02,0x00,0x00,0x36,0x31,0x00,0x40,0x24,0x09,0x00,0x10, +0x24,0x02,0x00,0x4c,0x10,0xc2,0x00,0x2a,0x24,0x02,0x00,0x6c,0x10,0xc2,0x00,0x05, +0x24,0x02,0x00,0x5a,0x10,0xc2,0x00,0x1f,0x24,0x02,0x00,0x68,0x10,0xc2,0x00,0x13, +0x24,0x02,0xff,0xfc,0x24,0x02,0xff,0xfc,0x26,0x43,0x00,0x03,0x00,0x62,0x90,0x24, +0x32,0x22,0x00,0x02,0x8e,0x47,0x00,0x00,0x00,0x00,0x30,0x21,0x10,0x40,0x00,0x03, +0x26,0x52,0x00,0x04,0x00,0xe0,0x10,0x21,0x00,0x02,0x37,0xc3,0x02,0x00,0x20,0x21, +0xaf,0xa9,0x00,0x10,0xaf,0xb4,0x00,0x14,0xaf,0xa8,0x00,0x18,0x0c,0x00,0x2f,0x91, +0xaf,0xb1,0x00,0x1c,0x08,0x00,0x2e,0xac,0x00,0x40,0x80,0x21,0x26,0x43,0x00,0x03, +0x00,0x62,0x90,0x24,0x32,0x22,0x00,0x02,0x96,0x47,0x00,0x02,0x00,0x00,0x30,0x21, +0x10,0x40,0xff,0xf2,0x26,0x52,0x00,0x04,0x00,0x07,0x14,0x00,0x08,0x00,0x2e,0xc6, +0x00,0x02,0x3c,0x03,0x26,0x42,0x00,0x03,0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24, +0x8e,0x47,0x00,0x00,0x00,0x00,0x30,0x21,0x08,0x00,0x2e,0xc7,0x26,0x52,0x00,0x04, +0x26,0x42,0x00,0x07,0x24,0x03,0xff,0xf8,0x00,0x43,0x90,0x24,0x8e,0x46,0x00,0x00, +0x8e,0x47,0x00,0x04,0x08,0x00,0x2e,0xc7,0x26,0x52,0x00,0x08,0x08,0x00,0x2e,0xb4, +0x36,0x31,0x00,0x02,0x26,0x44,0x00,0x03,0x24,0x02,0xff,0xfc,0x00,0x82,0x90,0x24, +0x8e,0x44,0x00,0x00,0x02,0x15,0x10,0x23,0x26,0x52,0x00,0x04,0x08,0x00,0x2e,0x42, +0xac,0x82,0x00,0x00,0x08,0x00,0x2e,0xb4,0x24,0x09,0x00,0x08,0x24,0x02,0xff,0xff, +0x12,0x82,0x00,0x11,0x00,0x00,0x00,0x00,0x26,0x43,0x00,0x03,0x24,0x02,0xff,0xfc, +0x00,0x62,0x90,0x24,0x8e,0x47,0x00,0x00,0x02,0x00,0x20,0x21,0x24,0x02,0x00,0x10, +0x00,0x00,0x30,0x21,0xaf,0xa2,0x00,0x10,0xaf,0xb4,0x00,0x14,0xaf,0xa8,0x00,0x18, +0x0c,0x00,0x2f,0x91,0xaf,0xb1,0x00,0x1c,0x8f,0xa5,0x00,0x44,0x00,0x40,0x80,0x21, +0x08,0x00,0x2e,0x42,0x26,0x52,0x00,0x04,0x24,0x14,0x00,0x08,0x08,0x00,0x2e,0xf6, +0x36,0x31,0x00,0x01,0x26,0x42,0x00,0x03,0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24, +0x8e,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x60,0x00,0x23,0x26,0x52,0x00,0x04, +0x02,0x60,0x20,0x21,0x0c,0x00,0x30,0x5f,0x01,0x00,0x28,0x21,0x00,0x40,0x20,0x21, +0x32,0x22,0x00,0x10,0x14,0x40,0x00,0x09,0x00,0x94,0x10,0x2a,0x10,0x40,0x00,0x07, +0x26,0x94,0xff,0xff,0x24,0x03,0x00,0x20,0x00,0x94,0x10,0x2a,0xa2,0x03,0x00,0x00, +0x26,0x94,0xff,0xff,0x14,0x40,0xff,0xfc,0x26,0x10,0x00,0x01,0x18,0x80,0x00,0x07, +0x00,0x80,0x18,0x21,0x92,0x62,0x00,0x00,0x24,0x63,0xff,0xff,0x26,0x73,0x00,0x01, +0xa2,0x02,0x00,0x00,0x14,0x60,0xff,0xfb,0x26,0x10,0x00,0x01,0x00,0x94,0x10,0x2a, +0x10,0x40,0xff,0x83,0x26,0x94,0xff,0xff,0x24,0x03,0x00,0x20,0x00,0x94,0x10,0x2a, +0xa2,0x03,0x00,0x00,0x26,0x94,0xff,0xff,0x14,0x40,0xff,0xfc,0x26,0x10,0x00,0x01, +0x08,0x00,0x2e,0xac,0x00,0x00,0x00,0x00,0x3c,0x02,0x80,0x01,0x08,0x00,0x2f,0x10, +0x24,0x53,0x08,0x04,0x24,0x02,0x00,0x25,0xa2,0x02,0x00,0x00,0x8f,0xa5,0x00,0x44, +0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x00,0x90,0xa3,0x00,0x00,0x10,0x40,0x00,0x03, +0x26,0x10,0x00,0x01,0x08,0x00,0x2e,0x40,0xa2,0x03,0x00,0x00,0x24,0xa5,0xff,0xff, +0x08,0x00,0x2e,0x42,0xaf,0xa5,0x00,0x44,0x80,0xa6,0x00,0x00,0x24,0xa5,0x00,0x01, +0x08,0x00,0x2e,0x86,0xaf,0xa5,0x00,0x44,0x24,0xa5,0x00,0x01,0xaf,0xa5,0x00,0x44, +0x90,0xa4,0x00,0x00,0x3c,0x02,0x80,0x01,0x24,0x42,0x02,0x1c,0x00,0x44,0x10,0x21, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,0x14,0x60,0x00,0x0f, +0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03,0x24,0x03,0x00,0x2a,0x10,0x43,0x00,0x04, +0x26,0x42,0x00,0x03,0x29,0x02,0x00,0x00,0x08,0x00,0x2e,0x7b,0x00,0x02,0x40,0x0b, +0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24,0x24,0xa5,0x00,0x01,0x8e,0x48,0x00,0x00, +0xaf,0xa5,0x00,0x44,0x08,0x00,0x2f,0x55,0x26,0x52,0x00,0x04,0x0c,0x00,0x2f,0x75, +0x27,0xa4,0x00,0x44,0x8f,0xa5,0x00,0x44,0x08,0x00,0x2f,0x55,0x00,0x40,0x40,0x21, +0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24,0x8e,0x54,0x00,0x00,0x24,0xe5,0x00,0x01, +0xaf,0xa5,0x00,0x44,0x06,0x81,0xff,0x0d,0x26,0x52,0x00,0x04,0x00,0x14,0xa0,0x23, +0x08,0x00,0x2e,0x77,0x36,0x31,0x00,0x10,0x0c,0x00,0x2f,0x75,0x27,0xa4,0x00,0x44, +0x8f,0xa5,0x00,0x44,0x08,0x00,0x2e,0x77,0x00,0x40,0xa0,0x21,0x08,0x00,0x2e,0x51, +0x36,0x31,0x00,0x01,0x8c,0x86,0x00,0x00,0x3c,0x02,0x80,0x01,0x00,0x80,0x48,0x21, +0x90,0xc3,0x00,0x00,0x24,0x44,0x02,0x1c,0x00,0x64,0x18,0x21,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x04,0x10,0x40,0x00,0x10,0x00,0x00,0x38,0x21, +0x00,0x80,0x40,0x21,0x24,0xc2,0x00,0x01,0x80,0xc5,0x00,0x00,0xad,0x22,0x00,0x00, +0x90,0x43,0x00,0x00,0x00,0x40,0x30,0x21,0x00,0x07,0x10,0x80,0x00,0x68,0x18,0x21, +0x90,0x64,0x00,0x00,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x40,0x00,0x45,0x10,0x21, +0x30,0x84,0x00,0x04,0x14,0x80,0xff,0xf3,0x24,0x47,0xff,0xd0,0x03,0xe0,0x00,0x08, +0x00,0xe0,0x10,0x21,0x27,0xbd,0xff,0x98,0xaf,0xb2,0x00,0x50,0x8f,0xb2,0x00,0x84, +0x3c,0x02,0x80,0x01,0xaf,0xb4,0x00,0x58,0x32,0x43,0x00,0x40,0xaf,0xb1,0x00,0x4c, +0xaf,0xb0,0x00,0x48,0xaf,0xb7,0x00,0x64,0xaf,0xb6,0x00,0x60,0xaf,0xb5,0x00,0x5c, +0xaf,0xb3,0x00,0x54,0x00,0x80,0x68,0x21,0x00,0xc0,0x70,0x21,0x00,0xe0,0x78,0x21, +0x8f,0xb0,0x00,0x78,0x8f,0xb8,0x00,0x7c,0x8f,0xb1,0x00,0x80,0x10,0x60,0x00,0x03, +0x24,0x54,0x08,0x0c,0x3c,0x02,0x80,0x01,0x24,0x54,0x08,0x34,0x32,0x42,0x00,0x10, +0x10,0x40,0x00,0x04,0x26,0x02,0xff,0xfe,0x24,0x02,0xff,0xfe,0x02,0x42,0x90,0x24, +0x26,0x02,0xff,0xfe,0x2c,0x42,0x00,0x23,0x10,0x40,0x00,0x5d,0x00,0x00,0x18,0x21, +0x32,0x42,0x00,0x01,0x24,0x15,0x00,0x30,0x24,0x03,0x00,0x20,0x32,0x44,0x00,0x02, +0x00,0x62,0xa8,0x0a,0x10,0x80,0x00,0x07,0x00,0x00,0xb8,0x21,0x05,0xc0,0x00,0x96, +0x32,0x42,0x00,0x04,0x10,0x40,0x00,0x90,0x32,0x42,0x00,0x08,0x24,0x17,0x00,0x2b, +0x27,0x18,0xff,0xff,0x32,0x56,0x00,0x20,0x12,0xc0,0x00,0x07,0x01,0xcf,0x10,0x25, +0x24,0x02,0x00,0x10,0x12,0x02,0x00,0x86,0x27,0x03,0xff,0xff,0x3a,0x02,0x00,0x08, +0x00,0x62,0xc0,0x0a,0x01,0xcf,0x10,0x25,0x14,0x40,0x00,0x55,0x00,0x00,0xc8,0x21, +0x24,0x02,0x00,0x30,0x24,0x19,0x00,0x01,0xa3,0xa2,0x00,0x00,0x02,0x39,0x10,0x2a, +0x03,0x22,0x88,0x0b,0x32,0x43,0x00,0x11,0x14,0x60,0x00,0x0a,0x03,0x11,0xc0,0x23, +0x03,0x00,0x10,0x21,0x18,0x40,0x00,0x07,0x27,0x18,0xff,0xff,0x24,0x03,0x00,0x20, +0x03,0x00,0x10,0x21,0xa1,0xa3,0x00,0x00,0x27,0x18,0xff,0xff,0x1c,0x40,0xff,0xfc, +0x25,0xad,0x00,0x01,0x12,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0xa1,0xb7,0x00,0x00, +0x25,0xad,0x00,0x01,0x12,0xc0,0x00,0x07,0x32,0x42,0x00,0x10,0x24,0x02,0x00,0x08, +0x12,0x02,0x00,0x38,0x24,0x02,0x00,0x10,0x12,0x02,0x00,0x30,0x24,0x02,0x00,0x30, +0x32,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x03,0x31,0x10,0x2a,0x03,0x00,0x10,0x21, +0x18,0x40,0x00,0x06,0x27,0x18,0xff,0xff,0x03,0x00,0x10,0x21,0xa1,0xb5,0x00,0x00, +0x27,0x18,0xff,0xff,0x1c,0x40,0xff,0xfc,0x25,0xad,0x00,0x01,0x03,0x31,0x10,0x2a, +0x10,0x40,0x00,0x07,0x26,0x31,0xff,0xff,0x24,0x03,0x00,0x30,0x03,0x31,0x10,0x2a, +0xa1,0xa3,0x00,0x00,0x26,0x31,0xff,0xff,0x14,0x40,0xff,0xfc,0x25,0xad,0x00,0x01, +0x03,0x20,0x10,0x21,0x18,0x40,0x00,0x08,0x27,0x39,0xff,0xff,0x03,0xb9,0x10,0x21, +0x90,0x43,0x00,0x00,0x03,0x20,0x20,0x21,0x27,0x39,0xff,0xff,0xa1,0xa3,0x00,0x00, +0x1c,0x80,0xff,0xfa,0x25,0xad,0x00,0x01,0x03,0x00,0x10,0x21,0x18,0x40,0x00,0x07, +0x27,0x18,0xff,0xff,0x24,0x03,0x00,0x20,0x03,0x00,0x10,0x21,0xa1,0xa3,0x00,0x00, +0x27,0x18,0xff,0xff,0x1c,0x40,0xff,0xfc,0x25,0xad,0x00,0x01,0x01,0xa0,0x18,0x21, +0x7b,0xb6,0x03,0x3c,0x7b,0xb4,0x02,0xfc,0x7b,0xb2,0x02,0xbc,0x7b,0xb0,0x02,0x7c, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x68,0xa1,0xa2,0x00,0x00, +0x92,0x83,0x00,0x21,0x25,0xad,0x00,0x01,0xa1,0xa3,0x00,0x00,0x08,0x00,0x2f,0xe4, +0x25,0xad,0x00,0x01,0x24,0x02,0x00,0x30,0x08,0x00,0x30,0x17,0xa1,0xa2,0x00,0x00, +0x01,0xcf,0x10,0x25,0x10,0x40,0xff,0xad,0x00,0x00,0x60,0x21,0x00,0x0e,0x18,0x02, +0x03,0x3d,0x98,0x21,0x00,0x60,0x20,0x21,0x01,0xe0,0x38,0x21,0x10,0x60,0x00,0x04, +0x27,0x39,0x00,0x01,0x00,0x70,0x00,0x1b,0x00,0x00,0x20,0x12,0x00,0x00,0x18,0x10, +0x00,0x80,0x48,0x21,0x00,0xe0,0x30,0x21,0x01,0x80,0x70,0x21,0x01,0x80,0x28,0x21, +0x10,0x00,0x00,0x06,0x24,0x04,0x00,0x21,0x00,0x03,0x08,0x40,0x00,0x03,0x2f,0xc2, +0x00,0x22,0x18,0x25,0x00,0x06,0x30,0x40,0x00,0x0e,0x70,0x40,0x14,0xa0,0x00,0x02, +0x00,0x70,0x10,0x2b,0x14,0x40,0x00,0x03,0x24,0x84,0xff,0xff,0x00,0x70,0x18,0x23, +0x25,0xce,0x00,0x01,0x14,0x80,0xff,0xf4,0x00,0x06,0x17,0xc2,0x02,0x83,0x18,0x21, +0x01,0xc0,0x38,0x21,0x00,0x00,0x50,0x21,0x00,0x09,0x20,0x00,0x00,0x00,0x28,0x21, +0x90,0x66,0x00,0x00,0x00,0x8a,0x70,0x25,0x00,0xa7,0x78,0x25,0x01,0xcf,0x10,0x25, +0x14,0x40,0xff,0xda,0xa2,0x66,0x00,0x00,0x08,0x00,0x2f,0xcc,0x02,0x39,0x10,0x2a, +0x08,0x00,0x2f,0xc5,0x27,0x18,0xff,0xfe,0x10,0x40,0xff,0x73,0x32,0x56,0x00,0x20, +0x08,0x00,0x2f,0xbc,0x24,0x17,0x00,0x20,0x00,0x0f,0x78,0x23,0x00,0x0e,0x70,0x23, +0x00,0x0f,0x10,0x2b,0x01,0xc2,0x70,0x23,0x08,0x00,0x2f,0xbc,0x24,0x17,0x00,0x2d, +0x80,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x06,0x00,0x80,0x18,0x21, +0x24,0x63,0x00,0x01,0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfc, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x64,0x10,0x23,0x24,0xa5,0xff,0xff, +0x24,0x02,0xff,0xff,0x10,0xa2,0x00,0x0d,0x00,0x80,0x18,0x21,0x80,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x24,0x06,0xff,0xff, +0x24,0xa5,0xff,0xff,0x10,0xa6,0x00,0x05,0x24,0x63,0x00,0x01,0x80,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x64,0x10,0x23,0x80,0x82,0x00,0x00,0x90,0x88,0x00,0x00,0x10,0x40,0x00,0x17, +0x00,0x00,0x48,0x21,0x90,0xa3,0x00,0x00,0x00,0xa0,0x30,0x21,0x10,0x60,0x00,0x0b, +0x00,0x60,0x38,0x21,0x00,0x08,0x16,0x00,0x00,0x02,0x46,0x03,0x00,0x07,0x16,0x00, +0x00,0x02,0x16,0x03,0x11,0x02,0x00,0x05,0x24,0xc6,0x00,0x01,0x90,0xc3,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xf9,0x00,0x60,0x38,0x21,0x00,0x03,0x16,0x00, +0x10,0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x84,0x00,0x01,0x90,0x82,0x00,0x00, +0x25,0x29,0x00,0x01,0x14,0x40,0xff,0xeb,0x00,0x40,0x40,0x21,0x03,0xe0,0x00,0x08, +0x01,0x20,0x10,0x21,0x80,0x82,0x00,0x00,0x90,0x87,0x00,0x00,0x10,0x40,0x00,0x17, +0x00,0x00,0x18,0x21,0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00, +0x10,0x60,0x00,0x0c,0x00,0xa0,0x30,0x21,0x00,0x07,0x16,0x00,0x00,0x02,0x3e,0x03, +0x00,0x03,0x16,0x03,0x10,0xe2,0x00,0x0d,0x00,0x80,0x18,0x21,0x24,0xc6,0x00,0x01, +0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,0x14,0x60,0xff,0xf9, +0x00,0x03,0x16,0x03,0x24,0x84,0x00,0x01,0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x40,0xff,0xec,0x00,0x40,0x38,0x21,0x00,0x00,0x18,0x21,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0,0xaf,0xb0,0x00,0x10,0x8f,0x90,0xc5,0x5c, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0x00,0x84,0x80,0x0b,0x00,0x00,0x30,0x21, +0x12,0x00,0x00,0x0a,0x00,0xa0,0x88,0x21,0x0c,0x00,0x30,0x71,0x02,0x00,0x20,0x21, +0x02,0x02,0x80,0x21,0x82,0x02,0x00,0x00,0x02,0x20,0x28,0x21,0x02,0x00,0x20,0x21, +0x14,0x40,0x00,0x07,0x00,0x00,0x30,0x21,0xaf,0x80,0xc5,0x5c,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x0c,0x00,0x30,0x8d,0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,0x10,0x40,0x00,0x07, +0x02,0x00,0x30,0x21,0x80,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0xa0,0x60,0x00,0x00,0x24,0x63,0x00,0x01,0xaf,0x83,0xc5,0x5c, +0x08,0x00,0x30,0xbb,0x00,0x00,0x00,0x00,0x24,0xc6,0xff,0xff,0x24,0x02,0xff,0xff, +0x10,0xc2,0x00,0x05,0x00,0x80,0x18,0x21,0x24,0xc6,0xff,0xff,0xa0,0x65,0x00,0x00, +0x14,0xc2,0xff,0xfd,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21, +0x24,0xc6,0xff,0xff,0x24,0x02,0xff,0xff,0x10,0xc2,0x00,0x08,0x00,0x80,0x18,0x21, +0x24,0x07,0xff,0xff,0x90,0xa2,0x00,0x00,0x24,0xc6,0xff,0xff,0x24,0xa5,0x00,0x01, +0xa0,0x62,0x00,0x00,0x14,0xc7,0xff,0xfb,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08, +0x00,0x80,0x10,0x21,0x00,0x80,0x18,0x21,0x90,0xa2,0x00,0x00,0x24,0xa5,0x00,0x01, +0xa0,0x82,0x00,0x00,0x14,0x40,0xff,0xfc,0x24,0x84,0x00,0x01,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x90,0x83,0x00,0x00,0x90,0xa2,0x00,0x00,0x24,0x84,0x00,0x01, +0x00,0x62,0x10,0x23,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0x14,0x40,0x00,0x03, +0x24,0xa5,0x00,0x01,0x14,0x60,0xff,0xf7,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x93,0x85,0x88,0x6d, +0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x53,0x00,0x80,0x40,0x21,0x8c,0x89,0x00,0x04, +0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x8c,0xc3,0x00,0x04,0x3c,0x02,0x01,0x00, +0x00,0x62,0x10,0x24,0x10,0x40,0x00,0x4b,0x30,0x62,0x00,0x08,0x10,0x45,0x00,0x59, +0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4,0x30,0x44,0x00,0xff, +0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54,0x24,0x02,0x00,0x94, +0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x00,0x00,0x00,0x00, +0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88,0x14,0x62,0x00,0x39, +0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38,0x00,0x00,0x00,0x00, +0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe2,0x00,0x80, +0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x94,0xc3,0x00,0x60, +0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00,0x90,0xc2,0x00,0x62, +0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15,0x24,0x02,0x00,0x06, +0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x66, +0x27,0x82,0x92,0x48,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21, +0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25, +0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24, +0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x31,0x61,0xad,0x07,0x00,0x10, +0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x92,0x48,0x00,0x05,0x28,0x80, +0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00, +0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36,0x3c,0x03,0xff,0xff, +0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00, +0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x50, +0x08,0x00,0x31,0x1f,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac,0x27,0x83,0x92,0x48, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff, +0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00,0x24,0x03,0x00,0x2e, +0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x04,0x01,0xac, +0x27,0x83,0x92,0x48,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, +0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e,0x24,0x03,0x00,0x0e, +0x08,0x00,0x31,0x60,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac,0x27,0x83,0x92,0x48, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff, +0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14,0x08,0x00,0x31,0x60, +0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xc6,0x00,0xff, +0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8b,0xc5,0x70, +0x27,0x83,0xc5,0x76,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x00, +0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff,0x95,0x02,0x00,0x02, +0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01,0x10,0x43,0x00,0x18, +0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4b,0x30,0x21, +0x94,0xc4,0x00,0x02,0x27,0x83,0xc5,0x76,0x27,0x85,0xc5,0x74,0x00,0x45,0x28,0x21, +0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02,0xa4,0x40,0x00,0x00, +0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01,0x01,0x44,0x20,0x21, +0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00,0x8c,0x82,0x00,0x04, +0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x04, +0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24,0x00,0x47,0x28,0x25, +0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2,0x01,0x43,0x18,0x21, +0xac,0x65,0x00,0x00,0x08,0x00,0x31,0x8e,0x01,0x26,0x10,0x21,0x08,0x00,0x31,0x8e, +0x01,0x26,0x10,0x21,0x93,0x83,0x88,0x6d,0x24,0x02,0x00,0x01,0x14,0x62,0x00,0x0d, +0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09,0x00,0x82,0x20,0x21, +0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00,0x34,0xc6,0x01,0x00, +0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00,0x24,0x02,0x00,0x06, +0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x09, +0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e,0x08,0x00,0x31,0xc1, +0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff,0x00,0xa2,0x28,0x21, +0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21,0x00,0x62,0x18,0x24, +0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x80,0x00, +0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00, +0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a, +0x93,0x83,0x88,0x6c,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23, +0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x88,0x6c,0x8c,0xc4,0x01,0xac, +0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26,0x00,0x02,0x10,0x2b, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x04, +0x00,0x00,0x00,0x00,0xa3,0x80,0x88,0x6d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0xa3,0x82,0x88,0x6d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21,0x00,0x45,0x10,0x21, +0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02,0x30,0x69,0x00,0x0f, +0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09,0x24,0x02,0x00,0x0a, +0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05,0x24,0x02,0x00,0x01, +0x93,0x83,0x88,0x6c,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03,0x34,0x84,0x80,0x18, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x8d,0x43,0x01,0xa8, +0x27,0x82,0x92,0x48,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21,0x8c,0x87,0x00,0xa8, +0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21,0x8c,0xa9,0x00,0x00, +0x3c,0x02,0xff,0xff,0x27,0x83,0x93,0x48,0x01,0x22,0x10,0x24,0x00,0x48,0x10,0x25, +0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2,0x3c,0x02,0x00,0x80, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00,0x8c,0xa9,0x00,0x04, +0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,0x01,0x22,0x10,0x25, +0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xc5,0x60,0x8c,0xa2,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x82,0xc5,0x68,0x8c,0xa3,0x00,0x04,0x3c,0x01,0xb0,0x07, +0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xc5,0x64,0x93,0x85,0x88,0x6c, +0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff,0x00,0x82,0x20,0x23, +0xad,0x44,0x01,0xa8,0xa3,0x85,0x88,0x6c,0x08,0x00,0x32,0x0c,0x00,0x00,0x00,0x00, +0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20,0x24,0x42,0xc9,0x10, +0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20,0xac,0x82,0x00,0x64, +0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04, +0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,0xac,0x80,0x00,0x50,0xac,0x80,0x00,0x54, +0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,0xa0,0x80,0x00,0x5c,0x24,0x42,0xc9,0xd4, +0x24,0x83,0x00,0x68,0x24,0x05,0x00,0x0f,0x24,0xa5,0xff,0xff,0xac,0x62,0x00,0x00, +0x04,0xa1,0xff,0xfd,0x24,0x63,0x00,0x04,0x3c,0x02,0x80,0x01,0x24,0x42,0xcb,0x04, +0xac,0x82,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x24,0x63,0xcc,0x90, +0x24,0x42,0xcb,0xfc,0xac,0x83,0x00,0x88,0xac,0x82,0x00,0x98,0x3c,0x03,0x80,0x01, +0x3c,0x02,0x80,0x01,0x24,0x63,0xcd,0x38,0x24,0x42,0xce,0x50,0xac,0x83,0x00,0xa0, +0xac,0x82,0x00,0xa4,0xa0,0x80,0x01,0xba,0xac,0x80,0x01,0xa8,0xac,0x80,0x01,0xac, +0xac,0x80,0x01,0xb0,0xac,0x80,0x01,0xb4,0xa0,0x80,0x01,0xb8,0x03,0xe0,0x00,0x08, +0xa0,0x80,0x01,0xb9,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20, +0x24,0x42,0xc9,0xd4,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0xc9,0xec, +0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,0xaf,0xbf,0x00,0x14,0x8c,0x83,0x00,0x10, +0x8f,0x82,0x94,0xe8,0x00,0x80,0x80,0x21,0x3c,0x04,0x80,0x01,0x30,0x46,0x00,0x01, +0x10,0x60,0x00,0x11,0x24,0x84,0x08,0x64,0x8e,0x02,0x00,0x14,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8e,0x05,0x00,0x10,0x8e,0x03,0x00,0x14, +0x8e,0x02,0x00,0x04,0x00,0xa3,0x28,0x21,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff, +0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00, +0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04,0x14,0xc0,0x00,0x0a,0x00,0x00,0x00,0x00, +0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54, +0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x8e,0x05,0x00,0x10,0x8e,0x07,0x00,0x04,0x8e,0x06,0x00,0x14, +0x0c,0x00,0x1a,0x6b,0x00,0x00,0x00,0x00,0x08,0x00,0x32,0x9d,0xae,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0xca,0xb0, +0xac,0x62,0x00,0x00,0x8c,0x86,0x00,0x04,0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01, +0x00,0xc2,0x10,0x21,0x8c,0x45,0x00,0x00,0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02, +0x30,0xa3,0x3f,0xff,0x30,0x42,0x00,0xff,0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14, +0x8c,0x83,0x00,0x14,0xac,0x85,0x00,0x40,0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08, +0xac,0x86,0x00,0x08,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x42,0x00,0x20,0x24,0x63,0xcb,0x04,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a, +0x00,0x80,0x80,0x21,0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50, +0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x32,0xac,0x00,0x00,0x00,0x00, +0x08,0x00,0x32,0xce,0xae,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, +0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xcb,0x68,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01, +0x8e,0x04,0x00,0x44,0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01, +0xae,0x02,0x00,0x50,0x30,0xa3,0x00,0xff,0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02, +0x30,0x84,0x00,0x0f,0x30,0x42,0x00,0x03,0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34, +0xae,0x02,0x00,0x2c,0xae,0x03,0x00,0x30,0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x32,0xac, +0x00,0x00,0x00,0x00,0x08,0x00,0x32,0xe6,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xcb,0xfc, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44, +0x8e,0x02,0x00,0x40,0x83,0x85,0x95,0x14,0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01, +0x00,0x02,0x16,0x02,0xae,0x04,0x00,0x14,0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18, +0x10,0xa0,0x00,0x04,0xae,0x03,0x00,0x3c,0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01, +0x24,0x06,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x86,0x95,0x14,0x8f,0xbf,0x00,0x14, +0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x0c,0x00,0x32,0xda,0x00,0x00,0x00,0x00,0x08,0x00,0x33,0x0b,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, +0x24,0x63,0xcc,0x90,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, +0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21, +0x3c,0x02,0xb0,0x03,0x8c,0x42,0x00,0x00,0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40, +0x83,0x86,0x95,0x14,0x92,0x05,0x00,0x41,0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01, +0x00,0x02,0x12,0xc2,0x00,0x03,0x1e,0x02,0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14, +0x00,0x00,0x38,0x21,0xae,0x03,0x00,0x18,0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c, +0x10,0x80,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01, +0xa3,0x87,0x95,0x14,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x32,0xda,0x00,0x00,0x00,0x00, +0x08,0x00,0x33,0x30,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, +0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xcd,0x38,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x37,0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44, +0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x85,0x20,0x21, +0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac, +0x02,0x00,0x20,0x21,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00,0x00,0x03,0x18,0x80, +0x27,0x82,0x92,0x48,0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00,0x8e,0x02,0x00,0x04, +0x8e,0x03,0x01,0xac,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04,0x00,0x03,0x18,0x80, +0x27,0x82,0x93,0x48,0x00,0x62,0x18,0x21,0x0c,0x00,0x30,0xfb,0xac,0x66,0x00,0x00, +0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01, +0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83, +0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21, +0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00, +0x93,0x82,0x88,0x6c,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01, +0xac,0xc3,0x00,0x00,0xa3,0x82,0x88,0x6c,0x0c,0x00,0x32,0x7b,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x0c,0x00,0x33,0x24,0x00,0x00,0x00,0x00,0x08,0x00,0x33,0x5a,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, +0x24,0x63,0xce,0x50,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, +0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37,0x00,0x80,0x80,0x21, +0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x01, +0x34,0x42,0x00,0x10,0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04, +0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21,0x00,0x45,0x10,0x21, +0x8c,0x46,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0x92,0x48,0x00,0x62,0x18,0x21, +0xac,0x66,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x00,0x45,0x10,0x21, +0x8c,0x46,0x00,0x04,0x00,0x03,0x18,0x80,0x27,0x82,0x93,0x48,0x00,0x62,0x18,0x21, +0x0c,0x00,0x30,0xfb,0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04, +0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40, +0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80, +0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8, +0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x88,0x6c,0x02,0x00,0x20,0x21, +0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x88,0x6c, +0x0c,0x00,0x32,0x7b,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x33,0x24,0x00,0x00,0x00,0x00, +0x08,0x00,0x33,0xa0,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, +0x34,0x42,0x00,0x20,0x24,0x63,0xcf,0x68,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00, +0x3c,0x02,0x80,0x01,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x1c,0x00,0x80,0x80,0x21,0x24,0x52,0xc9,0xd4,0x00,0x00,0x88,0x21, +0x3c,0x03,0xb0,0x09,0x34,0x63,0x00,0x06,0x8e,0x06,0x00,0x04,0x90,0x62,0x00,0x00, +0x00,0x06,0x22,0x02,0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00, +0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, +0x24,0x84,0xff,0xff,0x10,0x44,0x00,0x68,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x01, +0x00,0xc2,0x10,0x21,0x8c,0x44,0x00,0x04,0x3c,0x03,0x7c,0x00,0x34,0x63,0x00,0xf0, +0x00,0x83,0x18,0x24,0xae,0x04,0x00,0x44,0x8c,0x44,0x00,0x00,0x10,0x60,0x00,0x69, +0x00,0x00,0x38,0x21,0x3c,0x09,0xb0,0x03,0x3c,0x06,0x7c,0x00,0x35,0x29,0x00,0x99, +0x3c,0x0a,0xb0,0x01,0x24,0x08,0x00,0x40,0x34,0xc6,0x00,0xf0,0x3c,0x0b,0xff,0xff, +0x3c,0x0c,0x28,0x38,0x16,0x20,0x00,0x06,0x24,0xa5,0x00,0x01,0x93,0x82,0x88,0xa0, +0x24,0x11,0x00,0x01,0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x88,0xa0, +0x8e,0x02,0x00,0x04,0x24,0x07,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff, +0xae,0x02,0x00,0x04,0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00, +0xae,0x03,0x00,0x44,0x8c,0x44,0x00,0x00,0x10,0xa8,0x00,0x2d,0x00,0x66,0x18,0x24, +0x14,0x60,0xff,0xec,0x00,0x8b,0x10,0x24,0x14,0x4c,0xff,0xea,0x24,0x02,0x00,0x01, +0x10,0xe2,0x00,0x2f,0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60, +0x00,0x02,0x1e,0x42,0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01, +0xae,0x02,0x00,0x00,0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64, +0x8e,0x04,0x00,0x58,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00, +0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c, +0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21, +0x8c,0x42,0x00,0x68,0x00,0x00,0x00,0x00,0x10,0x52,0x00,0x06,0x00,0x00,0x00,0x00, +0x00,0x40,0xf8,0x09,0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00, +0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x60,0x08,0x00,0x33,0xe8,0xae,0x04,0x00,0x64, +0x8e,0x02,0x00,0x64,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00, +0x7a,0x02,0x0d,0x7c,0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x00,0x43,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x34,0x63,0x00,0x06,0x8e,0x04,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x04,0x22,0x02, +0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f, +0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23, +0x14,0x87,0xff,0xc5,0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x2c,0x62,0x00,0x03,0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,0x10,0x62,0x00,0x03, +0x24,0x02,0x00,0x01,0x08,0x00,0x34,0x48,0xa2,0x02,0x00,0x5c,0x08,0x00,0x34,0x48, +0xa2,0x00,0x00,0x5c,0x3c,0x02,0xff,0xff,0x00,0x82,0x10,0x24,0x3c,0x03,0x28,0x38, +0x14,0x43,0xff,0x94,0x24,0x02,0x00,0x01,0x08,0x00,0x34,0x20,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xd1,0xc0, +0xac,0x43,0x00,0x00,0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,0x00,0x80,0x40,0x21, +0x10,0x62,0x00,0x20,0x00,0x00,0x20,0x21,0x93,0x82,0x88,0x6d,0x00,0x03,0x28,0x80, +0x3c,0x07,0xb0,0x06,0x00,0xa8,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x66,0x00,0xa8, +0x10,0x44,0x00,0x1c,0x34,0xe7,0x80,0x18,0x3c,0x05,0xb0,0x01,0xaf,0x86,0xc5,0x60, +0x00,0xc5,0x28,0x21,0x8c,0xa3,0x00,0x00,0x00,0x06,0x20,0xc2,0x3c,0x02,0x00,0x80, +0x00,0x04,0x22,0x00,0x00,0x82,0x20,0x25,0xaf,0x83,0xc5,0x68,0x8c,0xa2,0x00,0x04, +0xac,0xe4,0x00,0x00,0x8d,0x03,0x01,0xa8,0xaf,0x82,0xc5,0x64,0x24,0x64,0x00,0x01, +0x04,0x80,0x00,0x0a,0x00,0x80,0x10,0x21,0x00,0x02,0x11,0x83,0x8d,0x03,0x01,0xac, +0x00,0x02,0x11,0x80,0x00,0x82,0x10,0x23,0x00,0x43,0x18,0x26,0xad,0x02,0x01,0xa8, +0x00,0x03,0x20,0x2b,0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x34,0x92, +0x24,0x62,0x00,0x40,0x27,0x82,0x92,0x48,0x00,0x06,0x20,0xc2,0x00,0x04,0x22,0x00, +0x00,0xa2,0x48,0x21,0x3c,0x02,0x00,0x80,0x00,0x82,0x58,0x25,0x93,0x82,0x88,0x6c, +0x3c,0x0a,0xb0,0x06,0x3c,0x03,0xb0,0x01,0x2c,0x42,0x00,0x02,0x00,0xc3,0x38,0x21, +0x35,0x4a,0x80,0x18,0x14,0x40,0xff,0xef,0x00,0x00,0x20,0x21,0x8c,0xe5,0x00,0x00, +0x8d,0x23,0x00,0x00,0x24,0x02,0xc0,0x00,0x00,0xa2,0x10,0x24,0x00,0x43,0x10,0x25, +0xac,0xe2,0x00,0x00,0x8d,0x04,0x01,0xa8,0x27,0x83,0x93,0x48,0x8c,0xe5,0x00,0x04, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00, +0x00,0xa2,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x04,0xaf,0x86,0xc5,0x60, +0x8c,0xe2,0x00,0x00,0x93,0x85,0x88,0x6c,0xaf,0x82,0xc5,0x68,0x8c,0xe3,0x00,0x04, +0xad,0x4b,0x00,0x00,0x8d,0x02,0x01,0xa8,0xaf,0x83,0xc5,0x64,0x24,0xa5,0xff,0xff, +0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xad,0x04,0x01,0xa8, +0xa3,0x85,0x88,0x6c,0x79,0x02,0x0d,0x7c,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x26, +0x08,0x00,0x34,0x99,0x00,0x02,0x20,0x2b,0x90,0x87,0x00,0x00,0x3c,0x02,0x80,0x01, +0x27,0xbd,0xff,0xe8,0x24,0x48,0x02,0x1c,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0x01,0x07,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x20, +0x10,0x40,0x00,0x0a,0x00,0x00,0x80,0x21,0x24,0x84,0x00,0x01,0x90,0x87,0x00,0x00, +0x00,0x00,0x00,0x00,0x01,0x07,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x20,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x07,0x16,0x00, +0x00,0x02,0x16,0x03,0x24,0x03,0x00,0x2d,0x10,0x43,0x00,0x0f,0x00,0x00,0x00,0x00, +0x0c,0x00,0x34,0xfd,0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,0x00,0x02,0x10,0x23, +0x04,0x61,0x00,0x05,0x00,0x70,0x10,0x0a,0x16,0x00,0x00,0x03,0x3c,0x02,0x80,0x00, +0x3c,0x02,0x7f,0xff,0x34,0x42,0xff,0xff,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x10,0xff,0xff,0x08,0x00,0x34,0xec, +0x24,0x84,0x00,0x01,0x00,0x80,0x38,0x21,0x90,0x84,0x00,0x00,0x3c,0x02,0x80,0x01, +0x24,0x48,0x02,0x1c,0x01,0x04,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x20,0x10,0x40,0x00,0x0a,0x00,0x00,0x50,0x21,0x24,0xe7,0x00,0x01, +0x90,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x18,0x21,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x20,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00, +0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03,0x38,0x42,0x00,0x2b,0x24,0xe3,0x00,0x01, +0x24,0x04,0x00,0x10,0x10,0xc4,0x00,0x38,0x00,0x62,0x38,0x0a,0x90,0xe4,0x00,0x00, +0x14,0xc0,0x00,0x07,0x00,0x80,0x18,0x21,0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03, +0x24,0x03,0x00,0x30,0x10,0x43,0x00,0x25,0x24,0x06,0x00,0x0a,0x00,0x80,0x18,0x21, +0x00,0x03,0x16,0x00,0x10,0x40,0x00,0x1a,0x30,0x64,0x00,0xff,0x24,0x82,0xff,0xa9, +0x2c,0x83,0x00,0x61,0x30,0x48,0x00,0xff,0x10,0x60,0x00,0x09,0x2c,0x89,0x00,0x41, +0x24,0x82,0xff,0xc9,0x30,0x48,0x00,0xff,0x11,0x20,0x00,0x05,0x2c,0x83,0x00,0x3a, +0x24,0x82,0xff,0xd0,0x14,0x60,0x00,0x02,0x30,0x48,0x00,0xff,0x24,0x08,0x00,0xff, +0x01,0x06,0x10,0x2a,0x10,0x40,0x00,0x0a,0x01,0x46,0x00,0x18,0x24,0xe7,0x00,0x01, +0x00,0x00,0x18,0x12,0x00,0x6a,0x10,0x2b,0x14,0x40,0x00,0x0a,0x00,0x68,0x50,0x21, +0x80,0xe2,0x00,0x00,0x90,0xe3,0x00,0x00,0x14,0x40,0xff,0xe8,0x30,0x64,0x00,0xff, +0x10,0xa0,0x00,0x02,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x03,0xe0,0x00,0x08, +0x01,0x40,0x10,0x21,0x03,0xe0,0x00,0x08,0x24,0x02,0xff,0xff,0x24,0x06,0x00,0x08, +0x80,0xe3,0x00,0x01,0x24,0x02,0x00,0x78,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x58, +0x14,0x62,0xff,0xd7,0x00,0x80,0x18,0x21,0x24,0xe7,0x00,0x02,0x90,0xe4,0x00,0x00, +0x08,0x00,0x35,0x1f,0x24,0x06,0x00,0x10,0x80,0xe3,0x00,0x00,0x24,0x02,0x00,0x30, +0x90,0xe4,0x00,0x00,0x10,0x62,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x35,0x18, +0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01, +0x34,0xc6,0x00,0x18,0x34,0x84,0x00,0x20,0x24,0x42,0xd5,0x54,0x24,0x03,0xff,0x83, +0xac,0x82,0x00,0x00,0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8, +0x3c,0x03,0xb0,0x07,0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00, +0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01, +0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07, +0xa3,0xa3,0x00,0x00,0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10, +0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38, +0xa0,0xa2,0x00,0x00,0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20, +0xa3,0xa4,0x00,0x00,0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xc8,0x70, +0xa3,0xa3,0x00,0x00,0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x08,}; + +u8 rtl8190_fwdata_array[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x0a,0x0d,0x5b,0x43,0x4d,0x50,0x4b,0x5d,0x00,0x00,0x00,0x00, +0x80,0x01,0x00,0x14,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08, +0x08,0x08,0x08,0x08,0x08,0x28,0x28,0x28,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x08, +0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xa0,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x04,0x04,0x04,0x04, +0x04,0x04,0x04,0x04,0x04,0x04,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x41,0x41,0x41, +0x41,0x41,0x41,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10,0x10,0x42,0x42,0x42, +0x42,0x42,0x42,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x10,0x10,0x10,0x08,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,0xa0,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x20,0x09,0x0d,0x0a, +0x00,0x00,0x00,0x00,0x80,0x01,0x03,0x1c,0x00,0x00,0x00,0x00,0x43,0x6e,0x73,0x64, +0x31,0x00,0x00,0x00,0x68,0x65,0x6c,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x72,0x34,0x00,0x00,0x77,0x34,0x00,0x00,0x64,0x62,0x67,0x00,0x72,0x61,0x63,0x74, +0x72,0x6c,0x00,0x00,0x73,0x79,0x73,0x64,0x00,0x00,0x00,0x00,0x73,0x79,0x73,0x63, +0x74,0x72,0x6c,0x00,0x74,0x78,0x74,0x62,0x6c,0x00,0x00,0x00,0x70,0x72,0x61,0x6e, +0x67,0x65,0x00,0x00,0x64,0x6d,0x00,0x00,0x75,0x6e,0x6b,0x6e,0x6f,0x77,0x00,0x00, +0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x80,0x00,0x24,0x5c,0x80,0x01,0x03,0x40,0x80,0x01,0x03,0x3c, +0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x25,0xbc, +0x80,0x01,0x03,0x44,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x80,0x00,0x27,0x38,0x80,0x01,0x03,0x48,0x80,0x01,0x03,0x3c, +0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x29,0x04, +0x80,0x01,0x03,0x4c,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x80,0x00,0x29,0xdc,0x80,0x01,0x03,0x54,0x80,0x01,0x03,0x3c, +0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x29,0xe4, +0x80,0x01,0x03,0x5c,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x80,0x00,0x29,0xec,0x80,0x01,0x03,0x64,0x80,0x01,0x03,0x3c, +0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x29,0xf4, +0x80,0x01,0x03,0x6c,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x80,0x00,0x2b,0x80,0x80,0x01,0x03,0x74,0x80,0x01,0x03,0x3c, +0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x2b,0xf4, +0x80,0x01,0x03,0x78,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x3c,0x00,0x00,0x00,0x0f, +0x00,0x00,0x00,0x01,0x80,0x00,0x2c,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0a,0x0d,0x52,0x54,0x4c,0x38,0x31,0x39,0x58,0x2d,0x25,0x64,0x3e,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x52,0x54,0x4c,0x38,0x31,0x39,0x58,0x2d,0x25,0x64,0x3e,0x0a, +0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x0a,0x0d,0x45,0x72, +0x72,0x20,0x44,0x49,0x52,0x00,0x00,0x00,0x0a,0x0d,0x44,0x42,0x47,0x20,0x43,0x4d, +0x44,0x73,0x3a,0x00,0x0a,0x0d,0x5b,0x00,0x5d,0x2d,0x00,0x00,0x0a,0x0d,0x3c,0x31, +0x2e,0x43,0x4d,0x4e,0x3e,0x20,0x3c,0x32,0x2e,0x3f,0x3e,0x00,0x0a,0x0d,0x20,0x79, +0x65,0x61,0x72,0x2d,0x64,0x61,0x79,0x2d,0x68,0x6f,0x75,0x72,0x2d,0x6d,0x69,0x6e, +0x2d,0x73,0x65,0x63,0x2d,0x31,0x30,0x6d,0x73,0x3d,0x00,0x00,0x25,0x64,0x2d,0x00, +0x0a,0x0d,0x09,0x20,0x20,0x20,0x20,0x20,0x30,0x30,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x30,0x34,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x38,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x30,0x43,0x00,0x00,0x00,0x0a,0x0d,0x09,0x20,0x20,0x20,0x20,0x20, +0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, +0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, +0x3d,0x3d,0x3d,0x00,0x0d,0x0a,0x20,0x30,0x78,0x25,0x30,0x38,0x58,0x20,0x20,0x00, +0x09,0x00,0x00,0x00,0x25,0x30,0x38,0x58,0x20,0x00,0x00,0x00,0x0a,0x0d,0x44,0x62, +0x67,0x5f,0x46,0x6c,0x61,0x67,0x25,0x64,0x3d,0x30,0x78,0x25,0x30,0x38,0x78,0x00, +0x0a,0x0d,0x54,0x58,0x4c,0x4c,0x54,0x09,0x09,0x4e,0x45,0x58,0x54,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4e,0x45,0x58,0x54,0x0a,0x0d,0x00, +0x0a,0x0d,0x20,0x50,0x61,0x67,0x65,0x25,0x33,0x64,0x09,0x00,0x25,0x34,0x64,0x20, +0x20,0x20,0x20,0x00,0x25,0x34,0x64,0x20,0x20,0x20,0x20,0x09,0x00,0x00,0x00,0x00, +0x0a,0x0d,0x54,0x58,0x4f,0x51,0x54,0x09,0x09,0x48,0x65,0x61,0x64,0x20,0x20,0x20, +0x20,0x54,0x61,0x69,0x6c,0x20,0x20,0x20,0x20,0x48,0x65,0x61,0x64,0x20,0x20,0x20, +0x20,0x54,0x61,0x69,0x6c,0x0a,0x0d,0x00,0x0a,0x0d,0x55,0x6e,0x6b,0x6e,0x6f,0x77, +0x20,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64,0x00,0x00,0x00,0x00,0x0a,0x0d,0x45,0x72, +0x72,0x20,0x41,0x72,0x67,0x0a,0x0d,0x55,0x53,0x41,0x47,0x45,0x3a,0x00,0x00,0x00, +0x10,0x00,0x08,0x00,0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4, +0x00,0xab,0x00,0x72,0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c, +0x02,0x76,0x01,0x3b,0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f, +0x01,0x3b,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20, +0x01,0x2f,0x00,0x98,0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e, +0x00,0x98,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f, +0x02,0x39,0x01,0x1c,0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39, +0x01,0x1c,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c, +0x01,0x11,0x00,0x89,0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b, +0x00,0x89,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e, +0x02,0xab,0x02,0xab,0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08, +0x04,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x54,0x4c,0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c, +0x5f,0x64,0x61,0x74,0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00, +0x41,0x64,0x45,0x4c,0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00, +0x00,0x00,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78, +0x63,0x43,0x6f,0x64,0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x42,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x4f,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x80,0x01,0x14,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10, +0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48, +0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20, +0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0, +0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x70,0x00,0x00,0x03,0x40, +0x00,0x00,0x03,0xa8,0x00,0x00,0x04,0x10,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0xa0, +0x00,0x00,0x02,0x70,0x00,0x00,0x03,0x40,0x00,0x00,0x04,0xe0,0x00,0x00,0x06,0x80, +0x00,0x00,0x07,0x50,0x00,0x00,0x08,0x20,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02, +0x03,0x03,0x04,0x04,0x01,0x02,0x02,0x04,0x04,0x06,0x07,0x08,0x02,0x04,0x04,0x07, +0x07,0x0b,0x0d,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x4e,0x55,0x4c,0x4c,0x3e,0x00,0x00,0x30,0x31,0x32,0x33, +0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a, +0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a, +0x00,0x00,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42, +0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52, +0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x5b,0x52,0x58,0x5d,0x20,0x70,0x6b,0x74,0x5f,0x6c,0x65,0x6e, +0x3d,0x25,0x64,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x25,0x64,0x20,0x73,0x74, +0x61,0x72,0x74,0x5f,0x61,0x64,0x64,0x72,0x3d,0x25,0x30,0x38,0x78,0x0a,0x0d,0x00, +0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x6c,0x80,0x00,0x07,0x80,0x80,0x00,0x07,0x80, +0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x94,0x80,0x00,0x75,0x98, +0x80,0x00,0x75,0xec,0x80,0x00,0x76,0x08,0x80,0x00,0x76,0xf4,0x80,0x00,0x77,0xac, +0x80,0x00,0x77,0xfc,0x80,0x00,0x78,0x68,0x80,0x00,0x79,0x6c,0x80,0x00,0x79,0xa0, +0x80,0x00,0x79,0xb4,0x80,0x00,0x79,0xc8,0x80,0x00,0x7a,0x74,0x80,0x00,0x7a,0xb0, +0x80,0x00,0x7b,0x60,0x80,0x00,0x7b,0x88,0x80,0x00,0x75,0x54,0x80,0x00,0x7b,0x9c, +0x80,0x00,0x82,0x28,0x80,0x00,0x82,0xa0,0x80,0x00,0x82,0xac,0x80,0x00,0x82,0xb8, +0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40, +0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40, +0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40,0x80,0x00,0x82,0x40, +0x80,0x00,0x82,0xc4,0x80,0x00,0x82,0xd0,0x80,0x00,0x82,0xdc,0x80,0x00,0xa5,0x50, +0x80,0x00,0xa5,0x50,0x80,0x00,0xa5,0x50,0x80,0x00,0xa5,0x50,0x80,0x00,0xa5,0x50, +0x80,0x00,0xa5,0x84,0x80,0x00,0xa5,0xf4,0x80,0x00,0xa6,0x1c,0x80,0x00,0xa6,0xf8, +0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xf8, +0x80,0x00,0xa6,0x30,0x80,0x00,0xa6,0x94,0x80,0x00,0xa6,0xc4,0x80,0x00,0xa6,0xf8, +0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xf8,0x80,0x00,0xa6,0xd0, +0x80,0x00,0xa7,0x2c,0x80,0x00,0xa7,0x40,0x80,0x00,0xa4,0xac,0x80,0x00,0xaa,0x50, +0x80,0x00,0xaa,0x50,0x80,0x00,0xaa,0x50,0x80,0x00,0xaa,0x50,0x80,0x00,0xaa,0x50, +0x80,0x00,0xaa,0x84,0x80,0x00,0xaa,0xf4,0x80,0x00,0xab,0x1c,0x80,0x00,0xab,0xf8, +0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xf8, +0x80,0x00,0xab,0x30,0x80,0x00,0xab,0x94,0x80,0x00,0xab,0xc4,0x80,0x00,0xab,0xf8, +0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xf8,0x80,0x00,0xab,0xd0, +0x80,0x00,0xac,0x2c,0x80,0x00,0xac,0x40,0x80,0x00,0xa8,0x88,0x80,0x00,0xb9,0x8c, +0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0x94,0x80,0x00,0xb9,0xa4, +0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4, +0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0x9c,0x80,0x00,0xb9,0xa4, +0x80,0x00,0xb9,0x84,0x80,0x00,0xb9,0xa4,0x80,0x00,0xb9,0xa4,0x80,0x00,0xbd,0xcc, +0x80,0x00,0xba,0xbc,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xba,0xc8, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xba,0x50,0x80,0x00,0xbb,0x9c, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbb,0x9c,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbb,0xa4,0x80,0x00,0xbb,0xc4,0x80,0x00,0xbb,0xcc, +0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0x24,0x80,0x00,0xbc,0xd4, +0x80,0x00,0xba,0xd0,0x80,0x00,0xbc,0xd4,0x80,0x00,0xbc,0xd4,0x80,0x00,0xba,0xcc, +}; + +#endif //__INC_R819XU_FIRMWARE_IMG_H -- cgit v1.2.3 From a3b2e09333ce811e69ac71379a2dd8ccd1b2ca6f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 25 Aug 2009 16:00:48 -0700 Subject: Staging: add cowloop to the build Now that the code can build, let's add it to the build system. Cc: "H.J. Thomassen" Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/cowloop/Kconfig | 16 ++++++++++++++++ drivers/staging/cowloop/Makefile | 1 + 4 files changed, 20 insertions(+) create mode 100644 drivers/staging/cowloop/Kconfig create mode 100644 drivers/staging/cowloop/Makefile (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2b3c0c45571..ee073ce3974 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -141,5 +141,7 @@ source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" +source "drivers/staging/cowloop/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index aa9553cc6a5..c5c8cae3645 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_RAR_REGISTER) += rar/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ +obj-$(CONFIG_COWLOOP) += cowloop/ diff --git a/drivers/staging/cowloop/Kconfig b/drivers/staging/cowloop/Kconfig new file mode 100644 index 00000000000..58d2a23bd2c --- /dev/null +++ b/drivers/staging/cowloop/Kconfig @@ -0,0 +1,16 @@ +config COWLOOP + tristate "copy-on-write pseudo Block Driver" + depends on BLOCK + default n + ---help--- + Cowloop is a "copy-on-write" pseudo block driver. It can be + stacked on top of a "real" block driver, and catches all write + operations on their way from the file systems layer above to + the real driver below, effectively shielding the lower driver + from those write accesses. The requests are then diverted to + an ordinary file, located somewhere else (configurable). Later + read requests are checked to see whether they can be serviced + by the "real" block driver below, or must be pulled in from + the diverted location. More information and userspace tools to + use the driver are on the project's website + http://www.ATComputing.nl/cowloop/ diff --git a/drivers/staging/cowloop/Makefile b/drivers/staging/cowloop/Makefile new file mode 100644 index 00000000000..2b6b81a63d2 --- /dev/null +++ b/drivers/staging/cowloop/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_COWLOOP) += cowloop.o -- cgit v1.2.3 From 06bf27ddaae4deb796ec90a11c5ecefd7364e3ed Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Sep 2009 21:27:08 -0700 Subject: Staging: remove me4000 driver. The comedi drivers should be used instead, no need to have this driver in the tree duplicating that one. Cc: Wolfgang Beiter Cc: Guenter Gebhardt Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/me4000/Kconfig | 10 - drivers/staging/me4000/Makefile | 1 - drivers/staging/me4000/README | 13 - drivers/staging/me4000/me4000.c | 6109 ------------------ drivers/staging/me4000/me4000.h | 966 --- drivers/staging/me4000/me4000_firmware.h | 10033 ----------------------------- drivers/staging/me4000/me4610_firmware.h | 5409 ---------------- 9 files changed, 22544 deletions(-) delete mode 100644 drivers/staging/me4000/Kconfig delete mode 100644 drivers/staging/me4000/Makefile delete mode 100644 drivers/staging/me4000/README delete mode 100644 drivers/staging/me4000/me4000.c delete mode 100644 drivers/staging/me4000/me4000.h delete mode 100644 drivers/staging/me4000/me4000_firmware.h delete mode 100644 drivers/staging/me4000/me4610_firmware.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index ee073ce3974..d76f6b356de 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -47,8 +47,6 @@ source "drivers/staging/slicoss/Kconfig" source "drivers/staging/sxg/Kconfig" -source "drivers/staging/me4000/Kconfig" - source "drivers/staging/meilhaus/Kconfig" source "drivers/staging/go7007/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c5c8cae3645..01bf2284520 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_SXG) += sxg/ -obj-$(CONFIG_ME4000) += me4000/ obj-$(CONFIG_MEILHAUS) += meilhaus/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ diff --git a/drivers/staging/me4000/Kconfig b/drivers/staging/me4000/Kconfig deleted file mode 100644 index 5e6c9de1f11..00000000000 --- a/drivers/staging/me4000/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config ME4000 - tristate "Meilhaus ME-4000 support" - default n - depends on PCI - help - This driver supports the Meilhaus ME-4000 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me4000. diff --git a/drivers/staging/me4000/Makefile b/drivers/staging/me4000/Makefile deleted file mode 100644 index 74487cd7bec..00000000000 --- a/drivers/staging/me4000/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_ME4000) += me4000.o diff --git a/drivers/staging/me4000/README b/drivers/staging/me4000/README deleted file mode 100644 index bbb83863220..00000000000 --- a/drivers/staging/me4000/README +++ /dev/null @@ -1,13 +0,0 @@ - -TODO: - - checkpatch.pl cleanups - - sparse cleanups - - possible /proc interaction cleanups - - more info needed for Kconfig entry - - real device id? - - module parameter cleanup - -Please send patches to Greg Kroah-Hartman -and Cc: Wolfgang Beiter and -Guenter Gebhardt - diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c deleted file mode 100644 index 01017b731d0..00000000000 --- a/drivers/staging/me4000/me4000.c +++ /dev/null @@ -1,6109 +0,0 @@ -/* Device driver for Meilhaus ME-4000 board family. - * ================================================ - * - * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Author: Guenter Gebhardt - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Include-File for the Meilhaus ME-4000 I/O board */ -#include "me4000.h" -#include "me4000_firmware.h" -#include "me4610_firmware.h" - -/* Administrative stuff for modinfo */ -MODULE_AUTHOR("Guenter Gebhardt "); -MODULE_DESCRIPTION - ("Device Driver Module for Meilhaus ME-4000 boards version 1.0.5"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-4000 Multi I/O boards"); -MODULE_LICENSE("GPL"); - -/* Board specific data are kept in a global list */ -static LIST_HEAD(me4000_board_info_list); - -/* Major Device Numbers. 0 means to get it automatically from the System */ -static int me4000_ao_major_driver_no; -static int me4000_ai_major_driver_no; -static int me4000_dio_major_driver_no; -static int me4000_cnt_major_driver_no; -static int me4000_ext_int_major_driver_no; - -/* Let the user specify a custom major driver number */ -module_param(me4000_ao_major_driver_no, int, 0); -MODULE_PARM_DESC(me4000_ao_major_driver_no, - "Major driver number for analog output (default 0)"); - -module_param(me4000_ai_major_driver_no, int, 0); -MODULE_PARM_DESC(me4000_ai_major_driver_no, - "Major driver number for analog input (default 0)"); - -module_param(me4000_dio_major_driver_no, int, 0); -MODULE_PARM_DESC(me4000_dio_major_driver_no, - "Major driver number digital I/O (default 0)"); - -module_param(me4000_cnt_major_driver_no, int, 0); -MODULE_PARM_DESC(me4000_cnt_major_driver_no, - "Major driver number for counter (default 0)"); - -module_param(me4000_ext_int_major_driver_no, int, 0); -MODULE_PARM_DESC(me4000_ext_int_major_driver_no, - "Major driver number for external interrupt (default 0)"); - -/*----------------------------------------------------------------------------- - Board detection and initialization - ---------------------------------------------------------------------------*/ -static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id); -static int me4000_xilinx_download(struct me4000_info *); -static int me4000_reset_board(struct me4000_info *); - -static void clear_board_info_list(void); -static void release_ao_contexts(struct me4000_info *board_info); -/*----------------------------------------------------------------------------- - Stuff used by all device parts - ---------------------------------------------------------------------------*/ -static int me4000_open(struct inode *, struct file *); -static int me4000_release(struct inode *, struct file *); - -static int me4000_get_user_info(struct me4000_user_info *, - struct me4000_info *board_info); -static int me4000_read_procmem(char *, char **, off_t, int, int *, void *); - -/*----------------------------------------------------------------------------- - Analog output stuff - ---------------------------------------------------------------------------*/ -static ssize_t me4000_ao_write_sing(struct file *, const char *, size_t, - loff_t *); -static ssize_t me4000_ao_write_wrap(struct file *, const char *, size_t, - loff_t *); -static ssize_t me4000_ao_write_cont(struct file *, const char *, size_t, - loff_t *); - -static int me4000_ao_ioctl_sing(struct inode *, struct file *, unsigned int, - unsigned long); -static int me4000_ao_ioctl_wrap(struct inode *, struct file *, unsigned int, - unsigned long); -static int me4000_ao_ioctl_cont(struct inode *, struct file *, unsigned int, - unsigned long); - -static unsigned int me4000_ao_poll_cont(struct file *, poll_table *); -static int me4000_ao_fsync_cont(struct file *, struct dentry *, int); - -static int me4000_ao_start(unsigned long *, struct me4000_ao_context *); -static int me4000_ao_stop(struct me4000_ao_context *); -static int me4000_ao_immediate_stop(struct me4000_ao_context *); -static int me4000_ao_timer_set_divisor(u32 *, struct me4000_ao_context *); -static int me4000_ao_preload(struct me4000_ao_context *); -static int me4000_ao_preload_update(struct me4000_ao_context *); -static int me4000_ao_ex_trig_set_edge(int *, struct me4000_ao_context *); -static int me4000_ao_ex_trig_enable(struct me4000_ao_context *); -static int me4000_ao_ex_trig_disable(struct me4000_ao_context *); -static int me4000_ao_prepare(struct me4000_ao_context *ao_info); -static int me4000_ao_reset(struct me4000_ao_context *ao_info); -static int me4000_ao_enable_do(struct me4000_ao_context *); -static int me4000_ao_disable_do(struct me4000_ao_context *); -static int me4000_ao_fsm_state(int *, struct me4000_ao_context *); - -static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context); -static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context); -static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context); -static int me4000_ao_simultaneous_update( - struct me4000_ao_channel_list *channels, - struct me4000_ao_context *ao_context); - -static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context); -static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context); -static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context); - -static int me4000_ao_ex_trig_timeout(unsigned long *arg, - struct me4000_ao_context *ao_context); -static int me4000_ao_get_free_buffer(unsigned long *arg, - struct me4000_ao_context *ao_context); - -/*----------------------------------------------------------------------------- - Analog input stuff - ---------------------------------------------------------------------------*/ -static int me4000_ai_single(struct me4000_ai_single *, - struct me4000_ai_context *); -static int me4000_ai_ioctl_sing(struct inode *, struct file *, unsigned int, - unsigned long); - -static ssize_t me4000_ai_read(struct file *, char *, size_t, loff_t *); -static int me4000_ai_ioctl_sw(struct inode *, struct file *, unsigned int, - unsigned long); -static unsigned int me4000_ai_poll(struct file *, poll_table *); -static int me4000_ai_fasync(int fd, struct file *file_p, int mode); - -static int me4000_ai_ioctl_ext(struct inode *, struct file *, unsigned int, - unsigned long); - -static int me4000_ai_prepare(struct me4000_ai_context *ai_context); -static int me4000_ai_reset(struct me4000_ai_context *ai_context); -static int me4000_ai_config(struct me4000_ai_config *, - struct me4000_ai_context *); -static int me4000_ai_start(struct me4000_ai_context *); -static int me4000_ai_start_ex(unsigned long *, struct me4000_ai_context *); -static int me4000_ai_stop(struct me4000_ai_context *); -static int me4000_ai_immediate_stop(struct me4000_ai_context *); -static int me4000_ai_ex_trig_enable(struct me4000_ai_context *); -static int me4000_ai_ex_trig_disable(struct me4000_ai_context *); -static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *, - struct me4000_ai_context *); -static int me4000_ai_sc_setup(struct me4000_ai_sc *arg, - struct me4000_ai_context *ai_context); -static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context); -static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context); -static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context); -static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context); -static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context); -static int me4000_ai_get_count_buffer(unsigned long *arg, - struct me4000_ai_context *ai_context); - -/*----------------------------------------------------------------------------- - EEPROM stuff - ---------------------------------------------------------------------------*/ -static int me4000_eeprom_read(struct me4000_eeprom *arg, - struct me4000_ai_context *ai_context); -static int me4000_eeprom_write(struct me4000_eeprom *arg, - struct me4000_ai_context *ai_context); - -/*----------------------------------------------------------------------------- - Digital I/O stuff - ---------------------------------------------------------------------------*/ -static int me4000_dio_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -static int me4000_dio_config(struct me4000_dio_config *, - struct me4000_dio_context *); -static int me4000_dio_get_byte(struct me4000_dio_byte *, - struct me4000_dio_context *); -static int me4000_dio_set_byte(struct me4000_dio_byte *, - struct me4000_dio_context *); -static int me4000_dio_reset(struct me4000_dio_context *); - -/*----------------------------------------------------------------------------- - Counter stuff - ---------------------------------------------------------------------------*/ -static int me4000_cnt_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -static int me4000_cnt_config(struct me4000_cnt_config *, - struct me4000_cnt_context *); -static int me4000_cnt_read(struct me4000_cnt *, struct me4000_cnt_context *); -static int me4000_cnt_write(struct me4000_cnt *, struct me4000_cnt_context *); -static int me4000_cnt_reset(struct me4000_cnt_context *); - -/*----------------------------------------------------------------------------- - External interrupt routines - ---------------------------------------------------------------------------*/ -static int me4000_ext_int_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -static int me4000_ext_int_enable(struct me4000_ext_int_context *); -static int me4000_ext_int_disable(struct me4000_ext_int_context *); -static int me4000_ext_int_count(unsigned long *arg, - struct me4000_ext_int_context *ext_int_context); -static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode); - -/*----------------------------------------------------------------------------- - The interrupt service routines - ---------------------------------------------------------------------------*/ -static irqreturn_t me4000_ao_isr(int, void *); -static irqreturn_t me4000_ai_isr(int, void *); -static irqreturn_t me4000_ext_int_isr(int, void *); - -/*----------------------------------------------------------------------------- - Inline functions - ---------------------------------------------------------------------------*/ - -static inline int me4000_buf_count(struct me4000_circ_buf buf, int size) -{ - return (buf.head - buf.tail) & (size - 1); -} - -static inline int me4000_buf_space(struct me4000_circ_buf buf, int size) -{ - return (buf.tail - (buf.head + 1)) & (size - 1); -} - -static inline int me4000_values_to_end(struct me4000_circ_buf buf, int size) -{ - int end; - int n; - end = size - buf.tail; - n = (buf.head + end) & (size - 1); - return (n < end) ? n : end; -} - -static inline int me4000_space_to_end(struct me4000_circ_buf buf, int size) -{ - int end; - int n; - - end = size - 1 - buf.head; - n = (end + buf.tail) & (size - 1); - return (n <= end) ? n : (end + 1); -} - -static inline void me4000_outb(unsigned char value, unsigned long port) -{ - PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port); - outb(value, port); -} - -static inline void me4000_outl(unsigned long value, unsigned long port) -{ - PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port); - outl(value, port); -} - -static inline unsigned long me4000_inl(unsigned long port) -{ - unsigned long value; - value = inl(port); - PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port); - return value; -} - -static inline unsigned char me4000_inb(unsigned long port) -{ - unsigned char value; - value = inb(port); - PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port); - return value; -} - -static struct pci_driver me4000_driver = { - .name = ME4000_NAME, - .id_table = me4000_pci_table, - .probe = me4000_probe -}; - -static const struct file_operations me4000_ao_fops_sing = { - .owner = THIS_MODULE, - .write = me4000_ao_write_sing, - .ioctl = me4000_ao_ioctl_sing, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ao_fops_wrap = { - .owner = THIS_MODULE, - .write = me4000_ao_write_wrap, - .ioctl = me4000_ao_ioctl_wrap, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ao_fops_cont = { - .owner = THIS_MODULE, - .write = me4000_ao_write_cont, - .poll = me4000_ao_poll_cont, - .ioctl = me4000_ao_ioctl_cont, - .open = me4000_open, - .release = me4000_release, - .fsync = me4000_ao_fsync_cont, -}; - -static const struct file_operations me4000_ai_fops_sing = { - .owner = THIS_MODULE, - .ioctl = me4000_ai_ioctl_sing, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ai_fops_cont_sw = { - .owner = THIS_MODULE, - .read = me4000_ai_read, - .poll = me4000_ai_poll, - .ioctl = me4000_ai_ioctl_sw, - .open = me4000_open, - .release = me4000_release, - .fasync = me4000_ai_fasync, -}; - -static const struct file_operations me4000_ai_fops_cont_et = { - .owner = THIS_MODULE, - .read = me4000_ai_read, - .poll = me4000_ai_poll, - .ioctl = me4000_ai_ioctl_ext, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ai_fops_cont_et_value = { - .owner = THIS_MODULE, - .read = me4000_ai_read, - .poll = me4000_ai_poll, - .ioctl = me4000_ai_ioctl_ext, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ai_fops_cont_et_chanlist = { - .owner = THIS_MODULE, - .read = me4000_ai_read, - .poll = me4000_ai_poll, - .ioctl = me4000_ai_ioctl_ext, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_dio_fops = { - .owner = THIS_MODULE, - .ioctl = me4000_dio_ioctl, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_cnt_fops = { - .owner = THIS_MODULE, - .ioctl = me4000_cnt_ioctl, - .open = me4000_open, - .release = me4000_release, -}; - -static const struct file_operations me4000_ext_int_fops = { - .owner = THIS_MODULE, - .ioctl = me4000_ext_int_ioctl, - .open = me4000_open, - .release = me4000_release, - .fasync = me4000_ext_int_fasync, -}; - -static const struct file_operations *me4000_ao_fops_array[] = { - /* single operations */ - &me4000_ao_fops_sing, - /* wraparound operations */ - &me4000_ao_fops_wrap, - /* continuous operations */ - &me4000_ao_fops_cont, -}; - -static const struct file_operations *me4000_ai_fops_array[] = { - /* single operations */ - &me4000_ai_fops_sing, - /* continuous operations with software start */ - &me4000_ai_fops_cont_sw, - /* continuous operations with external trigger */ - &me4000_ai_fops_cont_et, - /* sample values by external trigger */ - &me4000_ai_fops_cont_et_value, - /* work through one channel list by external trigger */ - &me4000_ai_fops_cont_et_chanlist, -}; - -static int __init me4000_init_module(void) -{ - int result; - - CALL_PDEBUG("init_module() is executed\n"); - - /* Register driver capabilities */ - result = pci_register_driver(&me4000_driver); - PDEBUG("init_module():%d devices detected\n", result); - if (result < 0) { - printk(KERN_ERR "ME4000:init_module():Can't register driver\n"); - goto INIT_ERROR_1; - } - - /* Allocate major number for analog output */ - result = - register_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME, - &me4000_ao_fops_sing); - if (result < 0) { - printk(KERN_ERR "ME4000:init_module():Can't get AO major no\n"); - goto INIT_ERROR_2; - } else { - me4000_ao_major_driver_no = result; - } - PDEBUG("init_module():Major driver number for AO = %ld\n", - me4000_ao_major_driver_no); - - /* Allocate major number for analog input */ - result = - register_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME, - &me4000_ai_fops_sing); - if (result < 0) { - printk(KERN_ERR "ME4000:init_module():Can't get AI major no\n"); - goto INIT_ERROR_3; - } else { - me4000_ai_major_driver_no = result; - } - PDEBUG("init_module():Major driver number for AI = %ld\n", - me4000_ai_major_driver_no); - - /* Allocate major number for digital I/O */ - result = - register_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME, - &me4000_dio_fops); - if (result < 0) { - printk(KERN_ERR - "ME4000:init_module():Can't get DIO major no\n"); - goto INIT_ERROR_4; - } else { - me4000_dio_major_driver_no = result; - } - PDEBUG("init_module():Major driver number for DIO = %ld\n", - me4000_dio_major_driver_no); - - /* Allocate major number for counter */ - result = - register_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME, - &me4000_cnt_fops); - if (result < 0) { - printk(KERN_ERR - "ME4000:init_module():Can't get CNT major no\n"); - goto INIT_ERROR_5; - } else { - me4000_cnt_major_driver_no = result; - } - PDEBUG("init_module():Major driver number for CNT = %ld\n", - me4000_cnt_major_driver_no); - - /* Allocate major number for external interrupt */ - result = - register_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME, - &me4000_ext_int_fops); - if (result < 0) { - printk(KERN_ERR - "ME4000:init_module():Can't get major no for external interrupt\n"); - goto INIT_ERROR_6; - } else { - me4000_ext_int_major_driver_no = result; - } - PDEBUG - ("init_module():Major driver number for external interrupt = %ld\n", - me4000_ext_int_major_driver_no); - - /* Create the /proc/me4000 entry */ - if (!create_proc_read_entry - ("me4000", 0, NULL, me4000_read_procmem, NULL)) { - result = -ENODEV; - printk(KERN_ERR - "ME4000:init_module():Can't create proc entry\n"); - goto INIT_ERROR_7; - } - - return 0; - -INIT_ERROR_7: - unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME); - -INIT_ERROR_6: - unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME); - -INIT_ERROR_5: - unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME); - -INIT_ERROR_4: - unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME); - -INIT_ERROR_3: - unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME); - -INIT_ERROR_2: - pci_unregister_driver(&me4000_driver); - clear_board_info_list(); - -INIT_ERROR_1: - return result; -} - -module_init(me4000_init_module); - -static void clear_board_info_list(void) -{ - struct me4000_info *board_info, *board_info_safe; - struct me4000_ao_context *ao_context, *ao_context_safe; - - /* Clear context lists */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - /* Clear analog output context list */ - list_for_each_entry_safe(ao_context, ao_context_safe, - &board_info->ao_context_list, list) { - me4000_ao_reset(ao_context); - free_irq(ao_context->irq, ao_context); - kfree(ao_context->circ_buf.buf); - list_del(&ao_context->list); - kfree(ao_context); - } - - /* Clear analog input context */ - kfree(board_info->ai_context->circ_buf.buf); - kfree(board_info->ai_context); - - /* Clear digital I/O context */ - kfree(board_info->dio_context); - - /* Clear counter context */ - kfree(board_info->cnt_context); - - /* Clear external interrupt context */ - kfree(board_info->ext_int_context); - } - - /* Clear the board info list */ - list_for_each_entry_safe(board_info, board_info_safe, - &me4000_board_info_list, list) { - pci_release_regions(board_info->pci_dev_p); - list_del(&board_info->list); - kfree(board_info); - } -} - -static int get_registers(struct pci_dev *dev, struct me4000_info *board_info) -{ - - /*--------------------------- plx regbase ---------------------------------*/ - - board_info->plx_regbase = pci_resource_start(dev, 1); - if (board_info->plx_regbase == 0) { - printk(KERN_ERR - "ME4000:get_registers():PCI base address 1 is not available\n"); - return -ENODEV; - } - board_info->plx_regbase_size = pci_resource_len(dev, 1); - - PDEBUG - ("get_registers():PLX configuration registers at address 0x%4lX [0x%4lX]\n", - board_info->plx_regbase, board_info->plx_regbase_size); - - /*--------------------------- me4000 regbase ------------------------------*/ - - board_info->me4000_regbase = pci_resource_start(dev, 2); - if (board_info->me4000_regbase == 0) { - printk(KERN_ERR - "ME4000:get_registers():PCI base address 2 is not available\n"); - return -ENODEV; - } - board_info->me4000_regbase_size = pci_resource_len(dev, 2); - - PDEBUG("get_registers():ME4000 registers at address 0x%4lX [0x%4lX]\n", - board_info->me4000_regbase, board_info->me4000_regbase_size); - - /*--------------------------- timer regbase ------------------------------*/ - - board_info->timer_regbase = pci_resource_start(dev, 3); - if (board_info->timer_regbase == 0) { - printk(KERN_ERR - "ME4000:get_registers():PCI base address 3 is not available\n"); - return -ENODEV; - } - board_info->timer_regbase_size = pci_resource_len(dev, 3); - - PDEBUG("get_registers():Timer registers at address 0x%4lX [0x%4lX]\n", - board_info->timer_regbase, board_info->timer_regbase_size); - - /*--------------------------- program regbase ------------------------------*/ - - board_info->program_regbase = pci_resource_start(dev, 5); - if (board_info->program_regbase == 0) { - printk(KERN_ERR - "get_registers():ME4000:PCI base address 5 is not available\n"); - return -ENODEV; - } - board_info->program_regbase_size = pci_resource_len(dev, 5); - - PDEBUG("get_registers():Program registers at address 0x%4lX [0x%4lX]\n", - board_info->program_regbase, board_info->program_regbase_size); - - return 0; -} - -static int init_board_info(struct pci_dev *pci_dev_p, - struct me4000_info *board_info) -{ - int i; - int result; - struct list_head *board_p; - board_info->pci_dev_p = pci_dev_p; - - for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) { - if (me4000_boards[i].device_id == pci_dev_p->device) { - board_info->board_p = &me4000_boards[i]; - break; - } - } - if (i == ARRAY_SIZE(me4000_boards)) { - printk(KERN_ERR - "ME4000:init_board_info():Device ID not valid\n"); - return -ENODEV; - } - - /* Get the index of the board in the global list */ - i = 0; - list_for_each(board_p, &me4000_board_info_list) { - if (board_p == &board_info->list) { - board_info->board_count = i; - break; - } - i++; - } - if (board_p == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:init_board_info():Cannot get index of board\n"); - return -ENODEV; - } - - /* Init list head for analog output contexts */ - INIT_LIST_HEAD(&board_info->ao_context_list); - - /* Init spin locks */ - spin_lock_init(&board_info->preload_lock); - spin_lock_init(&board_info->ai_ctrl_lock); - - /* Get the serial number */ - result = pci_read_config_dword(pci_dev_p, 0x2C, &board_info->serial_no); - if (result != PCIBIOS_SUCCESSFUL) { - printk(KERN_WARNING - "ME4000:init_board_info: Can't get serial_no\n"); - return result; - } - PDEBUG("init_board_info():serial_no = 0x%x\n", board_info->serial_no); - - /* Get the hardware revision */ - result = - pci_read_config_byte(pci_dev_p, 0x08, &board_info->hw_revision); - if (result != PCIBIOS_SUCCESSFUL) { - printk(KERN_WARNING - "ME4000:init_board_info():Can't get hw_revision\n"); - return result; - } - PDEBUG("init_board_info():hw_revision = 0x%x\n", - board_info->hw_revision); - - /* Get the vendor id */ - board_info->vendor_id = pci_dev_p->vendor; - PDEBUG("init_board_info():vendor_id = 0x%x\n", board_info->vendor_id); - - /* Get the device id */ - board_info->device_id = pci_dev_p->device; - PDEBUG("init_board_info():device_id = 0x%x\n", board_info->device_id); - - /* Get the pci device number */ - board_info->pci_dev_no = PCI_FUNC(pci_dev_p->devfn); - PDEBUG("init_board_info():pci_func_no = 0x%x\n", - board_info->pci_func_no); - - /* Get the pci slot number */ - board_info->pci_dev_no = PCI_SLOT(pci_dev_p->devfn); - PDEBUG("init_board_info():pci_dev_no = 0x%x\n", board_info->pci_dev_no); - - /* Get the pci bus number */ - board_info->pci_bus_no = pci_dev_p->bus->number; - PDEBUG("init_board_info():pci_bus_no = 0x%x\n", board_info->pci_bus_no); - - /* Get the irq assigned to the board */ - board_info->irq = pci_dev_p->irq; - PDEBUG("init_board_info():irq = %d\n", board_info->irq); - - return 0; -} - -static int alloc_ao_contexts(struct me4000_info *info) -{ - int i; - int err; - struct me4000_ao_context *ao_context; - - for (i = 0; i < info->board_p->ao.count; i++) { - ao_context = kzalloc(sizeof(struct me4000_ao_context), - GFP_KERNEL); - if (!ao_context) { - printk(KERN_ERR - "alloc_ao_contexts():Can't get memory for ao context\n"); - release_ao_contexts(info); - return -ENOMEM; - } - - spin_lock_init(&ao_context->use_lock); - spin_lock_init(&ao_context->int_lock); - ao_context->irq = info->irq; - init_waitqueue_head(&ao_context->wait_queue); - ao_context->board_info = info; - - if (info->board_p->ao.fifo_count) { - /* Allocate circular buffer */ - ao_context->circ_buf.buf = - kzalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL); - if (!ao_context->circ_buf.buf) { - printk(KERN_ERR - "alloc_ao_contexts():Can't get circular buffer\n"); - release_ao_contexts(info); - return -ENOMEM; - } - - /* Clear the circular buffer */ - ao_context->circ_buf.head = 0; - ao_context->circ_buf.tail = 0; - } - - switch (i) { - case 0: - ao_context->ctrl_reg = - info->me4000_regbase + ME4000_AO_00_CTRL_REG; - ao_context->status_reg = - info->me4000_regbase + ME4000_AO_00_STATUS_REG; - ao_context->fifo_reg = - info->me4000_regbase + ME4000_AO_00_FIFO_REG; - ao_context->single_reg = - info->me4000_regbase + ME4000_AO_00_SINGLE_REG; - ao_context->timer_reg = - info->me4000_regbase + ME4000_AO_00_TIMER_REG; - ao_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - ao_context->preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; - break; - case 1: - ao_context->ctrl_reg = - info->me4000_regbase + ME4000_AO_01_CTRL_REG; - ao_context->status_reg = - info->me4000_regbase + ME4000_AO_01_STATUS_REG; - ao_context->fifo_reg = - info->me4000_regbase + ME4000_AO_01_FIFO_REG; - ao_context->single_reg = - info->me4000_regbase + ME4000_AO_01_SINGLE_REG; - ao_context->timer_reg = - info->me4000_regbase + ME4000_AO_01_TIMER_REG; - ao_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - ao_context->preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; - break; - case 2: - ao_context->ctrl_reg = - info->me4000_regbase + ME4000_AO_02_CTRL_REG; - ao_context->status_reg = - info->me4000_regbase + ME4000_AO_02_STATUS_REG; - ao_context->fifo_reg = - info->me4000_regbase + ME4000_AO_02_FIFO_REG; - ao_context->single_reg = - info->me4000_regbase + ME4000_AO_02_SINGLE_REG; - ao_context->timer_reg = - info->me4000_regbase + ME4000_AO_02_TIMER_REG; - ao_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - ao_context->preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; - break; - case 3: - ao_context->ctrl_reg = - info->me4000_regbase + ME4000_AO_03_CTRL_REG; - ao_context->status_reg = - info->me4000_regbase + ME4000_AO_03_STATUS_REG; - ao_context->fifo_reg = - info->me4000_regbase + ME4000_AO_03_FIFO_REG; - ao_context->single_reg = - info->me4000_regbase + ME4000_AO_03_SINGLE_REG; - ao_context->timer_reg = - info->me4000_regbase + ME4000_AO_03_TIMER_REG; - ao_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - ao_context->preload_reg = - info->me4000_regbase + ME4000_AO_LOADSETREG_XX; - break; - default: - break; - } - - if (info->board_p->ao.fifo_count) { - /* Request the interrupt line */ - err = - request_irq(ao_context->irq, me4000_ao_isr, - IRQF_DISABLED | IRQF_SHARED, - ME4000_NAME, ao_context); - if (err) { - printk(KERN_ERR - "%s:Can't get interrupt line", __func__); - kfree(ao_context->circ_buf.buf); - kfree(ao_context); - release_ao_contexts(info); - return -ENODEV; - } - } - - list_add_tail(&ao_context->list, &info->ao_context_list); - ao_context->index = i; - } - - return 0; -} - -static void release_ao_contexts(struct me4000_info *board_info) -{ - struct me4000_ao_context *ao_context, *ao_context_safe; - - /* Clear analog output context list */ - list_for_each_entry_safe(ao_context, ao_context_safe, - &board_info->ao_context_list, list) { - free_irq(ao_context->irq, ao_context); - kfree(ao_context->circ_buf.buf); - list_del(&ao_context->list); - kfree(ao_context); - } -} - -static int alloc_ai_context(struct me4000_info *info) -{ - struct me4000_ai_context *ai_context; - - if (info->board_p->ai.count) { - ai_context = kzalloc(sizeof(struct me4000_ai_context), - GFP_KERNEL); - if (!ai_context) { - printk(KERN_ERR - "ME4000:alloc_ai_context():Can't get memory for ai context\n"); - return -ENOMEM; - } - - info->ai_context = ai_context; - - spin_lock_init(&ai_context->use_lock); - spin_lock_init(&ai_context->int_lock); - ai_context->number = 0; - ai_context->irq = info->irq; - init_waitqueue_head(&ai_context->wait_queue); - ai_context->board_info = info; - - ai_context->ctrl_reg = - info->me4000_regbase + ME4000_AI_CTRL_REG; - ai_context->status_reg = - info->me4000_regbase + ME4000_AI_STATUS_REG; - ai_context->channel_list_reg = - info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG; - ai_context->data_reg = - info->me4000_regbase + ME4000_AI_DATA_REG; - ai_context->chan_timer_reg = - info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG; - ai_context->chan_pre_timer_reg = - info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG; - ai_context->scan_timer_low_reg = - info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG; - ai_context->scan_timer_high_reg = - info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG; - ai_context->scan_pre_timer_low_reg = - info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG; - ai_context->scan_pre_timer_high_reg = - info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG; - ai_context->start_reg = - info->me4000_regbase + ME4000_AI_START_REG; - ai_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - ai_context->sample_counter_reg = - info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG; - } - - return 0; -} - -static int alloc_dio_context(struct me4000_info *info) -{ - struct me4000_dio_context *dio_context; - - if (info->board_p->dio.count) { - dio_context = kzalloc(sizeof(struct me4000_dio_context), - GFP_KERNEL); - if (!dio_context) { - printk(KERN_ERR - "ME4000:alloc_dio_context():Can't get memory for dio context\n"); - return -ENOMEM; - } - - info->dio_context = dio_context; - - spin_lock_init(&dio_context->use_lock); - dio_context->board_info = info; - - dio_context->dio_count = info->board_p->dio.count; - - dio_context->dir_reg = - info->me4000_regbase + ME4000_DIO_DIR_REG; - dio_context->ctrl_reg = - info->me4000_regbase + ME4000_DIO_CTRL_REG; - dio_context->port_0_reg = - info->me4000_regbase + ME4000_DIO_PORT_0_REG; - dio_context->port_1_reg = - info->me4000_regbase + ME4000_DIO_PORT_1_REG; - dio_context->port_2_reg = - info->me4000_regbase + ME4000_DIO_PORT_2_REG; - dio_context->port_3_reg = - info->me4000_regbase + ME4000_DIO_PORT_3_REG; - } - - return 0; -} - -static int alloc_cnt_context(struct me4000_info *info) -{ - struct me4000_cnt_context *cnt_context; - - if (info->board_p->cnt.count) { - cnt_context = kzalloc(sizeof(struct me4000_cnt_context), - GFP_KERNEL); - if (!cnt_context) { - printk(KERN_ERR - "ME4000:alloc_cnt_context():Can't get memory for cnt context\n"); - return -ENOMEM; - } - - info->cnt_context = cnt_context; - - spin_lock_init(&cnt_context->use_lock); - cnt_context->board_info = info; - - cnt_context->ctrl_reg = - info->timer_regbase + ME4000_CNT_CTRL_REG; - cnt_context->counter_0_reg = - info->timer_regbase + ME4000_CNT_COUNTER_0_REG; - cnt_context->counter_1_reg = - info->timer_regbase + ME4000_CNT_COUNTER_1_REG; - cnt_context->counter_2_reg = - info->timer_regbase + ME4000_CNT_COUNTER_2_REG; - } - - return 0; -} - -static int alloc_ext_int_context(struct me4000_info *info) -{ - struct me4000_ext_int_context *ext_int_context; - - if (info->board_p->cnt.count) { - ext_int_context = - kzalloc(sizeof(struct me4000_ext_int_context), GFP_KERNEL); - if (!ext_int_context) { - printk(KERN_ERR - "ME4000:alloc_ext_int_context():Can't get memory for cnt context\n"); - return -ENOMEM; - } - - info->ext_int_context = ext_int_context; - - spin_lock_init(&ext_int_context->use_lock); - ext_int_context->board_info = info; - - ext_int_context->fasync_ptr = NULL; - ext_int_context->irq = info->irq; - - ext_int_context->ctrl_reg = - info->me4000_regbase + ME4000_AI_CTRL_REG; - ext_int_context->irq_status_reg = - info->me4000_regbase + ME4000_IRQ_STATUS_REG; - } - - return 0; -} - -static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int result = 0; - struct me4000_info *board_info; - - CALL_PDEBUG("me4000_probe() is executed\n"); - - /* Allocate structure for board context */ - board_info = kzalloc(sizeof(struct me4000_info), GFP_KERNEL); - if (!board_info) { - printk(KERN_ERR - "ME4000:Can't get memory for board info structure\n"); - result = -ENOMEM; - goto PROBE_ERROR_1; - } - - /* Add to global linked list */ - list_add_tail(&board_info->list, &me4000_board_info_list); - - /* Get the PCI base registers */ - result = get_registers(dev, board_info); - if (result) { - printk(KERN_ERR "%s:Cannot get registers\n", __func__); - goto PROBE_ERROR_2; - } - - /* Enable the device */ - result = pci_enable_device(dev); - if (result < 0) { - printk(KERN_ERR "%s:Cannot enable PCI device\n", __func__); - goto PROBE_ERROR_2; - } - - /* Request the PCI register regions */ - result = pci_request_regions(dev, ME4000_NAME); - if (result < 0) { - printk(KERN_ERR "%s:Cannot request I/O regions\n", __func__); - goto PROBE_ERROR_2; - } - - /* Initialize board info */ - result = init_board_info(dev, board_info); - if (result) { - printk(KERN_ERR "%s:Cannot init baord info\n", __func__); - goto PROBE_ERROR_3; - } - - /* Download the xilinx firmware */ - result = me4000_xilinx_download(board_info); - if (result) { - printk(KERN_ERR "%s:Can't download firmware\n", __func__); - goto PROBE_ERROR_3; - } - - /* Make a hardware reset */ - result = me4000_reset_board(board_info); - if (result) { - printk(KERN_ERR "%s :Can't reset board\n", __func__); - goto PROBE_ERROR_3; - } - - /* Allocate analog output context structures */ - result = alloc_ao_contexts(board_info); - if (result) { - printk(KERN_ERR "%s:Cannot allocate ao contexts\n", __func__); - goto PROBE_ERROR_3; - } - - /* Allocate analog input context */ - result = alloc_ai_context(board_info); - if (result) { - printk(KERN_ERR "%s:Cannot allocate ai context\n", __func__); - goto PROBE_ERROR_4; - } - - /* Allocate digital I/O context */ - result = alloc_dio_context(board_info); - if (result) { - printk(KERN_ERR "%s:Cannot allocate dio context\n", __func__); - goto PROBE_ERROR_5; - } - - /* Allocate counter context */ - result = alloc_cnt_context(board_info); - if (result) { - printk(KERN_ERR "%s:Cannot allocate cnt context\n", __func__); - goto PROBE_ERROR_6; - } - - /* Allocate external interrupt context */ - result = alloc_ext_int_context(board_info); - if (result) { - printk(KERN_ERR - "%s:Cannot allocate ext_int context\n", __func__); - goto PROBE_ERROR_7; - } - - return 0; - -PROBE_ERROR_7: - kfree(board_info->cnt_context); - -PROBE_ERROR_6: - kfree(board_info->dio_context); - -PROBE_ERROR_5: - kfree(board_info->ai_context); - -PROBE_ERROR_4: - release_ao_contexts(board_info); - -PROBE_ERROR_3: - pci_release_regions(dev); - -PROBE_ERROR_2: - list_del(&board_info->list); - kfree(board_info); - -PROBE_ERROR_1: - return result; -} - -static int me4000_xilinx_download(struct me4000_info *info) -{ - int size = 0; - u32 value = 0; - int idx = 0; - unsigned char *firm; - wait_queue_head_t queue; - - CALL_PDEBUG("me4000_xilinx_download() is executed\n"); - - init_waitqueue_head(&queue); - - firm = (info->device_id == 0x4610) ? xilinx_firm_4610 : xilinx_firm; - - /* - * Set PLX local interrupt 2 polarity to high. - * Interrupt is thrown by init pin of xilinx. - */ - outl(0x10, info->plx_regbase + PLX_INTCSR); - - /* Set /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX_ICR); - value |= 0x100; - outl(value, info->plx_regbase + PLX_ICR); - - /* Init Xilinx with CS1 */ - inb(info->program_regbase + 0xC8); - - /* Wait until /INIT pin is set */ - udelay(20); - if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) { - printk(KERN_ERR "%s:Can't init Xilinx\n", __func__); - return -EIO; - } - - /* Reset /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX_ICR); - value &= ~0x100; - outl(value, info->plx_regbase + PLX_ICR); - - /* Download Xilinx firmware */ - size = (firm[0] << 24) + (firm[1] << 16) + (firm[2] << 8) + firm[3]; - udelay(10); - - for (idx = 0; idx < size; idx++) { - outb(firm[16 + idx], info->program_regbase); - - udelay(10); - - /* Check if BUSY flag is low */ - if (inl(info->plx_regbase + PLX_ICR) & 0x20) { - printk(KERN_ERR - "%s:Xilinx is still busy (idx = %d)\n", __func__, - idx); - return -EIO; - } - } - - PDEBUG("me4000_xilinx_download():%d bytes written\n", idx); - - /* If done flag is high download was successful */ - if (inl(info->plx_regbase + PLX_ICR) & 0x4) { - PDEBUG("me4000_xilinx_download():Done flag is set\n"); - PDEBUG("me4000_xilinx_download():Download was successful\n"); - } else { - printk(KERN_ERR - "ME4000:%s:DONE flag is not set\n", __func__); - printk(KERN_ERR - "ME4000:%s:Download not succesful\n", __func__); - return -EIO; - } - - /* Set /CS and /WRITE */ - value = inl(info->plx_regbase + PLX_ICR); - value |= 0x100; - outl(value, info->plx_regbase + PLX_ICR); - - return 0; -} - -static int me4000_reset_board(struct me4000_info *info) -{ - unsigned long icr; - - CALL_PDEBUG("me4000_reset_board() is executed\n"); - - /* Make a hardware reset */ - icr = me4000_inl(info->plx_regbase + PLX_ICR); - icr |= 0x40000000; - me4000_outl(icr, info->plx_regbase + PLX_ICR); - icr &= ~0x40000000; - me4000_outl(icr, info->plx_regbase + PLX_ICR); - - /* Set both stop bits in the analog input control register */ - me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AI_CTRL_REG); - - /* Set both stop bits in the analog output control register */ - me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_00_CTRL_REG); - me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_01_CTRL_REG); - me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_02_CTRL_REG); - me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP, - info->me4000_regbase + ME4000_AO_03_CTRL_REG); - - /* 0x8000 to the DACs means an output voltage of 0V */ - me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG); - me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG); - me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG); - me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG); - - /* Enable interrupts on the PLX */ - me4000_outl(0x43, info->plx_regbase + PLX_INTCSR); - - /* Set the adustment register for AO demux */ - me4000_outl(ME4000_AO_DEMUX_ADJUST_VALUE, - info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG); - - /* Set digital I/O direction for port 0 to output on isolated versions */ - if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) - me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG); - - return 0; -} - -static int me4000_open(struct inode *inode_p, struct file *file_p) -{ - int board, dev, mode; - int err = 0; - int i; - struct list_head *ptr; - struct me4000_info *board_info = NULL; - struct me4000_ao_context *ao_context = NULL; - struct me4000_ai_context *ai_context = NULL; - struct me4000_dio_context *dio_context = NULL; - struct me4000_cnt_context *cnt_context = NULL; - struct me4000_ext_int_context *ext_int_context = NULL; - - CALL_PDEBUG("me4000_open() is executed\n"); - - /* Analog output */ - if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) { - board = AO_BOARD(inode_p->i_rdev); - dev = AO_PORT(inode_p->i_rdev); - mode = AO_MODE(inode_p->i_rdev); - - PDEBUG("me4000_open():board = %d ao = %d mode = %d\n", board, - dev, mode); - - /* Search for the board context */ - i = 0; - list_for_each(ptr, &me4000_board_info_list) { - if (i == board) - break; - i++; - } - board_info = list_entry(ptr, struct me4000_info, list); - - if (ptr == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:me4000_open():Board %d not in device list\n", - board); - return -ENODEV; - } - - /* Search for the dac context */ - i = 0; - list_for_each(ptr, &board_info->ao_context_list) { - if (i == dev) - break; - i++; - } - ao_context = list_entry(ptr, struct me4000_ao_context, list); - - if (ptr == &board_info->ao_context_list) { - printk(KERN_ERR - "ME4000:me4000_open():Device %d not in device list\n", - dev); - return -ENODEV; - } - - /* Check if mode is valid */ - if (mode > 2) { - printk(KERN_ERR - "ME4000:me4000_open():Mode is not valid\n"); - return -ENODEV; - } - - /* Check if mode is valid for this AO */ - if ((mode != ME4000_AO_CONV_MODE_SINGLE) - && (dev >= board_info->board_p->ao.fifo_count)) { - printk(KERN_ERR - "ME4000:me4000_open():AO %d only in single mode available\n", - dev); - return -ENODEV; - } - - /* Check if already opened */ - spin_lock(&ao_context->use_lock); - if (ao_context->dac_in_use) { - printk(KERN_ERR - "ME4000:me4000_open():AO %d already in use\n", - dev); - spin_unlock(&ao_context->use_lock); - return -EBUSY; - } - ao_context->dac_in_use = 1; - spin_unlock(&ao_context->use_lock); - - ao_context->mode = mode; - - /* Hold the context in private data */ - file_p->private_data = ao_context; - - /* Set file operations pointer */ - file_p->f_op = me4000_ao_fops_array[mode]; - - err = me4000_ao_prepare(ao_context); - if (err) { - ao_context->dac_in_use = 0; - return 1; - } - } - /* Analog input */ - else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) { - board = AI_BOARD(inode_p->i_rdev); - mode = AI_MODE(inode_p->i_rdev); - - PDEBUG("me4000_open():ai board = %d mode = %d\n", board, mode); - - /* Search for the board context */ - i = 0; - list_for_each(ptr, &me4000_board_info_list) { - if (i == board) - break; - i++; - } - board_info = list_entry(ptr, struct me4000_info, list); - - if (ptr == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:me4000_open():Board %d not in device list\n", - board); - return -ENODEV; - } - - ai_context = board_info->ai_context; - - /* Check if mode is valid */ - if (mode > 5) { - printk(KERN_ERR - "ME4000:me4000_open():Mode is not valid\n"); - return -EINVAL; - } - - /* Check if already opened */ - spin_lock(&ai_context->use_lock); - if (ai_context->in_use) { - printk(KERN_ERR - "ME4000:me4000_open():AI already in use\n"); - spin_unlock(&ai_context->use_lock); - return -EBUSY; - } - ai_context->in_use = 1; - spin_unlock(&ai_context->use_lock); - - ai_context->mode = mode; - - /* Hold the context in private data */ - file_p->private_data = ai_context; - - /* Set file operations pointer */ - file_p->f_op = me4000_ai_fops_array[mode]; - - /* Prepare analog input */ - me4000_ai_prepare(ai_context); - } - /* Digital I/O */ - else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) { - board = DIO_BOARD(inode_p->i_rdev); - dev = 0; - mode = 0; - - PDEBUG("me4000_open():board = %d\n", board); - - /* Search for the board context */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - if (board_info->board_count == board) - break; - } - - if (&board_info->list == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:me4000_open():Board %d not in device list\n", - board); - return -ENODEV; - } - - /* Search for the dio context */ - dio_context = board_info->dio_context; - - /* Check if already opened */ - spin_lock(&dio_context->use_lock); - if (dio_context->in_use) { - printk(KERN_ERR - "ME4000:me4000_open():DIO already in use\n"); - spin_unlock(&dio_context->use_lock); - return -EBUSY; - } - dio_context->in_use = 1; - spin_unlock(&dio_context->use_lock); - - /* Hold the context in private data */ - file_p->private_data = dio_context; - - /* Set file operations pointer to single functions */ - file_p->f_op = &me4000_dio_fops; - - /* me4000_dio_reset(dio_context); */ - } - /* Counters */ - else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) { - board = CNT_BOARD(inode_p->i_rdev); - dev = 0; - mode = 0; - - PDEBUG("me4000_open():board = %d\n", board); - - /* Search for the board context */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - if (board_info->board_count == board) - break; - } - - if (&board_info->list == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:me4000_open():Board %d not in device list\n", - board); - return -ENODEV; - } - - /* Get the cnt context */ - cnt_context = board_info->cnt_context; - - /* Check if already opened */ - spin_lock(&cnt_context->use_lock); - if (cnt_context->in_use) { - printk(KERN_ERR - "ME4000:me4000_open():CNT already in use\n"); - spin_unlock(&cnt_context->use_lock); - return -EBUSY; - } - cnt_context->in_use = 1; - spin_unlock(&cnt_context->use_lock); - - /* Hold the context in private data */ - file_p->private_data = cnt_context; - - /* Set file operations pointer to single functions */ - file_p->f_op = &me4000_cnt_fops; - } - /* External Interrupt */ - else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) { - board = EXT_INT_BOARD(inode_p->i_rdev); - dev = 0; - mode = 0; - - PDEBUG("me4000_open():board = %d\n", board); - - /* Search for the board context */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - if (board_info->board_count == board) - break; - } - - if (&board_info->list == &me4000_board_info_list) { - printk(KERN_ERR - "ME4000:me4000_open():Board %d not in device list\n", - board); - return -ENODEV; - } - - /* Get the external interrupt context */ - ext_int_context = board_info->ext_int_context; - - /* Check if already opened */ - spin_lock(&cnt_context->use_lock); - if (ext_int_context->in_use) { - printk(KERN_ERR - "ME4000:me4000_open():External interrupt already in use\n"); - spin_unlock(&ext_int_context->use_lock); - return -EBUSY; - } - ext_int_context->in_use = 1; - spin_unlock(&ext_int_context->use_lock); - - /* Hold the context in private data */ - file_p->private_data = ext_int_context; - - /* Set file operations pointer to single functions */ - file_p->f_op = &me4000_ext_int_fops; - - /* Request the interrupt line */ - err = - request_irq(ext_int_context->irq, me4000_ext_int_isr, - IRQF_DISABLED | IRQF_SHARED, ME4000_NAME, - ext_int_context); - if (err) { - printk(KERN_ERR - "ME4000:me4000_open():Can't get interrupt line"); - ext_int_context->in_use = 0; - return -ENODEV; - } - - /* Reset the counter */ - me4000_ext_int_disable(ext_int_context); - } else { - printk(KERN_ERR "ME4000:me4000_open():Major number unknown\n"); - return -EINVAL; - } - - return 0; -} - -static int me4000_release(struct inode *inode_p, struct file *file_p) -{ - struct me4000_ao_context *ao_context; - struct me4000_ai_context *ai_context; - struct me4000_dio_context *dio_context; - struct me4000_cnt_context *cnt_context; - struct me4000_ext_int_context *ext_int_context; - - CALL_PDEBUG("me4000_release() is executed\n"); - - if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) { - ao_context = file_p->private_data; - - /* Mark DAC as unused */ - ao_context->dac_in_use = 0; - } else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) { - ai_context = file_p->private_data; - - /* Reset the analog input */ - me4000_ai_reset(ai_context); - - /* Free the interrupt and the circular buffer */ - if (ai_context->mode) { - free_irq(ai_context->irq, ai_context); - kfree(ai_context->circ_buf.buf); - ai_context->circ_buf.buf = NULL; - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - } - - /* Mark AI as unused */ - ai_context->in_use = 0; - } else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) { - dio_context = file_p->private_data; - - /* Mark digital I/O as unused */ - dio_context->in_use = 0; - } else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) { - cnt_context = file_p->private_data; - - /* Mark counters as unused */ - cnt_context->in_use = 0; - } else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) { - ext_int_context = file_p->private_data; - - /* Disable the externel interrupt */ - me4000_ext_int_disable(ext_int_context); - - free_irq(ext_int_context->irq, ext_int_context); - - /* Mark as unused */ - ext_int_context->in_use = 0; - } else { - printk(KERN_ERR - "ME4000:me4000_release():Major number unknown\n"); - return -EINVAL; - } - - return 0; -} - -/*------------------------------- Analog output stuff --------------------------------------*/ - -static int me4000_ao_prepare(struct me4000_ao_context *ao_context) -{ - unsigned long flags; - - CALL_PDEBUG("me4000_ao_prepare() is executed\n"); - - if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) { - /* Only do anything if not already in the correct mode */ - unsigned long mode = me4000_inl(ao_context->ctrl_reg); - if ((mode & ME4000_AO_CONV_MODE_CONTINUOUS) - && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) { - return 0; - } - - /* Stop any conversion */ - me4000_ao_immediate_stop(ao_context); - - /* Set the control register to default state */ - spin_lock_irqsave(&ao_context->int_lock, flags); - me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS | - ME4000_AO_CTRL_BIT_ENABLE_FIFO | - ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP, - ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - /* Set to fastest sample rate */ - me4000_outl(65, ao_context->timer_reg); - } else if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) { - /* Only do anything if not already in the correct mode */ - unsigned long mode = me4000_inl(ao_context->ctrl_reg); - if ((mode & ME4000_AO_CONV_MODE_WRAPAROUND) - && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) { - return 0; - } - - /* Stop any conversion */ - me4000_ao_immediate_stop(ao_context); - - /* Set the control register to default state */ - spin_lock_irqsave(&ao_context->int_lock, flags); - me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND | - ME4000_AO_CTRL_BIT_ENABLE_FIFO | - ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP, - ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - /* Set to fastest sample rate */ - me4000_outl(65, ao_context->timer_reg); - } else if (ao_context->mode == ME4000_AO_CONV_MODE_SINGLE) { - /* Only do anything if not already in the correct mode */ - unsigned long mode = me4000_inl(ao_context->ctrl_reg); - if (! - (mode & - (ME4000_AO_CONV_MODE_WRAPAROUND | - ME4000_AO_CONV_MODE_CONTINUOUS))) { - return 0; - } - - /* Stop any conversion */ - me4000_ao_immediate_stop(ao_context); - - /* Clear the control register */ - spin_lock_irqsave(&ao_context->int_lock, flags); - me4000_outl(0x0, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - /* Set voltage to 0V */ - me4000_outl(0x8000, ao_context->single_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_ao_prepare():Invalid mode specified\n"); - return -EINVAL; - } - - return 0; -} - -static int me4000_ao_reset(struct me4000_ao_context *ao_context) -{ - u32 tmp; - wait_queue_head_t queue; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_reset() is executed\n"); - - init_waitqueue_head(&queue); - - if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) { - /* - * First stop conversion of the DAC before reconfigure. - * This is essantial, cause of the state machine. - * If not stopped before configuring mode, it could - * walk in a undefined state. - */ - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; - me4000_outl(tmp, ao_context->ctrl_reg); - - wait_event_timeout(queue, - (inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM) == 0, - 1); - - /* Set to transparent mode */ - me4000_ao_simultaneous_disable(ao_context); - - /* Set to single mode in order to set default voltage */ - me4000_outl(0x0, ao_context->ctrl_reg); - - /* Set voltage to 0V */ - me4000_outl(0x8000, ao_context->single_reg); - - /* Set to fastest sample rate */ - me4000_outl(65, ao_context->timer_reg); - - /* Set the original mode and enable FIFO */ - me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND | - ME4000_AO_CTRL_BIT_ENABLE_FIFO | - ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP, - ao_context->ctrl_reg); - } else if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) { - /* - * First stop conversion of the DAC before reconfigure. - * This is essantial, cause of the state machine. - * If not stopped before configuring mode, it could - * walk in a undefined state. - */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_STOP; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - wait_event_timeout(queue, - (inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM) == 0, - 1); - - /* Clear the circular buffer */ - ao_context->circ_buf.head = 0; - ao_context->circ_buf.tail = 0; - - /* Set to transparent mode */ - me4000_ao_simultaneous_disable(ao_context); - - /* Set to single mode in order to set default voltage */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - me4000_outl(0x0, ao_context->ctrl_reg); - - /* Set voltage to 0V */ - me4000_outl(0x8000, ao_context->single_reg); - - /* Set to fastest sample rate */ - me4000_outl(65, ao_context->timer_reg); - - /* Set the original mode and enable FIFO */ - me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS | - ME4000_AO_CTRL_BIT_ENABLE_FIFO | - ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP, - ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } else { - /* Set to transparent mode */ - me4000_ao_simultaneous_disable(ao_context); - - /* Set voltage to 0V */ - me4000_outl(0x8000, ao_context->single_reg); - } - - return 0; -} - -static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff, - size_t cnt, loff_t *offp) -{ - struct me4000_ao_context *ao_context = filep->private_data; - u32 value; - const u16 *buffer = (const u16 *)buff; - - CALL_PDEBUG("me4000_ao_write_sing() is executed\n"); - - if (cnt != 2) { - printk(KERN_ERR - "%s:Write count is not 2\n", __func__); - return -EINVAL; - } - - if (get_user(value, buffer)) { - printk(KERN_ERR - "%s:Cannot copy data from user\n", __func__); - return -EFAULT; - } - - me4000_outl(value, ao_context->single_reg); - - return 2; -} - -static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff, - size_t cnt, loff_t *offp) -{ - struct me4000_ao_context *ao_context = filep->private_data; - size_t i; - u32 value; - u32 tmp; - const u16 *buffer = (const u16 *)buff; - size_t count = cnt / 2; - - CALL_PDEBUG("me4000_ao_write_wrap() is executed\n"); - - /* Check if a conversion is already running */ - if (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "%s:There is already a conversion running\n", __func__); - return -EBUSY; - } - - if (count > ME4000_AO_FIFO_COUNT) { - printk(KERN_ERR - "%s:Can't load more than %d values\n", __func__, - ME4000_AO_FIFO_COUNT); - return -ENOSPC; - } - - /* Reset the FIFO */ - tmp = inl(ao_context->ctrl_reg); - tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_FIFO; - outl(tmp, ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO; - outl(tmp, ao_context->ctrl_reg); - - for (i = 0; i < count; i++) { - if (get_user(value, buffer + i)) { - printk(KERN_ERR - "%s:Cannot copy data from user\n", __func__); - return -EFAULT; - } - if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) - || ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) - value = value << 16; - outl(value, ao_context->fifo_reg); - } - CALL_PDEBUG("me4000_ao_write_wrap() is leaved with %d\n", i * 2); - - return i * 2; -} - -static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff, - size_t cnt, loff_t *offp) -{ - struct me4000_ao_context *ao_context = filep->private_data; - const u16 *buffer = (const u16 *)buff; - size_t count = cnt / 2; - unsigned long flags; - u32 tmp; - int c = 0; - int k = 0; - int ret = 0; - u16 svalue; - u32 lvalue; - int i; - wait_queue_head_t queue; - - CALL_PDEBUG("me4000_ao_write_cont() is executed\n"); - - init_waitqueue_head(&queue); - - /* Check count */ - if (count <= 0) { - PDEBUG("me4000_ao_write_cont():Count is 0\n"); - return 0; - } - - if (filep->f_flags & O_APPEND) { - PDEBUG("me4000_ao_write_cont():Append data to data stream\n"); - while (count > 0) { - if (filep->f_flags & O_NONBLOCK) { - if (ao_context->pipe_flag) { - printk(KERN_ERR - "ME4000:me4000_ao_write_cont():Broken pipe in nonblocking write\n"); - return -EPIPE; - } - c = me4000_space_to_end(ao_context->circ_buf, - ME4000_AO_BUFFER_COUNT); - if (!c) { - PDEBUG - ("me4000_ao_write_cont():Returning from nonblocking write\n"); - break; - } - } else { - wait_event_interruptible(ao_context->wait_queue, - (c = - me4000_space_to_end - (ao_context->circ_buf, - ME4000_AO_BUFFER_COUNT))); - if (ao_context->pipe_flag) { - printk(KERN_ERR - "me4000_ao_write_cont():Broken pipe in blocking write\n"); - return -EPIPE; - } - if (signal_pending(current)) { - printk(KERN_ERR - "me4000_ao_write_cont():Wait for free buffer interrupted from signal\n"); - return -EINTR; - } - } - - PDEBUG("me4000_ao_write_cont():Space to end = %d\n", c); - - /* Only able to write size of free buffer or size of count */ - if (count < c) - c = count; - - k = 2 * c; - k -= copy_from_user(ao_context->circ_buf.buf + - ao_context->circ_buf.head, buffer, - k); - c = k / 2; - PDEBUG - ("me4000_ao_write_cont():Copy %d values from user space\n", - c); - - if (!c) - return -EFAULT; - - ao_context->circ_buf.head = - (ao_context->circ_buf.head + - c) & (ME4000_AO_BUFFER_COUNT - 1); - buffer += c; - count -= c; - ret += c; - - /* Values are now available so enable interrupts */ - spin_lock_irqsave(&ao_context->int_lock, flags); - if (me4000_buf_count - (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) { - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ; - me4000_outl(tmp, ao_context->ctrl_reg); - } - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } - - /* Wait until the state machine is stopped if O_SYNC is set */ - if (filep->f_flags & O_SYNC) { - while (inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (ao_context->pipe_flag) { - PDEBUG - ("me4000_ao_write_cont():Broken pipe detected after sync\n"); - return -EPIPE; - } - if (signal_pending(current)) { - printk(KERN_ERR - "me4000_ao_write_cont():Wait on state machine after sync interrupted\n"); - return -EINTR; - } - } - } - } else { - PDEBUG("me4000_ao_write_cont():Preload DAC FIFO\n"); - if ((me4000_inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM)) { - printk(KERN_ERR - "me4000_ao_write_cont():Can't Preload DAC FIFO while conversion is running\n"); - return -EBUSY; - } - - /* Clear the FIFO */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp &= - ~(ME4000_AO_CTRL_BIT_ENABLE_FIFO | - ME4000_AO_CTRL_BIT_ENABLE_IRQ); - me4000_outl(tmp, ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - /* Clear the circular buffer */ - ao_context->circ_buf.head = 0; - ao_context->circ_buf.tail = 0; - - /* Reset the broken pipe flag */ - ao_context->pipe_flag = 0; - - /* Only able to write size of fifo or count */ - c = ME4000_AO_FIFO_COUNT; - if (count < c) - c = count; - - PDEBUG - ("me4000_ao_write_cont():Write %d values to DAC on 0x%lX\n", - c, ao_context->fifo_reg); - - /* Write values to the fifo */ - for (i = 0; i < c; i++) { - if (get_user(svalue, buffer)) - return -EFAULT; - - if (((ao_context->fifo_reg & 0xFF) == - ME4000_AO_01_FIFO_REG) - || ((ao_context->fifo_reg & 0xFF) == - ME4000_AO_03_FIFO_REG)) { - lvalue = ((u32) svalue) << 16; - } else - lvalue = (u32) svalue; - - outl(lvalue, ao_context->fifo_reg); - buffer++; - } - count -= c; - ret += c; - - while (1) { - /* Get free buffer */ - c = me4000_space_to_end(ao_context->circ_buf, - ME4000_AO_BUFFER_COUNT); - - if (c == 0) - return 2 * ret; - - /* Only able to write size of free buffer or size of count */ - if (count < c) - c = count; - - /* If count = 0 return to user */ - if (c <= 0) { - PDEBUG - ("me4000_ao_write_cont():Count reached 0\n"); - break; - } - - k = 2 * c; - k -= copy_from_user(ao_context->circ_buf.buf + - ao_context->circ_buf.head, buffer, - k); - c = k / 2; - PDEBUG - ("me4000_ao_write_cont():Wrote %d values to buffer\n", - c); - - if (!c) - return -EFAULT; - - ao_context->circ_buf.head = - (ao_context->circ_buf.head + - c) & (ME4000_AO_BUFFER_COUNT - 1); - buffer += c; - count -= c; - ret += c; - - /* If values in the buffer are available so enable interrupts */ - spin_lock_irqsave(&ao_context->int_lock, flags); - if (me4000_buf_count - (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) { - PDEBUG - ("me4000_ao_write_cont():Enable Interrupts\n"); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ; - me4000_outl(tmp, ao_context->ctrl_reg); - } - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } - } - - if (filep->f_flags & O_NONBLOCK) - return (ret == 0) ? -EAGAIN : 2 * ret; - - return 2 * ret; -} - -static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table *wait) -{ - struct me4000_ao_context *ao_context; - unsigned long mask = 0; - - CALL_PDEBUG("me4000_ao_poll_cont() is executed\n"); - - ao_context = file_p->private_data; - - poll_wait(file_p, &ao_context->wait_queue, wait); - - /* Get free buffer */ - if (me4000_space_to_end(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) - mask |= POLLOUT | POLLWRNORM; - - CALL_PDEBUG("me4000_ao_poll_cont():Return mask %lX\n", mask); - - return mask; -} - -static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p, - int datasync) -{ - struct me4000_ao_context *ao_context; - wait_queue_head_t queue; - - CALL_PDEBUG("me4000_ao_fsync_cont() is executed\n"); - - ao_context = file_p->private_data; - init_waitqueue_head(&queue); - - while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - wait_event_interruptible_timeout(queue, - !(inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM), - 1); - if (ao_context->pipe_flag) { - printk(KERN_ERR - "%s:Broken pipe detected\n", __func__); - return -EPIPE; - } - - if (signal_pending(current)) { - printk(KERN_ERR - "%s:Wait on state machine interrupted\n", - __func__); - return -EINTR; - } - } - - return 0; -} - -static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ao_context *ao_context; - - CALL_PDEBUG("me4000_ao_ioctl_sing() is executed\n"); - - ao_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - return -ENOTTY; - PDEBUG("me4000_ao_ioctl_sing():Wrong magic number\n"); - } - - switch (service) { - case ME4000_AO_EX_TRIG_SETUP: - return me4000_ao_ex_trig_set_edge((int *)arg, ao_context); - case ME4000_AO_EX_TRIG_ENABLE: - return me4000_ao_ex_trig_enable(ao_context); - case ME4000_AO_EX_TRIG_DISABLE: - return me4000_ao_ex_trig_disable(ao_context); - case ME4000_AO_PRELOAD: - return me4000_ao_preload(ao_context); - case ME4000_AO_PRELOAD_UPDATE: - return me4000_ao_preload_update(ao_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ao_context->board_info); - case ME4000_AO_SIMULTANEOUS_EX_TRIG: - return me4000_ao_simultaneous_ex_trig(ao_context); - case ME4000_AO_SIMULTANEOUS_SW: - return me4000_ao_simultaneous_sw(ao_context); - case ME4000_AO_SIMULTANEOUS_DISABLE: - return me4000_ao_simultaneous_disable(ao_context); - case ME4000_AO_SIMULTANEOUS_UPDATE: - return - me4000_ao_simultaneous_update( - (struct me4000_ao_channel_list *)arg, - ao_context); - case ME4000_AO_EX_TRIG_TIMEOUT: - return me4000_ao_ex_trig_timeout((unsigned long *)arg, - ao_context); - case ME4000_AO_DISABLE_DO: - return me4000_ao_disable_do(ao_context); - default: - printk(KERN_ERR - "me4000_ao_ioctl_sing():Service number invalid\n"); - return -ENOTTY; - } - - return 0; -} - -static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ao_context *ao_context; - - CALL_PDEBUG("me4000_ao_ioctl_wrap() is executed\n"); - - ao_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - return -ENOTTY; - PDEBUG("me4000_ao_ioctl_wrap():Wrong magic number\n"); - } - - switch (service) { - case ME4000_AO_START: - return me4000_ao_start((unsigned long *)arg, ao_context); - case ME4000_AO_STOP: - return me4000_ao_stop(ao_context); - case ME4000_AO_IMMEDIATE_STOP: - return me4000_ao_immediate_stop(ao_context); - case ME4000_AO_RESET: - return me4000_ao_reset(ao_context); - case ME4000_AO_TIMER_SET_DIVISOR: - return me4000_ao_timer_set_divisor((u32 *) arg, ao_context); - case ME4000_AO_EX_TRIG_SETUP: - return me4000_ao_ex_trig_set_edge((int *)arg, ao_context); - case ME4000_AO_EX_TRIG_ENABLE: - return me4000_ao_ex_trig_enable(ao_context); - case ME4000_AO_EX_TRIG_DISABLE: - return me4000_ao_ex_trig_disable(ao_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ao_context->board_info); - case ME4000_AO_FSM_STATE: - return me4000_ao_fsm_state((int *)arg, ao_context); - case ME4000_AO_ENABLE_DO: - return me4000_ao_enable_do(ao_context); - case ME4000_AO_DISABLE_DO: - return me4000_ao_disable_do(ao_context); - case ME4000_AO_SYNCHRONOUS_EX_TRIG: - return me4000_ao_synchronous_ex_trig(ao_context); - case ME4000_AO_SYNCHRONOUS_SW: - return me4000_ao_synchronous_sw(ao_context); - case ME4000_AO_SYNCHRONOUS_DISABLE: - return me4000_ao_synchronous_disable(ao_context); - default: - return -ENOTTY; - } - return 0; -} - -static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ao_context *ao_context; - - CALL_PDEBUG("me4000_ao_ioctl_cont() is executed\n"); - - ao_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - return -ENOTTY; - PDEBUG("me4000_ao_ioctl_cont():Wrong magic number\n"); - } - - switch (service) { - case ME4000_AO_START: - return me4000_ao_start((unsigned long *)arg, ao_context); - case ME4000_AO_STOP: - return me4000_ao_stop(ao_context); - case ME4000_AO_IMMEDIATE_STOP: - return me4000_ao_immediate_stop(ao_context); - case ME4000_AO_RESET: - return me4000_ao_reset(ao_context); - case ME4000_AO_TIMER_SET_DIVISOR: - return me4000_ao_timer_set_divisor((u32 *) arg, ao_context); - case ME4000_AO_EX_TRIG_SETUP: - return me4000_ao_ex_trig_set_edge((int *)arg, ao_context); - case ME4000_AO_EX_TRIG_ENABLE: - return me4000_ao_ex_trig_enable(ao_context); - case ME4000_AO_EX_TRIG_DISABLE: - return me4000_ao_ex_trig_disable(ao_context); - case ME4000_AO_ENABLE_DO: - return me4000_ao_enable_do(ao_context); - case ME4000_AO_DISABLE_DO: - return me4000_ao_disable_do(ao_context); - case ME4000_AO_FSM_STATE: - return me4000_ao_fsm_state((int *)arg, ao_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ao_context->board_info); - case ME4000_AO_SYNCHRONOUS_EX_TRIG: - return me4000_ao_synchronous_ex_trig(ao_context); - case ME4000_AO_SYNCHRONOUS_SW: - return me4000_ao_synchronous_sw(ao_context); - case ME4000_AO_SYNCHRONOUS_DISABLE: - return me4000_ao_synchronous_disable(ao_context); - case ME4000_AO_GET_FREE_BUFFER: - return me4000_ao_get_free_buffer((unsigned long *)arg, - ao_context); - default: - return -ENOTTY; - } - return 0; -} - -static int me4000_ao_start(unsigned long *arg, - struct me4000_ao_context *ao_context) -{ - u32 tmp; - wait_queue_head_t queue; - unsigned long ref; - unsigned long timeout; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_start() is executed\n"); - - if (get_user(timeout, arg)) { - printk(KERN_ERR - "me4000_ao_start():Cannot copy data from user\n"); - return -EFAULT; - } - - init_waitqueue_head(&queue); - - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = inl(ao_context->ctrl_reg); - tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) { - if (timeout) { - ref = jiffies; - while (! - (inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ao_start():Wait on start of state machine interrupted\n"); - return -EINTR; - } - /* kernel 2.6 has different definitions for HZ - * in user and kernel space */ - if ((jiffies - ref) > (timeout * HZ / USER_HZ)) { - printk(KERN_ERR - "ME4000:me4000_ao_start():Timeout reached\n"); - return -EIO; - } - } - } - } else { - me4000_outl(0x8000, ao_context->single_reg); - } - - return 0; -} - -static int me4000_ao_stop(struct me4000_ao_context *ao_context) -{ - u32 tmp; - wait_queue_head_t queue; - unsigned long flags; - - init_waitqueue_head(&queue); - - CALL_PDEBUG("me4000_ao_stop() is executed\n"); - - /* Set the stop bit */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_STOP; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "me4000_ao_stop():Wait on state machine after stop interrupted\n"); - return -EINTR; - } - } - - /* Clear the stop bit */ - /* tmp &= ~ME4000_AO_CTRL_BIT_STOP; */ - /* me4000_outl(tmp, ao_context->ctrl_reg); */ - - return 0; -} - -static int me4000_ao_immediate_stop(struct me4000_ao_context *ao_context) -{ - u32 tmp; - wait_queue_head_t queue; - unsigned long flags; - - init_waitqueue_head(&queue); - - CALL_PDEBUG("me4000_ao_immediate_stop() is executed\n"); - - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "me4000_ao_immediate_stop():Wait on state machine after stop interrupted\n"); - return -EINTR; - } - } - - /* Clear the stop bits */ - /* tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); */ - /* me4000_outl(tmp, ao_context->ctrl_reg); */ - - return 0; -} - -static int me4000_ao_timer_set_divisor(u32 *arg, - struct me4000_ao_context *ao_context) -{ - u32 divisor; - u32 tmp; - - CALL_PDEBUG("me4000_ao_timer set_divisor() is executed\n"); - - if (get_user(divisor, arg)) - return -EFAULT; - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_timer_set_divisor():Can't set timer while DAC is running\n"); - return -EBUSY; - } - - PDEBUG("me4000_ao_timer set_divisor():Divisor from user = %d\n", - divisor); - - /* Check if the divisor is right. ME4000_AO_MIN_TICKS is the lowest */ - if (divisor < ME4000_AO_MIN_TICKS) { - printk(KERN_ERR - "ME4000:me4000_ao_timer set_divisor():Divisor to low\n"); - return -EINVAL; - } - - /* Fix bug in Firmware */ - divisor -= 2; - - PDEBUG("me4000_ao_timer set_divisor():Divisor to HW = %d\n", divisor); - - /* Write the divisor */ - me4000_outl(divisor, ao_context->timer_reg); - - return 0; -} - -static int me4000_ao_ex_trig_set_edge(int *arg, - struct me4000_ao_context *ao_context) -{ - int mode; - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_ex_trig_set_edge() is executed\n"); - - if (get_user(mode, arg)) - return -EFAULT; - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_ex_trig_set_edge():Can't set trigger while DAC is running\n"); - return -EBUSY; - } - - if (mode == ME4000_AO_TRIGGER_EXT_EDGE_RISING) { - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp &= - ~(ME4000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4000_AO_CTRL_BIT_EX_TRIG_BOTH); - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_FALLING) { - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp &= ~ME4000_AO_CTRL_BIT_EX_TRIG_BOTH; - tmp |= ME4000_AO_CTRL_BIT_EX_TRIG_EDGE; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_BOTH) { - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= - ME4000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4000_AO_CTRL_BIT_EX_TRIG_BOTH; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - } else { - printk(KERN_ERR - "me4000_ao_ex_trig_set_edge():Invalid trigger mode\n"); - return -EINVAL; - } - - return 0; -} - -static int me4000_ao_ex_trig_enable(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_ex_trig_enable() is executed\n"); - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_ex_trig_enable():Can't enable trigger while DAC is running\n"); - return -EBUSY; - } - - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_ex_trig_disable(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_ex_trig_disable() is executed\n"); - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_ex_trig_disable():Can't disable trigger while DAC is running\n"); - return -EBUSY; - } - - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context) -{ - u32 tmp; - - CALL_PDEBUG("me4000_ao_simultaneous_disable() is executed\n"); - - /* Check if the state machine is stopped */ - /* Be careful here because this function is called from - me4000_ao_synchronous disable */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_simultaneous_disable():Can't disable while DAC is running\n"); - return -EBUSY; - } - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - /* Disable preload bit */ - tmp &= ~(0x1 << ao_context->index); - /* Disable hw simultaneous bit */ - tmp &= ~(0x1 << (ao_context->index + 16)); - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - return 0; -} - -static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context) -{ - u32 tmp; - - CALL_PDEBUG("me4000_ao_simultaneous_ex_trig() is executed\n"); - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - /* Enable preload bit */ - tmp |= (0x1 << ao_context->index); - /* Enable hw simulatenous bit */ - tmp |= (0x1 << (ao_context->index + 16)); - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - return 0; -} - -static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context) -{ - u32 tmp; - - CALL_PDEBUG("me4000_ao_simultaneous_sw() is executed\n"); - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - /* Enable preload bit */ - tmp |= (0x1 << ao_context->index); - /* Enable hw simulatenous bit */ - tmp &= ~(0x1 << (ao_context->index + 16)); - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - return 0; -} - -static int me4000_ao_preload(struct me4000_ao_context *ao_context) -{ - CALL_PDEBUG("me4000_ao_preload() is executed\n"); - return me4000_ao_simultaneous_sw(ao_context); -} - -static int me4000_ao_preload_update(struct me4000_ao_context *ao_context) -{ - u32 tmp; - u32 ctrl; - struct list_head *entry; - - CALL_PDEBUG("me4000_ao_preload_update() is executed\n"); - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - list_for_each(entry, &ao_context->board_info->ao_context_list) { - /* The channels we update must be in the following state : - - Mode A - - Hardware trigger is disabled - - Corresponding simultaneous bit is reset - */ - ctrl = me4000_inl(ao_context->ctrl_reg); - if (! - (ctrl & - (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1 | - ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG))) { - if (! - (tmp & - (0x1 << - (((struct me4000_ao_context *)entry)->index - + 16)))) { - tmp &= - ~(0x1 << - (((struct me4000_ao_context *)entry)-> - index)); - } - } - } - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - return 0; -} - -static int me4000_ao_simultaneous_update(struct me4000_ao_channel_list *arg, - struct me4000_ao_context *ao_context) -{ - int err; - int i; - u32 tmp; - struct me4000_ao_channel_list channels; - - CALL_PDEBUG("me4000_ao_simultaneous_update() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&channels, arg, - sizeof(struct me4000_ao_channel_list)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ao_simultaneous_update():Can't copy command\n"); - return -EFAULT; - } - - channels.list = - kzalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL); - if (!channels.list) { - printk(KERN_ERR - "ME4000:me4000_ao_simultaneous_update():Can't get buffer\n"); - return -ENOMEM; - } - - /* Copy channel list from user */ - err = - copy_from_user(channels.list, arg->list, - sizeof(unsigned long) * channels.count); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ao_simultaneous_update():Can't copy list\n"); - kfree(channels.list); - return -EFAULT; - } - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - for (i = 0; i < channels.count; i++) { - if (channels.list[i] > - ao_context->board_info->board_p->ao.count) { - spin_unlock(&ao_context->board_info->preload_lock); - kfree(channels.list); - printk(KERN_ERR - "ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n"); - return -EFAULT; - } - /* Clear the preload bit */ - tmp &= ~(0x1 << channels.list[i]); - /* Clear the hw simultaneous bit */ - tmp &= ~(0x1 << (channels.list[i] + 16)); - } - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - kfree(channels.list); - - return 0; -} - -static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_synchronous_ex_trig() is executed\n"); - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR - "me4000_ao_synchronous_ex_trig(): DAC is running\n"); - return -EBUSY; - } - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - /* Disable synchronous sw bit */ - tmp &= ~(0x1 << ao_context->index); - /* Enable synchronous hw bit */ - tmp |= 0x1 << (ao_context->index + 16); - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - /* Make runnable */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) { - tmp &= - ~(ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(tmp, ao_context->ctrl_reg); - } - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_synchronous_sw() is executed\n"); - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR "me4000_ao_synchronous_sw(): DAC is running\n"); - return -EBUSY; - } - - spin_lock(&ao_context->board_info->preload_lock); - tmp = me4000_inl(ao_context->preload_reg); - /* Enable synchronous sw bit */ - tmp |= 0x1 << ao_context->index; - /* Disable synchronous hw bit */ - tmp &= ~(0x1 << (ao_context->index + 16)); - me4000_outl(tmp, ao_context->preload_reg); - spin_unlock(&ao_context->board_info->preload_lock); - - /* Make runnable */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = me4000_inl(ao_context->ctrl_reg); - if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) { - tmp &= - ~(ME4000_AO_CTRL_BIT_STOP | - ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(tmp, ao_context->ctrl_reg); - } - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context) -{ - return me4000_ao_simultaneous_disable(ao_context); -} - -static int me4000_ao_get_free_buffer(unsigned long *arg, - struct me4000_ao_context *ao_context) -{ - unsigned long c; - int err; - - c = me4000_buf_space(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT); - - err = copy_to_user(arg, &c, sizeof(unsigned long)); - if (err) { - printk(KERN_ERR - "%s:Can't copy to user space\n", __func__); - return -EFAULT; - } - - return 0; -} - -static int me4000_ao_ex_trig_timeout(unsigned long *arg, - struct me4000_ao_context *ao_context) -{ - u32 tmp; - wait_queue_head_t queue; - unsigned long ref; - unsigned long timeout; - - CALL_PDEBUG("me4000_ao_ex_trig_timeout() is executed\n"); - - if (get_user(timeout, arg)) { - printk(KERN_ERR - "me4000_ao_ex_trig_timeout():Cannot copy data from user\n"); - return -EFAULT; - } - - init_waitqueue_head(&queue); - - tmp = inl(ao_context->ctrl_reg); - - if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) { - if (timeout) { - ref = jiffies; - while ((inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n"); - return -EINTR; - } - /* kernel 2.6 has different definitions for HZ - * in user and kernel space */ - if ((jiffies - ref) > (timeout * HZ / USER_HZ)) { - printk(KERN_ERR - "ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n"); - return -EIO; - } - } - } else { - while ((inl(ao_context->status_reg) & - ME4000_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n"); - return -EINTR; - } - } - } - } else { - printk(KERN_ERR - "ME4000:me4000_ao_ex_trig_timeout():External Trigger is not enabled\n"); - return -EINVAL; - } - - return 0; -} - -static int me4000_ao_enable_do(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_enable_do() is executed\n"); - - /* Only available for analog output 3 */ - if (ao_context->index != 3) { - printk(KERN_ERR - "me4000_ao_enable_do():Only available for analog output 3\n"); - return -ENOTTY; - } - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR "me4000_ao_enable_do(): DAC is running\n"); - return -EBUSY; - } - - /* Set the stop bit */ - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_ENABLE_DO; - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_disable_do(struct me4000_ao_context *ao_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ao_disable_do() is executed\n"); - - /* Only available for analog output 3 */ - if (ao_context->index != 3) { - printk(KERN_ERR - "me4000_ao_disable():Only available for analog output 3\n"); - return -ENOTTY; - } - - /* Check if the state machine is stopped */ - tmp = me4000_inl(ao_context->status_reg); - if (tmp & ME4000_AO_STATUS_BIT_FSM) { - printk(KERN_ERR "me4000_ao_disable_do(): DAC is running\n"); - return -EBUSY; - } - - spin_lock_irqsave(&ao_context->int_lock, flags); - tmp = inl(ao_context->ctrl_reg); - tmp &= ~(ME4000_AO_CTRL_BIT_ENABLE_DO); - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock_irqrestore(&ao_context->int_lock, flags); - - return 0; -} - -static int me4000_ao_fsm_state(int *arg, struct me4000_ao_context *ao_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ao_fsm_state() is executed\n"); - - tmp = - (me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) ? 1 - : 0; - - if (ao_context->pipe_flag) { - printk(KERN_ERR "me4000_ao_fsm_state():Broken pipe detected\n"); - return -EPIPE; - } - - if (put_user(tmp, arg)) { - printk(KERN_ERR "me4000_ao_fsm_state():Cannot copy to user\n"); - return -EFAULT; - } - - return 0; -} - -/*------------------------- Analog input stuff -------------------------------*/ - -static int me4000_ai_prepare(struct me4000_ai_context *ai_context) -{ - wait_queue_head_t queue; - int err; - - CALL_PDEBUG("me4000_ai_prepare() is executed\n"); - - init_waitqueue_head(&queue); - - /* Set the new mode and stop bits */ - me4000_outl(ai_context-> - mode | ME4000_AI_CTRL_BIT_STOP | - ME4000_AI_CTRL_BIT_IMMEDIATE_STOP, ai_context->ctrl_reg); - - /* Set the timer registers */ - ai_context->chan_timer = 66; - ai_context->chan_pre_timer = 66; - ai_context->scan_timer_low = 0; - ai_context->scan_timer_high = 0; - - me4000_outl(65, ai_context->chan_timer_reg); - me4000_outl(65, ai_context->chan_pre_timer_reg); - me4000_outl(0, ai_context->scan_timer_low_reg); - me4000_outl(0, ai_context->scan_timer_high_reg); - me4000_outl(0, ai_context->scan_pre_timer_low_reg); - me4000_outl(0, ai_context->scan_pre_timer_high_reg); - - ai_context->channel_list_count = 0; - - if (ai_context->mode) { - /* Request the interrupt line */ - err = - request_irq(ai_context->irq, me4000_ai_isr, - IRQF_DISABLED | IRQF_SHARED, ME4000_NAME, - ai_context); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_prepare():Can't get interrupt line"); - return -ENODEV; - } - - /* Allocate circular buffer */ - ai_context->circ_buf.buf = - kzalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL); - if (!ai_context->circ_buf.buf) { - printk(KERN_ERR - "ME4000:me4000_ai_prepare():Can't get circular buffer\n"); - free_irq(ai_context->irq, ai_context); - return -ENOMEM; - } - - /* Clear the circular buffer */ - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - } - - return 0; -} - -static int me4000_ai_reset(struct me4000_ai_context *ai_context) -{ - wait_queue_head_t queue; - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_reset() is executed\n"); - - init_waitqueue_head(&queue); - - /* - * First stop conversion of the state machine before reconfigure. - * If not stopped before configuring mode, it could - * walk in a undefined state. - */ - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "me4000_ai_reset():Wait on state machine after stop interrupted\n"); - return -EINTR; - } - } - - /* Clear the control register and set the stop bits */ - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP, - ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - /* Reset timer registers */ - ai_context->chan_timer = 66; - ai_context->chan_pre_timer = 66; - ai_context->scan_timer_low = 0; - ai_context->scan_timer_high = 0; - ai_context->sample_counter = 0; - ai_context->sample_counter_reload = 0; - - me4000_outl(65, ai_context->chan_timer_reg); - me4000_outl(65, ai_context->chan_pre_timer_reg); - me4000_outl(0, ai_context->scan_timer_low_reg); - me4000_outl(0, ai_context->scan_timer_high_reg); - me4000_outl(0, ai_context->scan_pre_timer_low_reg); - me4000_outl(0, ai_context->scan_pre_timer_high_reg); - me4000_outl(0, ai_context->sample_counter_reg); - - ai_context->channel_list_count = 0; - - /* Clear the circular buffer */ - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - - return 0; -} - -static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ai_context *ai_context; - - CALL_PDEBUG("me4000_ai_ioctl_sing() is executed\n"); - - ai_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_ai_ioctl_sing():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR - "me4000_ai_ioctl_sing():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_AI_SINGLE: - return me4000_ai_single((struct me4000_ai_single *)arg, - ai_context); - case ME4000_AI_EX_TRIG_ENABLE: - return me4000_ai_ex_trig_enable(ai_context); - case ME4000_AI_EX_TRIG_DISABLE: - return me4000_ai_ex_trig_disable(ai_context); - case ME4000_AI_EX_TRIG_SETUP: - return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg, - ai_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ai_context->board_info); - case ME4000_AI_OFFSET_ENABLE: - return me4000_ai_offset_enable(ai_context); - case ME4000_AI_OFFSET_DISABLE: - return me4000_ai_offset_disable(ai_context); - case ME4000_AI_FULLSCALE_ENABLE: - return me4000_ai_fullscale_enable(ai_context); - case ME4000_AI_FULLSCALE_DISABLE: - return me4000_ai_fullscale_disable(ai_context); - case ME4000_AI_EEPROM_READ: - return me4000_eeprom_read((struct me4000_eeprom *)arg, - ai_context); - case ME4000_AI_EEPROM_WRITE: - return me4000_eeprom_write((struct me4000_eeprom *)arg, - ai_context); - default: - printk(KERN_ERR - "me4000_ai_ioctl_sing():Invalid service number\n"); - return -ENOTTY; - } - return 0; -} - -static int me4000_ai_single(struct me4000_ai_single *arg, - struct me4000_ai_context *ai_context) -{ - struct me4000_ai_single cmd; - int err; - u32 tmp; - wait_queue_head_t queue; - unsigned long jiffy; - - CALL_PDEBUG("me4000_ai_single() is executed\n"); - - init_waitqueue_head(&queue); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_single)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Can't copy from user space\n"); - return -EFAULT; - } - - /* Check range parameter */ - switch (cmd.range) { - case ME4000_AI_LIST_RANGE_BIPOLAR_10: - case ME4000_AI_LIST_RANGE_BIPOLAR_2_5: - case ME4000_AI_LIST_RANGE_UNIPOLAR_10: - case ME4000_AI_LIST_RANGE_UNIPOLAR_2_5: - break; - default: - printk(KERN_ERR - "ME4000:me4000_ai_single():Invalid range specified\n"); - return -EINVAL; - } - - /* Check mode and channel number */ - switch (cmd.mode) { - case ME4000_AI_LIST_INPUT_SINGLE_ENDED: - if (cmd.channel >= ai_context->board_info->board_p->ai.count) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Analog input is not available\n"); - return -EINVAL; - } - break; - case ME4000_AI_LIST_INPUT_DIFFERENTIAL: - if (cmd.channel >= - ai_context->board_info->board_p->ai.diff_count) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Analog input is not available in differential mode\n"); - return -EINVAL; - } - break; - default: - printk(KERN_ERR - "ME4000:me4000_ai_single():Invalid mode specified\n"); - return -EINVAL; - } - - /* Clear channel list, data fifo and both stop bits */ - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= - ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO | - ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - me4000_outl(tmp, ai_context->ctrl_reg); - - /* Enable channel list and data fifo */ - tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO; - me4000_outl(tmp, ai_context->ctrl_reg); - - /* Generate channel list entry */ - me4000_outl(cmd.channel | cmd.range | cmd. - mode | ME4000_AI_LIST_LAST_ENTRY, - ai_context->channel_list_reg); - - /* Set the timer to maximum */ - me4000_outl(66, ai_context->chan_timer_reg); - me4000_outl(66, ai_context->chan_pre_timer_reg); - - if (tmp & ME4000_AI_CTRL_BIT_EX_TRIG) { - jiffy = jiffies; - while (! - (me4000_inl(ai_context->status_reg) & - ME4000_AI_STATUS_BIT_EF_DATA)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Wait on start of state machine interrupted\n"); - return -EINTR; - } - /* 2.6 has different definitions for HZ in user and kernel space */ - if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Timeout reached\n"); - return -EIO; - } - } - } else { - /* Start conversion */ - me4000_inl(ai_context->start_reg); - - /* Wait until ready */ - udelay(10); - if (! - (me4000_inl(ai_context->status_reg) & - ME4000_AI_STATUS_BIT_EF_DATA)) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Value not available after wait\n"); - return -EIO; - } - } - - /* Read value from data fifo */ - cmd.value = me4000_inl(ai_context->data_reg) & 0xFFFF; - - /* Copy result back to user */ - err = copy_to_user(arg, &cmd, sizeof(struct me4000_ai_single)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_single():Can't copy to user space\n"); - return -EFAULT; - } - - return 0; -} - -static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ai_context *ai_context; - - CALL_PDEBUG("me4000_ai_ioctl_sw() is executed\n"); - - ai_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_ai_ioctl_sw():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR - "me4000_ai_ioctl_sw():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_AI_SC_SETUP: - return me4000_ai_sc_setup((struct me4000_ai_sc *)arg, - ai_context); - case ME4000_AI_CONFIG: - return me4000_ai_config((struct me4000_ai_config *)arg, - ai_context); - case ME4000_AI_START: - return me4000_ai_start(ai_context); - case ME4000_AI_STOP: - return me4000_ai_stop(ai_context); - case ME4000_AI_IMMEDIATE_STOP: - return me4000_ai_immediate_stop(ai_context); - case ME4000_AI_FSM_STATE: - return me4000_ai_fsm_state((int *)arg, ai_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ai_context->board_info); - case ME4000_AI_EEPROM_READ: - return me4000_eeprom_read((struct me4000_eeprom *)arg, - ai_context); - case ME4000_AI_EEPROM_WRITE: - return me4000_eeprom_write((struct me4000_eeprom *)arg, - ai_context); - case ME4000_AI_GET_COUNT_BUFFER: - return me4000_ai_get_count_buffer((unsigned long *)arg, - ai_context); - default: - printk(KERN_ERR - "%s:Invalid service number %d\n", __func__, service); - return -ENOTTY; - } - return 0; -} - -static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ai_context *ai_context; - - CALL_PDEBUG("me4000_ai_ioctl_ext() is executed\n"); - - ai_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_ai_ioctl_ext():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR - "me4000_ai_ioctl_ext():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_AI_SC_SETUP: - return me4000_ai_sc_setup((struct me4000_ai_sc *)arg, - ai_context); - case ME4000_AI_CONFIG: - return me4000_ai_config((struct me4000_ai_config *)arg, - ai_context); - case ME4000_AI_START: - return me4000_ai_start_ex((unsigned long *)arg, ai_context); - case ME4000_AI_STOP: - return me4000_ai_stop(ai_context); - case ME4000_AI_IMMEDIATE_STOP: - return me4000_ai_immediate_stop(ai_context); - case ME4000_AI_EX_TRIG_ENABLE: - return me4000_ai_ex_trig_enable(ai_context); - case ME4000_AI_EX_TRIG_DISABLE: - return me4000_ai_ex_trig_disable(ai_context); - case ME4000_AI_EX_TRIG_SETUP: - return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg, - ai_context); - case ME4000_AI_FSM_STATE: - return me4000_ai_fsm_state((int *)arg, ai_context); - case ME4000_GET_USER_INFO: - return me4000_get_user_info((struct me4000_user_info *)arg, - ai_context->board_info); - case ME4000_AI_GET_COUNT_BUFFER: - return me4000_ai_get_count_buffer((unsigned long *)arg, - ai_context); - default: - printk(KERN_ERR - "%s:Invalid service number %d\n", __func__ , service); - return -ENOTTY; - } - return 0; -} - -static int me4000_ai_fasync(int fd, struct file *file_p, int mode) -{ - struct me4000_ai_context *ai_context; - - CALL_PDEBUG("me4000_ao_fasync_cont() is executed\n"); - - ai_context = file_p->private_data; - return fasync_helper(fd, file_p, mode, &ai_context->fasync_p); -} - -static int me4000_ai_config(struct me4000_ai_config *arg, - struct me4000_ai_context *ai_context) -{ - struct me4000_ai_config cmd; - u32 *list = NULL; - u32 mode; - int i; - int err; - wait_queue_head_t queue; - u64 scan; - u32 tmp; - - CALL_PDEBUG("me4000_ai_config() is executed\n"); - - init_waitqueue_head(&queue); - - /* Check if conversion is stopped */ - if (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_FSM) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Conversion is not stopped\n"); - err = -EBUSY; - goto AI_CONFIG_ERR; - } - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_config)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Can't copy from user space\n"); - err = -EFAULT; - goto AI_CONFIG_ERR; - } - - PDEBUG - ("me4000_ai_config():chan = %ld, pre_chan = %ld, scan_low = %ld, scan_high = %ld, count = %ld\n", - cmd.timer.chan, cmd.timer.pre_chan, cmd.timer.scan_low, - cmd.timer.scan_high, cmd.channel_list.count); - - /* Check whether sample and hold is available for this board */ - if (cmd.sh) { - if (!ai_context->board_info->board_p->ai.sh_count) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Sample and Hold is not available for this board\n"); - err = -ENODEV; - goto AI_CONFIG_ERR; - } - } - - /* Check the channel list size */ - if (cmd.channel_list.count > ME4000_AI_CHANNEL_LIST_COUNT) { - printk(KERN_ERR - "me4000_ai_config():Channel list is to large\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - - /* Copy channel list from user */ - list = kmalloc(sizeof(u32) * cmd.channel_list.count, GFP_KERNEL); - if (!list) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Can't get memory for channel list\n"); - err = -ENOMEM; - goto AI_CONFIG_ERR; - } - err = - copy_from_user(list, cmd.channel_list.list, - sizeof(u32) * cmd.channel_list.count); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Can't copy from user space\n"); - err = -EFAULT; - goto AI_CONFIG_ERR; - } - - /* Check if last entry bit is set */ - if (!(list[cmd.channel_list.count - 1] & ME4000_AI_LIST_LAST_ENTRY)) { - printk(KERN_WARNING - "me4000_ai_config():Last entry bit is not set\n"); - list[cmd.channel_list.count - 1] |= ME4000_AI_LIST_LAST_ENTRY; - } - - /* Check whether mode is equal for all entries */ - mode = list[0] & 0x20; - for (i = 0; i < cmd.channel_list.count; i++) { - if ((list[i] & 0x20) != mode) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Mode is not equal for all entries\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - } - - /* Check whether channels are available for this mode */ - if (mode == ME4000_AI_LIST_INPUT_SINGLE_ENDED) { - for (i = 0; i < cmd.channel_list.count; i++) { - if ((list[i] & 0x1F) >= - ai_context->board_info->board_p->ai.count) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Channel is not available for single ended\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - } - } else if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) { - for (i = 0; i < cmd.channel_list.count; i++) { - if ((list[i] & 0x1F) >= - ai_context->board_info->board_p->ai.diff_count) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Channel is not available for differential\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - } - } - - /* Check if bipolar is set for all entries when in differential mode */ - if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) { - for (i = 0; i < cmd.channel_list.count; i++) { - if ((list[i] & 0xC0) != ME4000_AI_LIST_RANGE_BIPOLAR_10 - && (list[i] & 0xC0) != - ME4000_AI_LIST_RANGE_BIPOLAR_2_5) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Bipolar is not selected in differential mode\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - } - } - - if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE) { - /* Check for minimum channel divisor */ - if (cmd.timer.chan < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Channel timer divisor is to low\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - - /* Check if minimum channel divisor is adjusted when sample and hold is activated */ - if ((cmd.sh) && (cmd.timer.chan != ME4000_AI_MIN_TICKS)) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Channel timer divisor must be at minimum when sample and hold is activated\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - - /* Check for minimum channel pre divisor */ - if (cmd.timer.pre_chan < ME4000_AI_MIN_TICKS) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Channel pre timer divisor is to low\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - - /* Write the channel timers */ - me4000_outl(cmd.timer.chan - 1, ai_context->chan_timer_reg); - me4000_outl(cmd.timer.pre_chan - 1, - ai_context->chan_pre_timer_reg); - - /* Save the timer values in the board context */ - ai_context->chan_timer = cmd.timer.chan; - ai_context->chan_pre_timer = cmd.timer.pre_chan; - - if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST) { - /* Check for scan timer divisor */ - scan = - (u64) cmd.timer.scan_low | ((u64) cmd.timer. - scan_high << 32); - if (scan != 0) { - if (scan < - cmd.channel_list.count * cmd.timer.chan + - 1) { - printk(KERN_ERR - "ME4000:me4000_ai_config():Scan timer divisor is to low\n"); - err = -EINVAL; - goto AI_CONFIG_ERR; - } - } - - /* Write the scan timers */ - if (scan != 0) { - scan--; - tmp = (u32) (scan & 0xFFFFFFFF); - me4000_outl(tmp, - ai_context->scan_timer_low_reg); - tmp = (u32) ((scan >> 32) & 0xFFFFFFFF); - me4000_outl(tmp, - ai_context->scan_timer_high_reg); - - scan = - scan - (cmd.timer.chan - 1) + - (cmd.timer.pre_chan - 1); - tmp = (u32) (scan & 0xFFFFFFFF); - me4000_outl(tmp, - ai_context->scan_pre_timer_low_reg); - tmp = (u32) ((scan >> 32) & 0xFFFFFFFF); - me4000_outl(tmp, - ai_context-> - scan_pre_timer_high_reg); - } else { - me4000_outl(0x0, - ai_context->scan_timer_low_reg); - me4000_outl(0x0, - ai_context->scan_timer_high_reg); - - me4000_outl(0x0, - ai_context->scan_pre_timer_low_reg); - me4000_outl(0x0, - ai_context-> - scan_pre_timer_high_reg); - } - - ai_context->scan_timer_low = cmd.timer.scan_low; - ai_context->scan_timer_high = cmd.timer.scan_high; - } - } - - /* Clear the channel list */ - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_CHANNEL_FIFO; - me4000_outl(tmp, ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO; - me4000_outl(tmp, ai_context->ctrl_reg); - - /* Write the channel list */ - for (i = 0; i < cmd.channel_list.count; i++) - me4000_outl(list[i], ai_context->channel_list_reg); - - /* Setup sample and hold */ - if (cmd.sh) { - tmp |= ME4000_AI_CTRL_BIT_SAMPLE_HOLD; - me4000_outl(tmp, ai_context->ctrl_reg); - } else { - tmp &= ~ME4000_AI_CTRL_BIT_SAMPLE_HOLD; - me4000_outl(tmp, ai_context->ctrl_reg); - } - - /* Save the channel list size in the board context */ - ai_context->channel_list_count = cmd.channel_list.count; - - kfree(list); - - return 0; - -AI_CONFIG_ERR: - - /* Reset the timers */ - ai_context->chan_timer = 66; - ai_context->chan_pre_timer = 66; - ai_context->scan_timer_low = 0; - ai_context->scan_timer_high = 0; - - me4000_outl(65, ai_context->chan_timer_reg); - me4000_outl(65, ai_context->chan_pre_timer_reg); - me4000_outl(0, ai_context->scan_timer_high_reg); - me4000_outl(0, ai_context->scan_timer_low_reg); - me4000_outl(0, ai_context->scan_pre_timer_high_reg); - me4000_outl(0, ai_context->scan_pre_timer_low_reg); - - ai_context->channel_list_count = 0; - - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= - ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD); - - kfree(list); - - return err; - -} - -static int ai_common_start(struct me4000_ai_context *ai_context) -{ - u32 tmp; - CALL_PDEBUG("ai_common_start() is executed\n"); - - tmp = me4000_inl(ai_context->ctrl_reg); - - /* Check if conversion is stopped */ - if (tmp & ME4000_AI_STATUS_BIT_FSM) { - printk(KERN_ERR - "ME4000:ai_common_start():Conversion is not stopped\n"); - return -EBUSY; - } - - /* Clear data fifo, disable all interrupts, clear sample counter reload */ - tmp &= ~(ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_LE_IRQ | - ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_SC_RELOAD); - - me4000_outl(tmp, ai_context->ctrl_reg); - - /* Clear circular buffer */ - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - - /* Enable data fifo */ - tmp |= ME4000_AI_CTRL_BIT_DATA_FIFO; - - /* Determine interrupt setup */ - if (ai_context->sample_counter && !ai_context->sample_counter_reload) { - /* Enable Half Full Interrupt and Sample Counter Interrupt */ - tmp |= ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ; - } else if (ai_context->sample_counter - && ai_context->sample_counter_reload) { - if (ai_context->sample_counter <= ME4000_AI_FIFO_COUNT / 2) { - /* Enable only Sample Counter Interrupt */ - tmp |= - ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_SC_RELOAD; - } else { - /* Enable Half Full Interrupt and Sample Counter Interrupt */ - tmp |= - ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_HF_IRQ | - ME4000_AI_CTRL_BIT_SC_RELOAD; - } - } else { - /* Enable only Half Full Interrupt */ - tmp |= ME4000_AI_CTRL_BIT_HF_IRQ; - } - - /* Clear the stop bits */ - tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP); - - /* Write setup to hardware */ - me4000_outl(tmp, ai_context->ctrl_reg); - - /* Write sample counter */ - me4000_outl(ai_context->sample_counter, ai_context->sample_counter_reg); - - return 0; -} - -static int me4000_ai_start(struct me4000_ai_context *ai_context) -{ - int err; - CALL_PDEBUG("me4000_ai_start() is executed\n"); - - /* Prepare Hardware */ - err = ai_common_start(ai_context); - if (err) - return err; - - /* Start conversion by dummy read */ - me4000_inl(ai_context->start_reg); - - return 0; -} - -static int me4000_ai_start_ex(unsigned long *arg, - struct me4000_ai_context *ai_context) -{ - int err; - wait_queue_head_t queue; - unsigned long ref; - unsigned long timeout; - - CALL_PDEBUG("me4000_ai_start_ex() is executed\n"); - - if (get_user(timeout, arg)) { - printk(KERN_ERR - "me4000_ai_start_ex():Cannot copy data from user\n"); - return -EFAULT; - } - - init_waitqueue_head(&queue); - - /* Prepare Hardware */ - err = ai_common_start(ai_context); - if (err) - return err; - - if (timeout) { - ref = jiffies; - while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n"); - return -EINTR; - } - /* 2.6 has different definitions for HZ in user and kernel space */ - if ((jiffies - ref) > (timeout * HZ / USER_HZ)) { - printk(KERN_ERR - "ME4000:me4000_ai_start_ex():Timeout reached\n"); - return -EIO; - } - } - } else { - while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n"); - return -EINTR; - } - } - } - - return 0; -} - -static int me4000_ai_stop(struct me4000_ai_context *ai_context) -{ - wait_queue_head_t queue; - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_stop() is executed\n"); - - init_waitqueue_head(&queue); - - /* Disable irqs and clear data fifo */ - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= - ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_DATA_FIFO); - /* Stop conversion of the state machine */ - tmp |= ME4000_AI_CTRL_BIT_STOP; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - /* Clear circular buffer */ - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - - while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n"); - return -EINTR; - } - } - - return 0; -} - -static int me4000_ai_immediate_stop(struct me4000_ai_context *ai_context) -{ - wait_queue_head_t queue; - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_stop() is executed\n"); - - init_waitqueue_head(&queue); - - /* Disable irqs and clear data fifo */ - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= - ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_DATA_FIFO); - /* Stop conversion of the state machine */ - tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - /* Clear circular buffer */ - ai_context->circ_buf.head = 0; - ai_context->circ_buf.tail = 0; - - while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n"); - return -EINTR; - } - } - - return 0; -} - -static int me4000_ai_ex_trig_enable(struct me4000_ai_context *ai_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_ex_trig_enable() is executed\n"); - - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_EX_TRIG; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - return 0; -} - -static int me4000_ai_ex_trig_disable(struct me4000_ai_context *ai_context) -{ - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_ex_trig_disable() is executed\n"); - - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - - return 0; -} - -static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *arg, - struct me4000_ai_context *ai_context) -{ - struct me4000_ai_trigger cmd; - int err; - u32 tmp; - unsigned long flags; - - CALL_PDEBUG("me4000_ai_ex_trig_setup() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_trigger)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_ex_trig_setup():Can't copy from user space\n"); - return -EFAULT; - } - - spin_lock_irqsave(&ai_context->int_lock, flags); - tmp = me4000_inl(ai_context->ctrl_reg); - - if (cmd.mode == ME4000_AI_TRIGGER_EXT_DIGITAL) { - tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG; - } else if (cmd.mode == ME4000_AI_TRIGGER_EXT_ANALOG) { - if (!ai_context->board_info->board_p->ai.ex_trig_analog) { - printk(KERN_ERR - "ME4000:me4000_ai_ex_trig_setup():No analog trigger available\n"); - return -EINVAL; - } - tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG; - } else { - spin_unlock_irqrestore(&ai_context->int_lock, flags); - printk(KERN_ERR - "ME4000:me4000_ai_ex_trig_setup():Invalid trigger mode specified\n"); - return -EINVAL; - } - - if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_RISING) { - tmp &= - ~(ME4000_AI_CTRL_BIT_EX_TRIG_BOTH | - ME4000_AI_CTRL_BIT_EX_TRIG_FALLING); - } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_FALLING) { - tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_FALLING; - tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_BOTH; - } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_BOTH) { - tmp |= - ME4000_AI_CTRL_BIT_EX_TRIG_BOTH | - ME4000_AI_CTRL_BIT_EX_TRIG_FALLING; - } else { - spin_unlock_irqrestore(&ai_context->int_lock, flags); - printk(KERN_ERR - "ME4000:me4000_ai_ex_trig_setup():Invalid trigger edge specified\n"); - return -EINVAL; - } - - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock_irqrestore(&ai_context->int_lock, flags); - return 0; -} - -static int me4000_ai_sc_setup(struct me4000_ai_sc *arg, - struct me4000_ai_context *ai_context) -{ - struct me4000_ai_sc cmd; - int err; - - CALL_PDEBUG("me4000_ai_sc_setup() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_sc)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_ai_sc_setup():Can't copy from user space\n"); - return -EFAULT; - } - - ai_context->sample_counter = cmd.value; - ai_context->sample_counter_reload = cmd.reload; - - return 0; -} - -static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt, - loff_t *offp) -{ - struct me4000_ai_context *ai_context = filep->private_data; - s16 *buffer = (s16 *) buff; - size_t count = cnt / 2; - unsigned long flags; - int tmp; - int c = 0; - int k = 0; - int ret = 0; - wait_queue_t wait; - - CALL_PDEBUG("me4000_ai_read() is executed\n"); - - init_waitqueue_entry(&wait, current); - - /* Check count */ - if (count <= 0) { - PDEBUG("me4000_ai_read():Count is 0\n"); - return 0; - } - - while (count > 0) { - if (filep->f_flags & O_NONBLOCK) { - c = me4000_values_to_end(ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT); - if (!c) { - PDEBUG - ("me4000_ai_read():Returning from nonblocking read\n"); - break; - } - } else { - /* Check if conversion is still running */ - if (! - (me4000_inl(ai_context->status_reg) & - ME4000_AI_STATUS_BIT_FSM)) { - printk(KERN_ERR - "ME4000:me4000_ai_read():Conversion interrupted\n"); - return -EPIPE; - } - - wait_event_interruptible(ai_context->wait_queue, - (me4000_values_to_end - (ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT))); - if (signal_pending(current)) { - printk(KERN_ERR - "ME4000:me4000_ai_read():Wait on values interrupted from signal\n"); - return -EINTR; - } - } - - /* Only read count values or as much as available */ - c = me4000_values_to_end(ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT); - PDEBUG("me4000_ai_read():%d values to end\n", c); - if (count < c) - c = count; - - PDEBUG("me4000_ai_read():Copy %d values to user space\n", c); - k = 2 * c; - k -= copy_to_user(buffer, - ai_context->circ_buf.buf + - ai_context->circ_buf.tail, k); - c = k / 2; - if (!c) { - printk(KERN_ERR - "ME4000:me4000_ai_read():Cannot copy new values to user\n"); - return -EFAULT; - } - - ai_context->circ_buf.tail = - (ai_context->circ_buf.tail + c) & (ME4000_AI_BUFFER_COUNT - - 1); - buffer += c; - count -= c; - ret += c; - - spin_lock_irqsave(&ai_context->int_lock, flags); - if (me4000_buf_space - (ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) { - tmp = me4000_inl(ai_context->ctrl_reg); - - /* Determine interrupt setup */ - if (ai_context->sample_counter - && !ai_context->sample_counter_reload) { - /* Enable Half Full Interrupt and Sample Counter Interrupt */ - tmp |= - ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_HF_IRQ; - } else if (ai_context->sample_counter - && ai_context->sample_counter_reload) { - if (ai_context->sample_counter < - ME4000_AI_FIFO_COUNT / 2) { - /* Enable only Sample Counter Interrupt */ - tmp |= ME4000_AI_CTRL_BIT_SC_IRQ; - } else { - /* Enable Half Full Interrupt and Sample Counter Interrupt */ - tmp |= - ME4000_AI_CTRL_BIT_SC_IRQ | - ME4000_AI_CTRL_BIT_HF_IRQ; - } - } else { - /* Enable only Half Full Interrupt */ - tmp |= ME4000_AI_CTRL_BIT_HF_IRQ; - } - - me4000_outl(tmp, ai_context->ctrl_reg); - } - spin_unlock_irqrestore(&ai_context->int_lock, flags); - } - - /* Check if conversion is still running */ - if (!(me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) { - printk(KERN_ERR - "ME4000:me4000_ai_read():Conversion not running after complete read\n"); - return -EPIPE; - } - - if (filep->f_flags & O_NONBLOCK) - return (k == 0) ? -EAGAIN : 2 * ret; - - CALL_PDEBUG("me4000_ai_read() is leaved\n"); - return ret * 2; -} - -static unsigned int me4000_ai_poll(struct file *file_p, poll_table *wait) -{ - struct me4000_ai_context *ai_context; - unsigned long mask = 0; - - CALL_PDEBUG("me4000_ai_poll() is executed\n"); - - ai_context = file_p->private_data; - - /* Register wait queue */ - poll_wait(file_p, &ai_context->wait_queue, wait); - - /* Get available values */ - if (me4000_values_to_end(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) - mask |= POLLIN | POLLRDNORM; - - PDEBUG("me4000_ai_poll():Return mask %lX\n", mask); - - return mask; -} - -static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ai_offset_enable() is executed\n"); - - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_OFFSET; - me4000_outl(tmp, ai_context->ctrl_reg); - - return 0; -} - -static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ai_offset_disable() is executed\n"); - - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_OFFSET; - me4000_outl(tmp, ai_context->ctrl_reg); - - return 0; -} - -static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ai_fullscale_enable() is executed\n"); - - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_FULLSCALE; - me4000_outl(tmp, ai_context->ctrl_reg); - - return 0; -} - -static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ai_fullscale_disable() is executed\n"); - - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_FULLSCALE; - me4000_outl(tmp, ai_context->ctrl_reg); - - return 0; -} - -static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ai_fsm_state() is executed\n"); - - tmp = - (me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) ? 1 - : 0; - - if (put_user(tmp, arg)) { - printk(KERN_ERR "me4000_ai_fsm_state():Cannot copy to user\n"); - return -EFAULT; - } - - return 0; -} - -static int me4000_ai_get_count_buffer(unsigned long *arg, - struct me4000_ai_context *ai_context) -{ - unsigned long c; - int err; - - c = me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT); - - err = copy_to_user(arg, &c, sizeof(unsigned long)); - if (err) { - printk(KERN_ERR - "%s:Can't copy to user space\n", __func__); - return -EFAULT; - } - - return 0; -} - -/*---------------------------------- EEPROM stuff ---------------------------*/ - -static int eeprom_write_cmd(struct me4000_ai_context *ai_context, unsigned long cmd, - int length) -{ - int i; - unsigned long value; - - CALL_PDEBUG("eeprom_write_cmd() is executed\n"); - - PDEBUG("eeprom_write_cmd():Write command 0x%08lX with length = %d\n", - cmd, length); - - /* Get the ICR register and clear the related bits */ - value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR); - value &= ~(PLX_ICR_MASK_EEPROM); - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - - /* Raise the chip select */ - value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT; - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - for (i = 0; i < length; i++) { - if (cmd & ((0x1 << (length - 1)) >> i)) - value |= PLX_ICR_BIT_EEPROM_WRITE; - else - value &= ~PLX_ICR_BIT_EEPROM_WRITE; - - /* Write to EEPROM */ - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Raising edge of the clock */ - value |= PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Falling edge of the clock */ - value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - } - - /* Clear the chip select */ - value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT; - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Wait until hardware is ready for sure */ - mdelay(10); - - return 0; -} - -static unsigned short eeprom_read_cmd(struct me4000_ai_context *ai_context, - unsigned long cmd, int length) -{ - int i; - unsigned long value; - unsigned short id = 0; - - CALL_PDEBUG("eeprom_read_cmd() is executed\n"); - - PDEBUG("eeprom_read_cmd():Read command 0x%08lX with length = %d\n", cmd, - length); - - /* Get the ICR register and clear the related bits */ - value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR); - value &= ~(PLX_ICR_MASK_EEPROM); - - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - - /* Raise the chip select */ - value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT; - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Write the read command to the eeprom */ - for (i = 0; i < length; i++) { - if (cmd & ((0x1 << (length - 1)) >> i)) - value |= PLX_ICR_BIT_EEPROM_WRITE; - else - value &= ~PLX_ICR_BIT_EEPROM_WRITE; - - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Raising edge of the clock */ - value |= PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - /* Falling edge of the clock */ - value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - } - - /* Read the value from the eeprom */ - for (i = 0; i < 16; i++) { - /* Raising edge of the clock */ - value |= PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - if (me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR) & - PLX_ICR_BIT_EEPROM_READ) { - id |= (0x8000 >> i); - PDEBUG("eeprom_read_cmd():OR with 0x%04X\n", - (0x8000 >> i)); - } else { - PDEBUG("eeprom_read_cmd():Dont't OR\n"); - } - - /* Falling edge of the clock */ - value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET; - me4000_outl(value, - ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - } - - /* Clear the chip select */ - value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT; - me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR); - udelay(EEPROM_DELAY); - - return id; -} - -static int me4000_eeprom_write(struct me4000_eeprom *arg, - struct me4000_ai_context *ai_context) -{ - int err; - struct me4000_eeprom setup; - unsigned long cmd; - unsigned long date_high; - unsigned long date_low; - - CALL_PDEBUG("me4000_eeprom_write() is executed\n"); - - err = copy_from_user(&setup, arg, sizeof(setup)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_eeprom_write():Cannot copy from user\n"); - return err; - } - - /* Enable writing */ - eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_ENABLE, - ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE); - - /* Command for date */ - date_high = (setup.date & 0xFFFF0000) >> 16; - date_low = (setup.date & 0x0000FFFF); - - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_HIGH << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - date_high); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_LOW << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - date_low); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for unipolar 10V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - uni_10_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for unipolar 10V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - uni_10_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for unipolar 2,5V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - uni_2_5_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for unipolar 2,5V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - uni_2_5_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for bipolar 10V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - bi_10_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for bipolar 10V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - bi_10_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for bipolar 2,5V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - bi_2_5_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for bipolar 2,5V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - bi_2_5_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for differential 10V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - diff_10_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for differential 10V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE - << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - diff_10_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for differential 2,5V offset */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET << - ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - diff_2_5_offset); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Command for differential 2,5V fullscale */ - cmd = - ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE - << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF & - (unsigned - long) - setup. - diff_2_5_fullscale); - err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE); - if (err) - return err; - - /* Disable writing */ - eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_DISABLE, - ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE); - - return 0; -} - -static int me4000_eeprom_read(struct me4000_eeprom *arg, - struct me4000_ai_context *ai_context) -{ - int err; - unsigned long cmd; - struct me4000_eeprom setup; - - CALL_PDEBUG("me4000_eeprom_read() is executed\n"); - - /* Command for date */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_HIGH; - setup.date = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - setup.date <<= 16; - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_LOW; - setup.date |= - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for unipolar 10V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET; - setup.uni_10_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for unipolar 10V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE; - setup.uni_10_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for unipolar 2,5V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET; - setup.uni_2_5_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for unipolar 2,5V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE; - setup.uni_2_5_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for bipolar 10V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET; - setup.bi_10_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for bipolar 10V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE; - setup.bi_10_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for bipolar 2,5V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET; - setup.bi_2_5_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for bipolar 2,5V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE; - setup.bi_2_5_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for differntial 10V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET; - setup.diff_10_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for differential 10V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE; - setup.diff_10_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for differntial 2,5V offset */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET; - setup.diff_2_5_offset = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - /* Command for differential 2,5V fullscale */ - cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE; - setup.diff_2_5_fullscale = - eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ); - - err = copy_to_user(arg, &setup, sizeof(setup)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_eeprom_read():Cannot copy to user\n"); - return err; - } - - return 0; -} - -/*------------------------------------ DIO stuff ----------------------------------------------*/ - -static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_dio_context *dio_context; - - CALL_PDEBUG("me4000_dio_ioctl() is executed\n"); - - dio_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_DIO_CONFIG: - return me4000_dio_config((struct me4000_dio_config *)arg, - dio_context); - case ME4000_DIO_SET_BYTE: - return me4000_dio_set_byte((struct me4000_dio_byte *)arg, - dio_context); - case ME4000_DIO_GET_BYTE: - return me4000_dio_get_byte((struct me4000_dio_byte *)arg, - dio_context); - case ME4000_DIO_RESET: - return me4000_dio_reset(dio_context); - default: - printk(KERN_ERR - "ME4000:me4000_dio_ioctl():Invalid service number %d\n", - service); - return -ENOTTY; - } - return 0; -} - -static int me4000_dio_config(struct me4000_dio_config *arg, - struct me4000_dio_context *dio_context) -{ - struct me4000_dio_config cmd; - u32 tmp; - int err; - - CALL_PDEBUG("me4000_dio_config() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_config)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Can't copy from user space\n"); - return -EFAULT; - } - - /* Check port parameter */ - if (cmd.port >= dio_context->dio_count) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port, - cmd.mode, cmd.function); - - if (cmd.port == ME4000_DIO_PORT_A) { - if (cmd.mode == ME4000_DIO_PORT_INPUT) { - /* Check if opto isolated version */ - if (!(me4000_inl(dio_context->dir_reg) & 0x1)) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Cannot set to input on opto isolated versions\n"); - return -EIO; - } - - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_0 | - ME4000_DIO_CTRL_BIT_MODE_1); - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_0 | - ME4000_DIO_CTRL_BIT_MODE_1); - tmp |= ME4000_DIO_CTRL_BIT_MODE_0; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_LOW) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_0 | - ME4000_DIO_CTRL_BIT_MODE_1 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_0); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_0 | - ME4000_DIO_CTRL_BIT_MODE_1; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_0 | - ME4000_DIO_CTRL_BIT_MODE_1 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_0; - me4000_outl(tmp, dio_context->ctrl_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Mode %d is not available\n", - cmd.mode); - return -EINVAL; - } - } else if (cmd.port == ME4000_DIO_PORT_B) { - if (cmd.mode == ME4000_DIO_PORT_INPUT) { - /* Only do anything when TTL version is installed */ - if ((me4000_inl(dio_context->dir_reg) & 0x1)) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_2 | - ME4000_DIO_CTRL_BIT_MODE_3); - me4000_outl(tmp, dio_context->ctrl_reg); - } - } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) { - /* Check if opto isolated version */ - if (!(me4000_inl(dio_context->dir_reg) & 0x1)) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Cannot set to output on opto isolated versions\n"); - return -EIO; - } - - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_2 | - ME4000_DIO_CTRL_BIT_MODE_3); - tmp |= ME4000_DIO_CTRL_BIT_MODE_2; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_LOW) { - /* Check if opto isolated version */ - if (!(me4000_inl(dio_context->dir_reg) & 0x1)) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Cannot set to FIFO low output on opto isolated versions\n"); - return -EIO; - } - - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_2 | - ME4000_DIO_CTRL_BIT_MODE_3 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_1); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_2 | - ME4000_DIO_CTRL_BIT_MODE_3; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) { - /* Check if opto isolated version */ - if (!(me4000_inl(dio_context->dir_reg) & 0x1)) { - printk(KERN_ERR - "ME4000:me4000_dio_config():Cannot set to FIFO high output on opto isolated versions\n"); - return -EIO; - } - - tmp = me4000_inl(dio_context->ctrl_reg); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_2 | - ME4000_DIO_CTRL_BIT_MODE_3 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_1; - me4000_outl(tmp, dio_context->ctrl_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Mode %d is not available\n", - cmd.mode); - return -EINVAL; - } - } else if (cmd.port == ME4000_DIO_PORT_C) { - if (cmd.mode == ME4000_DIO_PORT_INPUT) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_4 | - ME4000_DIO_CTRL_BIT_MODE_5); - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_4 | - ME4000_DIO_CTRL_BIT_MODE_5); - tmp |= ME4000_DIO_CTRL_BIT_MODE_4; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_LOW) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_4 | - ME4000_DIO_CTRL_BIT_MODE_5 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_2); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_4 | - ME4000_DIO_CTRL_BIT_MODE_5; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_4 | - ME4000_DIO_CTRL_BIT_MODE_5 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_2; - me4000_outl(tmp, dio_context->ctrl_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Mode %d is not available\n", - cmd.mode); - return -EINVAL; - } - } else if (cmd.port == ME4000_DIO_PORT_D) { - if (cmd.mode == ME4000_DIO_PORT_INPUT) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_6 | - ME4000_DIO_CTRL_BIT_MODE_7); - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_6 | - ME4000_DIO_CTRL_BIT_MODE_7); - tmp |= ME4000_DIO_CTRL_BIT_MODE_6; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_LOW) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_MODE_6 | - ME4000_DIO_CTRL_BIT_MODE_7 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_3); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_6 | - ME4000_DIO_CTRL_BIT_MODE_7; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp |= - ME4000_DIO_CTRL_BIT_MODE_6 | - ME4000_DIO_CTRL_BIT_MODE_7 | - ME4000_DIO_CTRL_BIT_FIFO_HIGH_3; - me4000_outl(tmp, dio_context->ctrl_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Mode %d is not available\n", - cmd.mode); - return -EINVAL; - } - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port, - cmd.mode, cmd.function); - - if ((cmd.mode == ME4000_DIO_FIFO_HIGH) - || (cmd.mode == ME4000_DIO_FIFO_LOW)) { - tmp = me4000_inl(dio_context->ctrl_reg); - tmp &= - ~(ME4000_DIO_CTRL_BIT_FUNCTION_0 | - ME4000_DIO_CTRL_BIT_FUNCTION_1); - if (cmd.function == ME4000_DIO_FUNCTION_PATTERN) { - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.function == ME4000_DIO_FUNCTION_DEMUX) { - tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_0; - me4000_outl(tmp, dio_context->ctrl_reg); - } else if (cmd.function == ME4000_DIO_FUNCTION_MUX) { - tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_1; - me4000_outl(tmp, dio_context->ctrl_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_config():Invalid port function specified\n"); - return -EINVAL; - } - } - - return 0; -} - -static int me4000_dio_set_byte(struct me4000_dio_byte *arg, - struct me4000_dio_context *dio_context) -{ - struct me4000_dio_byte cmd; - int err; - - CALL_PDEBUG("me4000_dio_set_byte() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Can't copy from user space\n"); - return -EFAULT; - } - - /* Check port parameter */ - if (cmd.port >= dio_context->dio_count) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - if (cmd.port == ME4000_DIO_PORT_A) { - if ((me4000_inl(dio_context->ctrl_reg) & 0x3) != 0x1) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n", - cmd.port); - return -EIO; - } - me4000_outl(cmd.byte, dio_context->port_0_reg); - } else if (cmd.port == ME4000_DIO_PORT_B) { - if ((me4000_inl(dio_context->ctrl_reg) & 0xC) != 0x4) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n", - cmd.port); - return -EIO; - } - me4000_outl(cmd.byte, dio_context->port_1_reg); - } else if (cmd.port == ME4000_DIO_PORT_C) { - if ((me4000_inl(dio_context->ctrl_reg) & 0x30) != 0x10) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n", - cmd.port); - return -EIO; - } - me4000_outl(cmd.byte, dio_context->port_2_reg); - } else if (cmd.port == ME4000_DIO_PORT_D) { - if ((me4000_inl(dio_context->ctrl_reg) & 0xC0) != 0x40) { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n", - cmd.port); - return -EIO; - } - me4000_outl(cmd.byte, dio_context->port_3_reg); - } else { - printk(KERN_ERR - "ME4000:me4000_dio_set_byte():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - return 0; -} - -static int me4000_dio_get_byte(struct me4000_dio_byte *arg, - struct me4000_dio_context *dio_context) -{ - struct me4000_dio_byte cmd; - int err; - - CALL_PDEBUG("me4000_dio_get_byte() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_dio_get_byte():Can't copy from user space\n"); - return -EFAULT; - } - - /* Check port parameter */ - if (cmd.port >= dio_context->dio_count) { - printk(KERN_ERR - "ME4000:me4000_dio_get_byte():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - if (cmd.port == ME4000_DIO_PORT_A) { - cmd.byte = me4000_inl(dio_context->port_0_reg) & 0xFF; - } else if (cmd.port == ME4000_DIO_PORT_B) { - cmd.byte = me4000_inl(dio_context->port_1_reg) & 0xFF; - } else if (cmd.port == ME4000_DIO_PORT_C) { - cmd.byte = me4000_inl(dio_context->port_2_reg) & 0xFF; - } else if (cmd.port == ME4000_DIO_PORT_D) { - cmd.byte = me4000_inl(dio_context->port_3_reg) & 0xFF; - } else { - printk(KERN_ERR - "ME4000:me4000_dio_get_byte():Port %d is not available\n", - cmd.port); - return -EINVAL; - } - - /* Copy result back to user */ - err = copy_to_user(arg, &cmd, sizeof(struct me4000_dio_byte)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_dio_get_byte():Can't copy to user space\n"); - return -EFAULT; - } - - return 0; -} - -static int me4000_dio_reset(struct me4000_dio_context *dio_context) -{ - CALL_PDEBUG("me4000_dio_reset() is executed\n"); - - /* Clear the control register */ - me4000_outl(0, dio_context->ctrl_reg); - - /* Check for opto isolated version */ - if (!(me4000_inl(dio_context->dir_reg) & 0x1)) { - me4000_outl(0x1, dio_context->ctrl_reg); - me4000_outl(0x0, dio_context->port_0_reg); - } - - return 0; -} - -/*------------------------------------ COUNTER STUFF ------------------------------------*/ - -static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_cnt_context *cnt_context; - - CALL_PDEBUG("me4000_cnt_ioctl() is executed\n"); - - cnt_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_CNT_READ: - return me4000_cnt_read((struct me4000_cnt *)arg, cnt_context); - case ME4000_CNT_WRITE: - return me4000_cnt_write((struct me4000_cnt *)arg, cnt_context); - case ME4000_CNT_CONFIG: - return me4000_cnt_config((struct me4000_cnt_config *)arg, - cnt_context); - case ME4000_CNT_RESET: - return me4000_cnt_reset(cnt_context); - default: - printk(KERN_ERR - "ME4000:me4000_dio_ioctl():Invalid service number %d\n", - service); - return -ENOTTY; - } - return 0; -} - -static int me4000_cnt_config(struct me4000_cnt_config *arg, - struct me4000_cnt_context *cnt_context) -{ - struct me4000_cnt_config cmd; - u8 counter; - u8 mode; - int err; - - CALL_PDEBUG("me4000_cnt_config() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt_config)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_cnt_config():Can't copy from user space\n"); - return -EFAULT; - } - - /* Check counter parameter */ - switch (cmd.counter) { - case ME4000_CNT_COUNTER_0: - counter = ME4000_CNT_CTRL_BIT_COUNTER_0; - break; - case ME4000_CNT_COUNTER_1: - counter = ME4000_CNT_CTRL_BIT_COUNTER_1; - break; - case ME4000_CNT_COUNTER_2: - counter = ME4000_CNT_CTRL_BIT_COUNTER_2; - break; - default: - printk(KERN_ERR - "ME4000:me4000_cnt_config():Counter %d is not available\n", - cmd.counter); - return -EINVAL; - } - - /* Check mode parameter */ - switch (cmd.mode) { - case ME4000_CNT_MODE_0: - mode = ME4000_CNT_CTRL_BIT_MODE_0; - break; - case ME4000_CNT_MODE_1: - mode = ME4000_CNT_CTRL_BIT_MODE_1; - break; - case ME4000_CNT_MODE_2: - mode = ME4000_CNT_CTRL_BIT_MODE_2; - break; - case ME4000_CNT_MODE_3: - mode = ME4000_CNT_CTRL_BIT_MODE_3; - break; - case ME4000_CNT_MODE_4: - mode = ME4000_CNT_CTRL_BIT_MODE_4; - break; - case ME4000_CNT_MODE_5: - mode = ME4000_CNT_CTRL_BIT_MODE_5; - break; - default: - printk(KERN_ERR - "ME4000:me4000_cnt_config():Mode %d is not available\n", - cmd.mode); - return -EINVAL; - } - - /* Write the control word */ - me4000_outb((counter | mode | 0x30), cnt_context->ctrl_reg); - - return 0; -} - -static int me4000_cnt_read(struct me4000_cnt *arg, - struct me4000_cnt_context *cnt_context) -{ - struct me4000_cnt cmd; - u8 tmp; - int err; - - CALL_PDEBUG("me4000_cnt_read() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_cnt_read():Can't copy from user space\n"); - return -EFAULT; - } - - /* Read counter */ - switch (cmd.counter) { - case ME4000_CNT_COUNTER_0: - tmp = me4000_inb(cnt_context->counter_0_reg); - cmd.value = tmp; - tmp = me4000_inb(cnt_context->counter_0_reg); - cmd.value |= ((u16) tmp) << 8; - break; - case ME4000_CNT_COUNTER_1: - tmp = me4000_inb(cnt_context->counter_1_reg); - cmd.value = tmp; - tmp = me4000_inb(cnt_context->counter_1_reg); - cmd.value |= ((u16) tmp) << 8; - break; - case ME4000_CNT_COUNTER_2: - tmp = me4000_inb(cnt_context->counter_2_reg); - cmd.value = tmp; - tmp = me4000_inb(cnt_context->counter_2_reg); - cmd.value |= ((u16) tmp) << 8; - break; - default: - printk(KERN_ERR - "ME4000:me4000_cnt_read():Counter %d is not available\n", - cmd.counter); - return -EINVAL; - } - - /* Copy result back to user */ - err = copy_to_user(arg, &cmd, sizeof(struct me4000_cnt)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_cnt_read():Can't copy to user space\n"); - return -EFAULT; - } - - return 0; -} - -static int me4000_cnt_write(struct me4000_cnt *arg, - struct me4000_cnt_context *cnt_context) -{ - struct me4000_cnt cmd; - u8 tmp; - int err; - - CALL_PDEBUG("me4000_cnt_write() is executed\n"); - - /* Copy data from user */ - err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt)); - if (err) { - printk(KERN_ERR - "ME4000:me4000_cnt_write():Can't copy from user space\n"); - return -EFAULT; - } - - /* Write counter */ - switch (cmd.counter) { - case ME4000_CNT_COUNTER_0: - tmp = cmd.value & 0xFF; - me4000_outb(tmp, cnt_context->counter_0_reg); - tmp = (cmd.value >> 8) & 0xFF; - me4000_outb(tmp, cnt_context->counter_0_reg); - break; - case ME4000_CNT_COUNTER_1: - tmp = cmd.value & 0xFF; - me4000_outb(tmp, cnt_context->counter_1_reg); - tmp = (cmd.value >> 8) & 0xFF; - me4000_outb(tmp, cnt_context->counter_1_reg); - break; - case ME4000_CNT_COUNTER_2: - tmp = cmd.value & 0xFF; - me4000_outb(tmp, cnt_context->counter_2_reg); - tmp = (cmd.value >> 8) & 0xFF; - me4000_outb(tmp, cnt_context->counter_2_reg); - break; - default: - printk(KERN_ERR - "ME4000:me4000_cnt_write():Counter %d is not available\n", - cmd.counter); - return -EINVAL; - } - - return 0; -} - -static int me4000_cnt_reset(struct me4000_cnt_context *cnt_context) -{ - CALL_PDEBUG("me4000_cnt_reset() is executed\n"); - - /* Set the mode and value for counter 0 */ - me4000_outb(0x30, cnt_context->ctrl_reg); - me4000_outb(0x00, cnt_context->counter_0_reg); - me4000_outb(0x00, cnt_context->counter_0_reg); - - /* Set the mode and value for counter 1 */ - me4000_outb(0x70, cnt_context->ctrl_reg); - me4000_outb(0x00, cnt_context->counter_1_reg); - me4000_outb(0x00, cnt_context->counter_1_reg); - - /* Set the mode and value for counter 2 */ - me4000_outb(0xB0, cnt_context->ctrl_reg); - me4000_outb(0x00, cnt_context->counter_2_reg); - me4000_outb(0x00, cnt_context->counter_2_reg); - - return 0; -} - -/*------------------------------------ External Interrupt stuff ------------------------------------*/ - -static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p, - unsigned int service, unsigned long arg) -{ - struct me4000_ext_int_context *ext_int_context; - - CALL_PDEBUG("me4000_ext_int_ioctl() is executed\n"); - - ext_int_context = file_p->private_data; - - if (_IOC_TYPE(service) != ME4000_MAGIC) { - printk(KERN_ERR "me4000_ext_int_ioctl():Wrong magic number\n"); - return -ENOTTY; - } - if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) { - printk(KERN_ERR - "me4000_ext_int_ioctl():Service number to high\n"); - return -ENOTTY; - } - - switch (service) { - case ME4000_EXT_INT_ENABLE: - return me4000_ext_int_enable(ext_int_context); - case ME4000_EXT_INT_DISABLE: - return me4000_ext_int_disable(ext_int_context); - case ME4000_EXT_INT_COUNT: - return me4000_ext_int_count((unsigned long *)arg, - ext_int_context); - default: - printk(KERN_ERR - "ME4000:me4000_ext_int_ioctl():Invalid service number %d\n", - service); - return -ENOTTY; - } - return 0; -} - -static int me4000_ext_int_enable(struct me4000_ext_int_context *ext_int_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ext_int_enable() is executed\n"); - - tmp = me4000_inl(ext_int_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_EX_IRQ; - me4000_outl(tmp, ext_int_context->ctrl_reg); - - return 0; -} - -static int me4000_ext_int_disable(struct me4000_ext_int_context *ext_int_context) -{ - unsigned long tmp; - - CALL_PDEBUG("me4000_ext_int_disable() is executed\n"); - - tmp = me4000_inl(ext_int_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ; - me4000_outl(tmp, ext_int_context->ctrl_reg); - - return 0; -} - -static int me4000_ext_int_count(unsigned long *arg, - struct me4000_ext_int_context *ext_int_context) -{ - - CALL_PDEBUG("me4000_ext_int_count() is executed\n"); - - put_user(ext_int_context->int_count, arg); - return 0; -} - -/*------------------------------------ General stuff ------------------------------------*/ - -static int me4000_get_user_info(struct me4000_user_info *arg, - struct me4000_info *board_info) -{ - struct me4000_user_info user_info; - - CALL_PDEBUG("me4000_get_user_info() is executed\n"); - - user_info.board_count = board_info->board_count; - user_info.plx_regbase = board_info->plx_regbase; - user_info.plx_regbase_size = board_info->plx_regbase_size; - user_info.me4000_regbase = board_info->me4000_regbase; - user_info.me4000_regbase_size = board_info->me4000_regbase_size; - user_info.serial_no = board_info->serial_no; - user_info.hw_revision = board_info->hw_revision; - user_info.vendor_id = board_info->vendor_id; - user_info.device_id = board_info->device_id; - user_info.pci_bus_no = board_info->pci_bus_no; - user_info.pci_dev_no = board_info->pci_dev_no; - user_info.pci_func_no = board_info->pci_func_no; - user_info.irq = board_info->irq; - user_info.irq_count = board_info->irq_count; - user_info.driver_version = ME4000_DRIVER_VERSION; - user_info.ao_count = board_info->board_p->ao.count; - user_info.ao_fifo_count = board_info->board_p->ao.fifo_count; - - user_info.ai_count = board_info->board_p->ai.count; - user_info.ai_sh_count = board_info->board_p->ai.sh_count; - user_info.ai_ex_trig_analog = board_info->board_p->ai.ex_trig_analog; - - user_info.dio_count = board_info->board_p->dio.count; - - user_info.cnt_count = board_info->board_p->cnt.count; - - if (copy_to_user(arg, &user_info, sizeof(struct me4000_user_info))) - return -EFAULT; - - return 0; -} - -/*------------------------------------ ISR STUFF ------------------------------------*/ - -static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode) -{ - int result = 0; - struct me4000_ext_int_context *ext_int_context; - - CALL_PDEBUG("me4000_ext_int_fasync() is executed\n"); - - ext_int_context = file_ptr->private_data; - - result = - fasync_helper(fd, file_ptr, mode, &ext_int_context->fasync_ptr); - - CALL_PDEBUG("me4000_ext_int_fasync() is leaved\n"); - return result; -} - -static irqreturn_t me4000_ao_isr(int irq, void *dev_id) -{ - u32 tmp; - u32 value; - struct me4000_ao_context *ao_context; - int i; - int c = 0; - int c1 = 0; - - ISR_PDEBUG("me4000_ao_isr() is executed\n"); - - ao_context = dev_id; - - /* Check if irq number is right */ - if (irq != ao_context->irq) { - ISR_PDEBUG("me4000_ao_isr():incorrect interrupt num: %d\n", - irq); - return IRQ_NONE; - } - - /* Check if this DAC rised an interrupt */ - if (! - ((0x1 << (ao_context->index + 3)) & - me4000_inl(ao_context->irq_status_reg))) { - ISR_PDEBUG("me4000_ao_isr():Not this DAC\n"); - return IRQ_NONE; - } - - /* Read status register to find out what happened */ - tmp = me4000_inl(ao_context->status_reg); - - if (!(tmp & ME4000_AO_STATUS_BIT_EF) && (tmp & ME4000_AO_STATUS_BIT_HF) - && (tmp & ME4000_AO_STATUS_BIT_HF)) { - c = ME4000_AO_FIFO_COUNT; - ISR_PDEBUG("me4000_ao_isr():Fifo empty\n"); - } else if ((tmp & ME4000_AO_STATUS_BIT_EF) - && (tmp & ME4000_AO_STATUS_BIT_HF) - && (tmp & ME4000_AO_STATUS_BIT_HF)) { - c = ME4000_AO_FIFO_COUNT / 2; - ISR_PDEBUG("me4000_ao_isr():Fifo under half full\n"); - } else { - c = 0; - ISR_PDEBUG("me4000_ao_isr():Fifo full\n"); - } - - ISR_PDEBUG("me4000_ao_isr():Try to write 0x%04X values\n", c); - - while (1) { - c1 = me4000_values_to_end(ao_context->circ_buf, - ME4000_AO_BUFFER_COUNT); - ISR_PDEBUG("me4000_ao_isr():Values to end = %d\n", c1); - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - ISR_PDEBUG - ("me4000_ao_isr():Work done or buffer empty\n"); - break; - } - if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) || - ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) { - for (i = 0; i < c1; i++) { - value = - ((u32) - (* - (ao_context->circ_buf.buf + - ao_context->circ_buf.tail + i))) << 16; - outl(value, ao_context->fifo_reg); - } - } else - outsw(ao_context->fifo_reg, - ao_context->circ_buf.buf + - ao_context->circ_buf.tail, c1); - - - ao_context->circ_buf.tail = - (ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT - - 1); - ISR_PDEBUG("me4000_ao_isr():%d values wrote to port 0x%04X\n", - c1, ao_context->fifo_reg); - c -= c1; - } - - /* If there are no values left in the buffer, disable interrupts */ - spin_lock(&ao_context->int_lock); - if (!me4000_buf_count(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) { - ISR_PDEBUG - ("me4000_ao_isr():Disable Interrupt because no values left in buffer\n"); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ; - me4000_outl(tmp, ao_context->ctrl_reg); - } - spin_unlock(&ao_context->int_lock); - - /* Reset the interrupt */ - spin_lock(&ao_context->int_lock); - tmp = me4000_inl(ao_context->ctrl_reg); - tmp |= ME4000_AO_CTRL_BIT_RESET_IRQ; - me4000_outl(tmp, ao_context->ctrl_reg); - tmp &= ~ME4000_AO_CTRL_BIT_RESET_IRQ; - me4000_outl(tmp, ao_context->ctrl_reg); - - /* If state machine is stopped, flow was interrupted */ - if (!(me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM)) { - printk(KERN_ERR "ME4000:me4000_ao_isr():Broken pipe\n"); - /* Set flag in order to inform write routine */ - ao_context->pipe_flag = 1; - /* Disable interrupt */ - tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ; - } - me4000_outl(tmp, ao_context->ctrl_reg); - spin_unlock(&ao_context->int_lock); - - /* Wake up waiting process */ - wake_up_interruptible(&(ao_context->wait_queue)); - - /* Count the interrupt */ - ao_context->board_info->irq_count++; - - return IRQ_HANDLED; -} - -static irqreturn_t me4000_ai_isr(int irq, void *dev_id) -{ - u32 tmp; - struct me4000_ai_context *ai_context; - int i; - int c = 0; - int c1 = 0; -#ifdef ME4000_ISR_DEBUG - unsigned long before; - unsigned long after; -#endif - - ISR_PDEBUG("me4000_ai_isr() is executed\n"); - -#ifdef ME4000_ISR_DEBUG - rdtscl(before); -#endif - - ai_context = dev_id; - - /* Check if irq number is right */ - if (irq != ai_context->irq) { - ISR_PDEBUG("me4000_ai_isr():incorrect interrupt num: %d\n", - irq); - return IRQ_NONE; - } - - if (me4000_inl(ai_context->irq_status_reg) & - ME4000_IRQ_STATUS_BIT_AI_HF) { - ISR_PDEBUG - ("me4000_ai_isr():Fifo half full interrupt occured\n"); - - /* Read status register to find out what happened */ - tmp = me4000_inl(ai_context->ctrl_reg); - - if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && - !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG("me4000_ai_isr():Fifo full\n"); - c = ME4000_AI_FIFO_COUNT; - - /* FIFO overflow, so stop conversion and disable all interrupts */ - spin_lock(&ai_context->int_lock); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; - tmp &= - ~(ME4000_AI_CTRL_BIT_HF_IRQ | - ME4000_AI_CTRL_BIT_SC_IRQ); - outl(tmp, ai_context->ctrl_reg); - spin_unlock(&ai_context->int_lock); - } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) && - !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG("me4000_ai_isr():Fifo half full\n"); - c = ME4000_AI_FIFO_COUNT / 2; - } else { - c = 0; - ISR_PDEBUG - ("me4000_ai_isr():Can't determine state of fifo\n"); - } - - ISR_PDEBUG("me4000_ai_isr():Try to read %d values\n", c); - - while (1) { - c1 = me4000_space_to_end(ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT); - ISR_PDEBUG("me4000_ai_isr():Space to end = %d\n", c1); - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - ISR_PDEBUG - ("me4000_ai_isr():Work done or buffer full\n"); - break; - } - - insw(ai_context->data_reg, - ai_context->circ_buf.buf + - ai_context->circ_buf.head, c1); - ai_context->circ_buf.head = - (ai_context->circ_buf.head + - c1) & (ME4000_AI_BUFFER_COUNT - 1); - c -= c1; - } - - /* Work is done, so reset the interrupt */ - ISR_PDEBUG - ("me4000_ai_isr():reset interrupt fifo half full interrupt\n"); - spin_lock(&ai_context->int_lock); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - me4000_outl(tmp, ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock(&ai_context->int_lock); - } - - if (me4000_inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { - ISR_PDEBUG - ("me4000_ai_isr():Sample counter interrupt occured\n"); - - if (!ai_context->sample_counter_reload) { - ISR_PDEBUG - ("me4000_ai_isr():Single data block available\n"); - - /* Poll data until fifo empty */ - for (i = 0; - (i < ME4000_AI_FIFO_COUNT / 2) - && (inl(ai_context->ctrl_reg) & - ME4000_AI_STATUS_BIT_EF_DATA); i++) { - if (me4000_space_to_end - (ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT)) { - *(ai_context->circ_buf.buf + - ai_context->circ_buf.head) = - inw(ai_context->data_reg); - ai_context->circ_buf.head = - (ai_context->circ_buf.head + - 1) & (ME4000_AI_BUFFER_COUNT - 1); - } else - break; - } - ISR_PDEBUG("me4000_ai_isr():%d values read\n", i); - } else { - if (ai_context->sample_counter <= - ME4000_AI_FIFO_COUNT / 2) { - ISR_PDEBUG - ("me4000_ai_isr():Interrupt from adjustable half full threshold\n"); - - /* Read status register to find out what happened */ - tmp = me4000_inl(ai_context->ctrl_reg); - - if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && - !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG - ("me4000_ai_isr():Fifo full\n"); - c = ME4000_AI_FIFO_COUNT; - - /* FIFO overflow, so stop conversion */ - spin_lock(&ai_context->int_lock); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= - ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, ai_context->ctrl_reg); - spin_unlock(&ai_context->int_lock); - } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) - && !(tmp & - ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & - ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG - ("me4000_ai_isr():Fifo half full\n"); - c = ME4000_AI_FIFO_COUNT / 2; - } else { - c = ai_context->sample_counter; - ISR_PDEBUG - ("me4000_ai_isr():Sample count values\n"); - } - - ISR_PDEBUG - ("me4000_ai_isr():Try to read %d values\n", - c); - - while (1) { - c1 = me4000_space_to_end(ai_context-> - circ_buf, - ME4000_AI_BUFFER_COUNT); - ISR_PDEBUG - ("me4000_ai_isr():Space to end = %d\n", - c1); - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - ISR_PDEBUG - ("me4000_ai_isr():Work done or buffer full\n"); - break; - } - - insw(ai_context->data_reg, - ai_context->circ_buf.buf + - ai_context->circ_buf.head, c1); - ai_context->circ_buf.head = - (ai_context->circ_buf.head + - c1) & (ME4000_AI_BUFFER_COUNT - 1); - c -= c1; - } - } else { - ISR_PDEBUG - ("me4000_ai_isr():Multiple data block available\n"); - - /* Read status register to find out what happened */ - tmp = me4000_inl(ai_context->ctrl_reg); - - if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) && - !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG - ("me4000_ai_isr():Fifo full\n"); - c = ME4000_AI_FIFO_COUNT; - - /* FIFO overflow, so stop conversion */ - spin_lock(&ai_context->int_lock); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= - ME4000_AI_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, ai_context->ctrl_reg); - spin_unlock(&ai_context->int_lock); - - while (1) { - c1 = me4000_space_to_end - (ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT); - ISR_PDEBUG - ("me4000_ai_isr():Space to end = %d\n", - c1); - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - ISR_PDEBUG - ("me4000_ai_isr():Work done or buffer full\n"); - break; - } - - insw(ai_context->data_reg, - ai_context->circ_buf.buf + - ai_context->circ_buf.head, - c1); - ai_context->circ_buf.head = - (ai_context->circ_buf.head + - c1) & - (ME4000_AI_BUFFER_COUNT - - 1); - c -= c1; - } - } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) - && !(tmp & - ME4000_AI_STATUS_BIT_HF_DATA) - && (tmp & - ME4000_AI_STATUS_BIT_EF_DATA)) { - ISR_PDEBUG - ("me4000_ai_isr():Fifo half full\n"); - c = ME4000_AI_FIFO_COUNT / 2; - - while (1) { - c1 = me4000_space_to_end - (ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT); - ISR_PDEBUG - ("me4000_ai_isr():Space to end = %d\n", - c1); - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - ISR_PDEBUG - ("me4000_ai_isr():Work done or buffer full\n"); - break; - } - - insw(ai_context->data_reg, - ai_context->circ_buf.buf + - ai_context->circ_buf.head, - c1); - ai_context->circ_buf.head = - (ai_context->circ_buf.head + - c1) & - (ME4000_AI_BUFFER_COUNT - - 1); - c -= c1; - } - } else { - /* Poll data until fifo empty */ - for (i = 0; - (i < ME4000_AI_FIFO_COUNT / 2) - && (inl(ai_context->ctrl_reg) & - ME4000_AI_STATUS_BIT_EF_DATA); - i++) { - if (me4000_space_to_end - (ai_context->circ_buf, - ME4000_AI_BUFFER_COUNT)) { - *(ai_context->circ_buf. - buf + - ai_context->circ_buf. - head) = - inw(ai_context->data_reg); - ai_context->circ_buf. - head = - (ai_context-> - circ_buf.head + - 1) & - (ME4000_AI_BUFFER_COUNT - - 1); - } else - break; - } - ISR_PDEBUG - ("me4000_ai_isr():%d values read\n", - i); - } - } - } - - /* Work is done, so reset the interrupt */ - ISR_PDEBUG - ("me4000_ai_isr():reset interrupt from sample counter\n"); - spin_lock(&ai_context->int_lock); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - me4000_outl(tmp, ai_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET; - me4000_outl(tmp, ai_context->ctrl_reg); - spin_unlock(&ai_context->int_lock); - } - - /* Values are now available, so wake up waiting process */ - if (me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) { - ISR_PDEBUG("me4000_ai_isr():Wake up waiting process\n"); - wake_up_interruptible(&(ai_context->wait_queue)); - } - - /* If there is no space left in the buffer, disable interrupts */ - spin_lock(&ai_context->int_lock); - if (!me4000_buf_space(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) { - ISR_PDEBUG - ("me4000_ai_isr():Disable Interrupt because no space left in buffer\n"); - tmp = me4000_inl(ai_context->ctrl_reg); - tmp &= - ~(ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ | - ME4000_AI_CTRL_BIT_LE_IRQ); - me4000_outl(tmp, ai_context->ctrl_reg); - } - spin_unlock(&ai_context->int_lock); - -#ifdef ME4000_ISR_DEBUG - rdtscl(after); - printk(KERN_ERR "ME4000:me4000_ai_isr():Time lapse = %lu\n", - after - before); -#endif - - return IRQ_HANDLED; -} - -static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id) -{ - struct me4000_ext_int_context *ext_int_context; - unsigned long tmp; - - ISR_PDEBUG("me4000_ext_int_isr() is executed\n"); - - ext_int_context = dev_id; - - /* Check if irq number is right */ - if (irq != ext_int_context->irq) { - ISR_PDEBUG("me4000_ext_int_isr():incorrect interrupt num: %d\n", - irq); - return IRQ_NONE; - } - - if (me4000_inl(ext_int_context->irq_status_reg) & - ME4000_IRQ_STATUS_BIT_EX) { - ISR_PDEBUG("me4000_ext_int_isr():External interrupt occured\n"); - tmp = me4000_inl(ext_int_context->ctrl_reg); - tmp |= ME4000_AI_CTRL_BIT_EX_IRQ_RESET; - me4000_outl(tmp, ext_int_context->ctrl_reg); - tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ_RESET; - me4000_outl(tmp, ext_int_context->ctrl_reg); - - ext_int_context->int_count++; - - if (ext_int_context->fasync_ptr) { - ISR_PDEBUG - ("me2600_ext_int_isr():Send signal to process\n"); - kill_fasync(&ext_int_context->fasync_ptr, SIGIO, - POLL_IN); - } - } - - return IRQ_HANDLED; -} - -static void __exit me4000_module_exit(void) -{ - struct me4000_info *board_info; - - CALL_PDEBUG("cleanup_module() is executed\n"); - - unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME); - - unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME); - - unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME); - - unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME); - - unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME); - - remove_proc_entry("me4000", NULL); - - pci_unregister_driver(&me4000_driver); - - /* Reset the boards */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - me4000_reset_board(board_info); - } - - clear_board_info_list(); -} - -module_exit(me4000_module_exit); - -static int me4000_read_procmem(char *buf, char **start, off_t offset, int count, - int *eof, void *data) -{ - int len = 0; - int limit = count - 1000; - struct me4000_info *board_info; - - len += sprintf(buf + len, "\nME4000 DRIVER VERSION %X.%X.%X\n\n", - (ME4000_DRIVER_VERSION & 0xFF0000) >> 16, - (ME4000_DRIVER_VERSION & 0xFF00) >> 8, - (ME4000_DRIVER_VERSION & 0xFF)); - - /* Search for the board context */ - list_for_each_entry(board_info, &me4000_board_info_list, list) { - len += - sprintf(buf + len, "Board number %d:\n", - board_info->board_count); - len += sprintf(buf + len, "---------------\n"); - len += - sprintf(buf + len, "PLX base register = 0x%lX\n", - board_info->plx_regbase); - len += - sprintf(buf + len, "PLX base register size = 0x%X\n", - (unsigned int)board_info->plx_regbase_size); - len += - sprintf(buf + len, "ME4000 base register = 0x%X\n", - (unsigned int)board_info->me4000_regbase); - len += - sprintf(buf + len, "ME4000 base register size = 0x%X\n", - (unsigned int)board_info->me4000_regbase_size); - len += - sprintf(buf + len, "Serial number = 0x%X\n", - board_info->serial_no); - len += - sprintf(buf + len, "Hardware revision = 0x%X\n", - board_info->hw_revision); - len += - sprintf(buf + len, "Vendor id = 0x%X\n", - board_info->vendor_id); - len += - sprintf(buf + len, "Device id = 0x%X\n", - board_info->device_id); - len += - sprintf(buf + len, "PCI bus number = %d\n", - board_info->pci_bus_no); - len += - sprintf(buf + len, "PCI device number = %d\n", - board_info->pci_dev_no); - len += - sprintf(buf + len, "PCI function number = %d\n", - board_info->pci_func_no); - len += sprintf(buf + len, "IRQ = %u\n", board_info->irq); - len += - sprintf(buf + len, - "Count of interrupts since module was loaded = %d\n", - board_info->irq_count); - - len += - sprintf(buf + len, "Count of analog outputs = %d\n", - board_info->board_p->ao.count); - len += - sprintf(buf + len, "Count of analog output fifos = %d\n", - board_info->board_p->ao.fifo_count); - - len += - sprintf(buf + len, "Count of analog inputs = %d\n", - board_info->board_p->ai.count); - len += - sprintf(buf + len, - "Count of sample and hold devices for analog input = %d\n", - board_info->board_p->ai.sh_count); - len += - sprintf(buf + len, - "Analog external trigger available for analog input = %d\n", - board_info->board_p->ai.ex_trig_analog); - - len += - sprintf(buf + len, "Count of digital ports = %d\n", - board_info->board_p->dio.count); - - len += - sprintf(buf + len, "Count of counter devices = %d\n", - board_info->board_p->cnt.count); - len += - sprintf(buf + len, "AI control register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AI_CTRL_REG)); - - len += sprintf(buf + len, "AO 0 control register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_00_CTRL_REG)); - len += - sprintf(buf + len, "AO 0 status register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_00_STATUS_REG)); - len += - sprintf(buf + len, "AO 1 control register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_01_CTRL_REG)); - len += - sprintf(buf + len, "AO 1 status register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_01_STATUS_REG)); - len += - sprintf(buf + len, "AO 2 control register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_02_CTRL_REG)); - len += - sprintf(buf + len, "AO 2 status register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_02_STATUS_REG)); - len += - sprintf(buf + len, "AO 3 control register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_03_CTRL_REG)); - len += - sprintf(buf + len, "AO 3 status register = 0x%08X\n", - inl(board_info->me4000_regbase + - ME4000_AO_03_STATUS_REG)); - if (len >= limit) - break; - } - - *eof = 1; - return len; -} diff --git a/drivers/staging/me4000/me4000.h b/drivers/staging/me4000/me4000.h deleted file mode 100644 index 81c6f4d5e25..00000000000 --- a/drivers/staging/me4000/me4000.h +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : me4000.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _ME4000_H_ -#define _ME4000_H_ - -#ifdef __KERNEL__ - -/*============================================================================= - The version of the driver release - ===========================================================================*/ - -#define ME4000_DRIVER_VERSION 0x10009 // Version 1.00.09 - -/*============================================================================= - Debug section - ===========================================================================*/ - -#undef ME4000_CALL_DEBUG // Debug function entry and exit -#undef ME4000_ISR_DEBUG // Debug the interrupt service routine -#undef ME4000_PORT_DEBUG // Debug port access -#undef ME4000_DEBUG // General purpose debug masseges - -#ifdef ME4000_CALL_DEBUG -#undef CALL_PDEBUG -#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args) -#else -# define CALL_PDEBUG(fmt, args...) // no debugging, do nothing -#endif - -#ifdef ME4000_ISR_DEBUG -#undef ISR_PDEBUG -#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args) -#else -#define ISR_PDEBUG(fmt, args...) // no debugging, do nothing -#endif - -#ifdef ME4000_PORT_DEBUG -#undef PORT_PDEBUG -#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args) -#else -#define PORT_PDEBUG(fmt, args...) // no debugging, do nothing -#endif - -#ifdef ME4000_DEBUG -#undef PDEBUG -#define PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args) -#else -#define PDEBUG(fmt, args...) // no debugging, do nothing -#endif - -/*============================================================================= - PCI vendor and device IDs - ===========================================================================*/ - -#define PCI_VENDOR_ID_MEILHAUS 0x1402 - -#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version - -#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 // Isolated version with Sample and Hold - -#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 // Isolated version with Sample and Hold - -#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 // Isolated version with Sample and Hold - -/*============================================================================= - Device names, for entries in /proc/.. - ===========================================================================*/ - -#define ME4000_NAME "me4000" -#define ME4000_AO_NAME "me4000_ao" -#define ME4000_AI_NAME "me4000_ai" -#define ME4000_DIO_NAME "me4000_dio" -#define ME4000_CNT_NAME "me4000_cnt" -#define ME4000_EXT_INT_NAME "me4000_ext_int" - -/*============================================================================= - ME-4000 base register offsets - ===========================================================================*/ - -#define ME4000_AO_00_CTRL_REG 0x00 // R/W -#define ME4000_AO_00_STATUS_REG 0x04 // R/_ -#define ME4000_AO_00_FIFO_REG 0x08 // _/W -#define ME4000_AO_00_SINGLE_REG 0x0C // R/W -#define ME4000_AO_00_TIMER_REG 0x10 // _/W - -#define ME4000_AO_01_CTRL_REG 0x18 // R/W -#define ME4000_AO_01_STATUS_REG 0x1C // R/_ -#define ME4000_AO_01_FIFO_REG 0x20 // _/W -#define ME4000_AO_01_SINGLE_REG 0x24 // R/W -#define ME4000_AO_01_TIMER_REG 0x28 // _/W - -#define ME4000_AO_02_CTRL_REG 0x30 // R/W -#define ME4000_AO_02_STATUS_REG 0x34 // R/_ -#define ME4000_AO_02_FIFO_REG 0x38 // _/W -#define ME4000_AO_02_SINGLE_REG 0x3C // R/W -#define ME4000_AO_02_TIMER_REG 0x40 // _/W - -#define ME4000_AO_03_CTRL_REG 0x48 // R/W -#define ME4000_AO_03_STATUS_REG 0x4C // R/_ -#define ME4000_AO_03_FIFO_REG 0x50 // _/W -#define ME4000_AO_03_SINGLE_REG 0x54 // R/W -#define ME4000_AO_03_TIMER_REG 0x58 // _/W - -#define ME4000_AI_CTRL_REG 0x74 // _/W -#define ME4000_AI_STATUS_REG 0x74 // R/_ -#define ME4000_AI_CHANNEL_LIST_REG 0x78 // _/W -#define ME4000_AI_DATA_REG 0x7C // R/_ -#define ME4000_AI_CHAN_TIMER_REG 0x80 // _/W -#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 // _/W -#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 // _/W -#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8C // _/W -#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 // _/W -#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 // _/W -#define ME4000_AI_START_REG 0x98 // R/_ - -#define ME4000_IRQ_STATUS_REG 0x9C // R/_ - -#define ME4000_DIO_PORT_0_REG 0xA0 // R/W -#define ME4000_DIO_PORT_1_REG 0xA4 // R/W -#define ME4000_DIO_PORT_2_REG 0xA8 // R/W -#define ME4000_DIO_PORT_3_REG 0xAC // R/W -#define ME4000_DIO_DIR_REG 0xB0 // R/W - -#define ME4000_AO_LOADSETREG_XX 0xB4 // R/W - -#define ME4000_DIO_CTRL_REG 0xB8 // R/W - -#define ME4000_AO_DEMUX_ADJUST_REG 0xBC // -/W - -#define ME4000_AI_SAMPLE_COUNTER_REG 0xC0 // _/W - -/*============================================================================= - Value to adjust Demux - ===========================================================================*/ - -#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C - -/*============================================================================= - Counter base register offsets - ===========================================================================*/ - -#define ME4000_CNT_COUNTER_0_REG 0x00 -#define ME4000_CNT_COUNTER_1_REG 0x01 -#define ME4000_CNT_COUNTER_2_REG 0x02 -#define ME4000_CNT_CTRL_REG 0x03 - -/*============================================================================= - PLX base register offsets - ===========================================================================*/ - -#define PLX_INTCSR 0x4C // Interrupt control and status register -#define PLX_ICR 0x50 // Initialization control register - -/*============================================================================= - Bits for the PLX_ICSR register - ===========================================================================*/ - -#define PLX_INTCSR_LOCAL_INT1_EN 0x01 // If set, local interrupt 1 is enabled (r/w) -#define PLX_INTCSR_LOCAL_INT1_POL 0x02 // If set, local interrupt 1 polarity is active high (r/w) -#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 // If set, local interrupt 1 is active (r/_) -#define PLX_INTCSR_LOCAL_INT2_EN 0x08 // If set, local interrupt 2 is enabled (r/w) -#define PLX_INTCSR_LOCAL_INT2_POL 0x10 // If set, local interrupt 2 polarity is active high (r/w) -#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 // If set, local interrupt 2 is active (r/_) -#define PLX_INTCSR_PCI_INT_EN 0x40 // If set, PCI interrupt is enabled (r/w) -#define PLX_INTCSR_SOFT_INT 0x80 // If set, a software interrupt is generated (r/w) - -/*============================================================================= - Bits for the PLX_ICR register - ===========================================================================*/ - -#define PLX_ICR_BIT_EEPROM_CLOCK_SET 0x01000000 -#define PLX_ICR_BIT_EEPROM_CHIP_SELECT 0x02000000 -#define PLX_ICR_BIT_EEPROM_WRITE 0x04000000 -#define PLX_ICR_BIT_EEPROM_READ 0x08000000 -#define PLX_ICR_BIT_EEPROM_VALID 0x10000000 - -#define PLX_ICR_MASK_EEPROM 0x1F000000 - -#define EEPROM_DELAY 1 - -/*============================================================================= - Bits for the ME4000_AO_CTRL_REG register - ===========================================================================*/ - -#define ME4000_AO_CTRL_BIT_MODE_0 0x001 -#define ME4000_AO_CTRL_BIT_MODE_1 0x002 -#define ME4000_AO_CTRL_MASK_MODE 0x003 -#define ME4000_AO_CTRL_BIT_STOP 0x004 -#define ME4000_AO_CTRL_BIT_ENABLE_FIFO 0x008 -#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010 -#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020 -#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080 -#define ME4000_AO_CTRL_BIT_ENABLE_DO 0x100 -#define ME4000_AO_CTRL_BIT_ENABLE_IRQ 0x200 -#define ME4000_AO_CTRL_BIT_RESET_IRQ 0x400 -#define ME4000_AO_CTRL_BIT_EX_TRIG_BOTH 0x800 - -/*============================================================================= - Bits for the ME4000_AO_STATUS_REG register - ===========================================================================*/ - -#define ME4000_AO_STATUS_BIT_FSM 0x01 -#define ME4000_AO_STATUS_BIT_FF 0x02 -#define ME4000_AO_STATUS_BIT_HF 0x04 -#define ME4000_AO_STATUS_BIT_EF 0x08 - -/*============================================================================= - Bits for the ME4000_AI_CTRL_REG register - ===========================================================================*/ - -#define ME4000_AI_CTRL_BIT_MODE_0 0x00000001 -#define ME4000_AI_CTRL_BIT_MODE_1 0x00000002 -#define ME4000_AI_CTRL_BIT_MODE_2 0x00000004 -#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD 0x00000008 -#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP 0x00000010 -#define ME4000_AI_CTRL_BIT_STOP 0x00000020 -#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO 0x00000040 -#define ME4000_AI_CTRL_BIT_DATA_FIFO 0x00000080 -#define ME4000_AI_CTRL_BIT_FULLSCALE 0x00000100 -#define ME4000_AI_CTRL_BIT_OFFSET 0x00000200 -#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG 0x00000400 -#define ME4000_AI_CTRL_BIT_EX_TRIG 0x00000800 -#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING 0x00001000 -#define ME4000_AI_CTRL_BIT_EX_IRQ 0x00002000 -#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET 0x00004000 -#define ME4000_AI_CTRL_BIT_LE_IRQ 0x00008000 -#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET 0x00010000 -#define ME4000_AI_CTRL_BIT_HF_IRQ 0x00020000 -#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET 0x00040000 -#define ME4000_AI_CTRL_BIT_SC_IRQ 0x00080000 -#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET 0x00100000 -#define ME4000_AI_CTRL_BIT_SC_RELOAD 0x00200000 -#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH 0x80000000 - -/*============================================================================= - Bits for the ME4000_AI_STATUS_REG register - ===========================================================================*/ - -#define ME4000_AI_STATUS_BIT_EF_CHANNEL 0x00400000 -#define ME4000_AI_STATUS_BIT_HF_CHANNEL 0x00800000 -#define ME4000_AI_STATUS_BIT_FF_CHANNEL 0x01000000 -#define ME4000_AI_STATUS_BIT_EF_DATA 0x02000000 -#define ME4000_AI_STATUS_BIT_HF_DATA 0x04000000 -#define ME4000_AI_STATUS_BIT_FF_DATA 0x08000000 -#define ME4000_AI_STATUS_BIT_LE 0x10000000 -#define ME4000_AI_STATUS_BIT_FSM 0x20000000 - -/*============================================================================= - Bits for the ME4000_IRQ_STATUS_REG register - ===========================================================================*/ - -#define ME4000_IRQ_STATUS_BIT_EX 0x01 -#define ME4000_IRQ_STATUS_BIT_LE 0x02 -#define ME4000_IRQ_STATUS_BIT_AI_HF 0x04 -#define ME4000_IRQ_STATUS_BIT_AO_0_HF 0x08 -#define ME4000_IRQ_STATUS_BIT_AO_1_HF 0x10 -#define ME4000_IRQ_STATUS_BIT_AO_2_HF 0x20 -#define ME4000_IRQ_STATUS_BIT_AO_3_HF 0x40 -#define ME4000_IRQ_STATUS_BIT_SC 0x80 - -/*============================================================================= - Bits for the ME4000_DIO_CTRL_REG register - ===========================================================================*/ - -#define ME4000_DIO_CTRL_BIT_MODE_0 0X0001 -#define ME4000_DIO_CTRL_BIT_MODE_1 0X0002 -#define ME4000_DIO_CTRL_BIT_MODE_2 0X0004 -#define ME4000_DIO_CTRL_BIT_MODE_3 0X0008 -#define ME4000_DIO_CTRL_BIT_MODE_4 0X0010 -#define ME4000_DIO_CTRL_BIT_MODE_5 0X0020 -#define ME4000_DIO_CTRL_BIT_MODE_6 0X0040 -#define ME4000_DIO_CTRL_BIT_MODE_7 0X0080 - -#define ME4000_DIO_CTRL_BIT_FUNCTION_0 0X0100 -#define ME4000_DIO_CTRL_BIT_FUNCTION_1 0X0200 - -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 0X0400 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 0X0800 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 0X1000 -#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 0X2000 - -/*============================================================================= - Bits for the ME4000_CNT_CTRL_REG register - ===========================================================================*/ - -#define ME4000_CNT_CTRL_BIT_COUNTER_0 0x00 -#define ME4000_CNT_CTRL_BIT_COUNTER_1 0x40 -#define ME4000_CNT_CTRL_BIT_COUNTER_2 0x80 - -#define ME4000_CNT_CTRL_BIT_MODE_0 0x00 // Change state if zero crossing -#define ME4000_CNT_CTRL_BIT_MODE_1 0x02 // Retriggerable One-Shot -#define ME4000_CNT_CTRL_BIT_MODE_2 0x04 // Asymmetrical divider -#define ME4000_CNT_CTRL_BIT_MODE_3 0x06 // Symmetrical divider -#define ME4000_CNT_CTRL_BIT_MODE_4 0x08 // Counter start by software trigger -#define ME4000_CNT_CTRL_BIT_MODE_5 0x0A // Counter start by hardware trigger - -/*============================================================================= - Extract information from minor device number - ===========================================================================*/ - -#define AO_BOARD(dev) ((MINOR(dev) >> 6) & 0x3) -#define AO_PORT(dev) ((MINOR(dev) >> 2) & 0xF) -#define AO_MODE(dev) (MINOR(dev) & 0x3) - -#define AI_BOARD(dev) ((MINOR(dev) >> 3) & 0x1F) -#define AI_MODE(dev) (MINOR(dev) & 0x7) - -#define DIO_BOARD(dev) (MINOR(dev)) - -#define CNT_BOARD(dev) (MINOR(dev)) - -#define EXT_INT_BOARD(dev) (MINOR(dev)) - -/*============================================================================= - Circular buffer used for analog input/output reads/writes. - ===========================================================================*/ - -struct me4000_circ_buf { - s16 *buf; - int volatile head; - int volatile tail; -}; - -/*============================================================================= - Information about the hardware capabilities - ===========================================================================*/ - -struct me4000_ao_info { - int count; - int fifo_count; -}; - -struct me4000_ai_info { - int count; - int sh_count; - int diff_count; - int ex_trig_analog; -}; - -struct me4000_dio_info { - int count; -}; - -struct me4000_cnt_info { - int count; -}; - -struct me4000_board { - u16 vendor_id; - u16 device_id; - struct me4000_ao_info ao; - struct me4000_ai_info ai; - struct me4000_dio_info dio; - struct me4000_cnt_info cnt; -}; - -static struct me4000_board me4000_boards[] = { - {PCI_VENDOR_ID_MEILHAUS, 0x4610, {0, 0}, {16, 0, 0, 0}, {4}, {3}}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4660, {2, 0}, {16, 0, 0, 0}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4661, {2, 0}, {16, 0, 0, 0}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4662, {2, 0}, {16, 8, 0, 0}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4663, {2, 0}, {16, 8, 0, 0}, {4}, {3}}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}}, - {PCI_VENDOR_ID_MEILHAUS, 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}}, - - {0}, -}; - -/*============================================================================= - PCI device table. - This is used by modprobe to translate PCI IDs to drivers. - ===========================================================================*/ - -static struct pci_device_id me4000_pci_table[] __devinitdata = { - {PCI_VENDOR_ID_MEILHAUS, 0x4610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - - {0} -}; - -MODULE_DEVICE_TABLE(pci, me4000_pci_table); - -/*============================================================================= - Global board and subdevice information structures - ===========================================================================*/ - -struct me4000_info { - struct list_head list; // List of all detected boards - int board_count; // Index of the board after detection - - unsigned long plx_regbase; // PLX configuration space base address - resource_size_t me4000_regbase; // Base address of the ME4000 - resource_size_t timer_regbase; // Base address of the timer circuit - resource_size_t program_regbase; // Base address to set the program pin for the xilinx - - unsigned long plx_regbase_size; // PLX register set space - resource_size_t me4000_regbase_size; // ME4000 register set space - resource_size_t timer_regbase_size; // Timer circuit register set space - resource_size_t program_regbase_size; // Size of program base address of the ME4000 - - unsigned int serial_no; // Serial number of the board - unsigned char hw_revision; // Hardware revision of the board - unsigned short vendor_id; // Meilhaus vendor id (0x1402) - unsigned short device_id; // Device ID - - int pci_bus_no; // PCI bus number - int pci_dev_no; // PCI device number - int pci_func_no; // PCI function number - struct pci_dev *pci_dev_p; // General PCI information - - struct me4000_board *board_p; // Holds the board capabilities - - unsigned int irq; // IRQ assigned from the PCI BIOS - unsigned int irq_count; // Count of external interrupts - - spinlock_t preload_lock; // Guards the analog output preload register - spinlock_t ai_ctrl_lock; // Guards the analog input control register - - struct list_head ao_context_list; // List with analog output specific context - struct me4000_ai_context *ai_context; // Analog input specific context - struct me4000_dio_context *dio_context; // Digital I/O specific context - struct me4000_cnt_context *cnt_context; // Counter specific context - struct me4000_ext_int_context *ext_int_context; // External interrupt specific context -}; - -struct me4000_ao_context { - struct list_head list; // linked list of me4000_ao_context_t - int index; // Index in the list - int mode; // Indicates mode (0 = single, 1 = wraparound, 2 = continous) - int dac_in_use; // Indicates if already opend - spinlock_t use_lock; // Guards in_use - spinlock_t int_lock; // Used when locking out interrupts - struct me4000_circ_buf circ_buf; // Circular buffer - wait_queue_head_t wait_queue; // Wait queue to sleep while blocking write - struct me4000_info *board_info; - unsigned int irq; // The irq associated with this ADC - int volatile pipe_flag; // Indicates broken pipe set from me4000_ao_isr() - unsigned long ctrl_reg; - unsigned long status_reg; - unsigned long fifo_reg; - unsigned long single_reg; - unsigned long timer_reg; - unsigned long irq_status_reg; - unsigned long preload_reg; - struct fasync_struct *fasync_p; // Queue for asynchronous notification -}; - -struct me4000_ai_context { - struct list_head list; // linked list of me4000_ai_info_t - int mode; // Indicates mode - int in_use; // Indicates if already opend - spinlock_t use_lock; // Guards in_use - spinlock_t int_lock; // Used when locking out interrupts - int number; // Number of the DAC - unsigned int irq; // The irq associated with this ADC - struct me4000_circ_buf circ_buf; // Circular buffer - wait_queue_head_t wait_queue; // Wait queue to sleep while blocking read - struct me4000_info *board_info; - - struct fasync_struct *fasync_p; // Queue for asynchronous notification - - unsigned long ctrl_reg; - unsigned long status_reg; - unsigned long channel_list_reg; - unsigned long data_reg; - unsigned long chan_timer_reg; - unsigned long chan_pre_timer_reg; - unsigned long scan_timer_low_reg; - unsigned long scan_timer_high_reg; - unsigned long scan_pre_timer_low_reg; - unsigned long scan_pre_timer_high_reg; - unsigned long start_reg; - unsigned long irq_status_reg; - unsigned long sample_counter_reg; - - unsigned long chan_timer; - unsigned long chan_pre_timer; - unsigned long scan_timer_low; - unsigned long scan_timer_high; - unsigned long channel_list_count; - unsigned long sample_counter; - int sample_counter_reload; -}; - -struct me4000_dio_context { - struct list_head list; // linked list of me4000_dio_context_t - int in_use; // Indicates if already opend - spinlock_t use_lock; // Guards in_use - int number; - int dio_count; - struct me4000_info *board_info; - unsigned long dir_reg; - unsigned long ctrl_reg; - unsigned long port_0_reg; - unsigned long port_1_reg; - unsigned long port_2_reg; - unsigned long port_3_reg; -}; - -struct me4000_cnt_context { - struct list_head list; // linked list of me4000_dio_context_t - int in_use; // Indicates if already opend - spinlock_t use_lock; // Guards in_use - int number; - int cnt_count; - struct me4000_info *board_info; - unsigned long ctrl_reg; - unsigned long counter_0_reg; - unsigned long counter_1_reg; - unsigned long counter_2_reg; -}; - -struct me4000_ext_int_context { - struct list_head list; // linked list of me4000_dio_context_t - int in_use; // Indicates if already opend - spinlock_t use_lock; // Guards in_use - int number; - struct me4000_info *board_info; - unsigned int irq; - unsigned long int_count; - struct fasync_struct *fasync_ptr; - unsigned long ctrl_reg; - unsigned long irq_status_reg; -}; - -#endif - -/*============================================================================= - Application include section starts here - ===========================================================================*/ - -/*----------------------------------------------------------------------------- - Defines for analog input - ----------------------------------------------------------------------------*/ - -/* General stuff */ -#define ME4000_AI_FIFO_COUNT 2048 - -#define ME4000_AI_MIN_TICKS 66 -#define ME4000_AI_MAX_SCAN_TICKS 0xFFFFFFFFFFLL - -#define ME4000_AI_BUFFER_SIZE (32 * 1024) // Size in bytes - -#define ME4000_AI_BUFFER_COUNT ((ME4000_AI_BUFFER_SIZE) / 2) // Size in values - -/* Channel list defines and masks */ -#define ME4000_AI_CHANNEL_LIST_COUNT 1024 - -#define ME4000_AI_LIST_INPUT_SINGLE_ENDED 0x000 -#define ME4000_AI_LIST_INPUT_DIFFERENTIAL 0x020 - -#define ME4000_AI_LIST_RANGE_BIPOLAR_10 0x000 -#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 0x040 -#define ME4000_AI_LIST_RANGE_UNIPOLAR_10 0x080 -#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 0x0C0 - -#define ME4000_AI_LIST_LAST_ENTRY 0x100 - -/* External trigger defines */ -#define ME4000_AI_TRIGGER_SOFTWARE 0x0 // Use only with API -#define ME4000_AI_TRIGGER_EXT_DIGITAL 0x1 -#define ME4000_AI_TRIGGER_EXT_ANALOG 0x2 - -#define ME4000_AI_TRIGGER_EXT_EDGE_RISING 0x0 -#define ME4000_AI_TRIGGER_EXT_EDGE_FALLING 0x1 -#define ME4000_AI_TRIGGER_EXT_EDGE_BOTH 0x2 - -/* Sample and Hold */ -#define ME4000_AI_SIMULTANEOUS_DISABLE 0x0 -#define ME4000_AI_SIMULTANEOUS_ENABLE 0x1 - -/* Defines for the Sample Counter */ -#define ME4000_AI_SC_RELOAD 0x0 -#define ME4000_AI_SC_ONCE 0x1 - -/* Modes for analog input */ -#define ME4000_AI_ACQ_MODE_SINGLE 0x00 // Catch one single value -#define ME4000_AI_ACQ_MODE_SOFTWARE 0x01 // Continous sampling with software start -#define ME4000_AI_ACQ_MODE_EXT 0x02 // Continous sampling with external trigger start -#define ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE 0x03 // Sample one value by external trigger -#define ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST 0x04 // Sample one channel list by external trigger - -/* Staus of AI FSM */ -#define ME4000_AI_STATUS_IDLE 0x0 -#define ME4000_AI_STATUS_BUSY 0x1 - -/* Voltages for calibration */ -#define ME4000_AI_GAIN_1_UNI_OFFSET 10.0E-3 -#define ME4000_AI_GAIN_1_UNI_FULLSCALE 9950.0E-3 -#define ME4000_AI_GAIN_1_BI_OFFSET 0.0 -#define ME4000_AI_GAIN_1_BI_FULLSCALE 9950.0E-3 -#define ME4000_AI_GAIN_4_UNI_OFFSET 10.0E-3 -#define ME4000_AI_GAIN_4_UNI_FULLSCALE 2450.0E-3 -#define ME4000_AI_GAIN_4_BI_OFFSET 0.0 -#define ME4000_AI_GAIN_4_BI_FULLSCALE 2450.0E-3 - -/* Ideal digits for calibration */ -#define ME4000_AI_GAIN_1_UNI_OFFSET_DIGITS (-32702) -#define ME4000_AI_GAIN_1_UNI_FULLSCALE_DIGITS 32440 -#define ME4000_AI_GAIN_1_BI_OFFSET_DIGITS 0 -#define ME4000_AI_GAIN_1_BI_FULLSCALE_DIGITS 32604 -#define ME4000_AI_GAIN_4_UNI_OFFSET_DIGITS (-32505) -#define ME4000_AI_GAIN_4_UNI_FULLSCALE_DIGITS 31457 -#define ME4000_AI_GAIN_4_BI_OFFSET_DIGITS 0 -#define ME4000_AI_GAIN_4_BI_FULLSCALE_DIGITS 32113 - -/*----------------------------------------------------------------------------- - Defines for analog output - ----------------------------------------------------------------------------*/ - -/* General stuff */ -#define ME4000_AO_FIFO_COUNT (4 * 1024) - -#define ME4000_AO_MIN_TICKS 66 - -#define ME4000_AO_BUFFER_SIZE (32 * 1024) // Size in bytes - -#define ME4000_AO_BUFFER_COUNT ((ME4000_AO_BUFFER_SIZE) / 2) // Size in values - -/* Conversion modes for analog output */ -#define ME4000_AO_CONV_MODE_SINGLE 0x0 -#define ME4000_AO_CONV_MODE_WRAPAROUND 0x1 -#define ME4000_AO_CONV_MODE_CONTINUOUS 0x2 - -/* Trigger setup */ -#define ME4000_AO_TRIGGER_EXT_EDGE_RISING 0x0 -#define ME4000_AO_TRIGGER_EXT_EDGE_FALLING 0x1 -#define ME4000_AO_TRIGGER_EXT_EDGE_BOTH 0x2 - -/* Status of AO FSM */ -#define ME4000_AO_STATUS_IDLE 0x0 -#define ME4000_AO_STATUS_BUSY 0x1 - -/*----------------------------------------------------------------------------- - Defines for eeprom - ----------------------------------------------------------------------------*/ - -#define ME4000_EEPROM_CMD_READ 0x180 -#define ME4000_EEPROM_CMD_WRITE_ENABLE 0x130 -#define ME4000_EEPROM_CMD_WRITE_DISABLE 0x100 -#define ME4000_EEPROM_CMD_WRITE 0x1400000 - -#define ME4000_EEPROM_CMD_LENGTH_READ 9 -#define ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE 9 -#define ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE 9 -#define ME4000_EEPROM_CMD_LENGTH_WRITE 25 - -#define ME4000_EEPROM_ADR_DATE_HIGH 0x32 -#define ME4000_EEPROM_ADR_DATE_LOW 0x33 - -#define ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET 0x34 -#define ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE 0x35 -#define ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET 0x36 -#define ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE 0x37 -#define ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET 0x38 -#define ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE 0x39 - -#define ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET 0x3A -#define ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE 0x3B -#define ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET 0x3C -#define ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE 0x3D -#define ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET 0x3E -#define ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE 0x3F - -#define ME4000_EEPROM_ADR_LENGTH 6 -#define ME4000_EEPROM_DATA_LENGTH 16 - -/*----------------------------------------------------------------------------- - Defines for digital I/O - ----------------------------------------------------------------------------*/ - -#define ME4000_DIO_PORT_A 0x0 -#define ME4000_DIO_PORT_B 0x1 -#define ME4000_DIO_PORT_C 0x2 -#define ME4000_DIO_PORT_D 0x3 - -#define ME4000_DIO_PORT_INPUT 0x0 -#define ME4000_DIO_PORT_OUTPUT 0x1 -#define ME4000_DIO_FIFO_LOW 0x2 -#define ME4000_DIO_FIFO_HIGH 0x3 - -#define ME4000_DIO_FUNCTION_PATTERN 0x0 -#define ME4000_DIO_FUNCTION_DEMUX 0x1 -#define ME4000_DIO_FUNCTION_MUX 0x2 - -/*----------------------------------------------------------------------------- - Defines for counters - ----------------------------------------------------------------------------*/ - -#define ME4000_CNT_COUNTER_0 0 -#define ME4000_CNT_COUNTER_1 1 -#define ME4000_CNT_COUNTER_2 2 - -#define ME4000_CNT_MODE_0 0 // Change state if zero crossing -#define ME4000_CNT_MODE_1 1 // Retriggerable One-Shot -#define ME4000_CNT_MODE_2 2 // Asymmetrical divider -#define ME4000_CNT_MODE_3 3 // Symmetrical divider -#define ME4000_CNT_MODE_4 4 // Counter start by software trigger -#define ME4000_CNT_MODE_5 5 // Counter start by hardware trigger - -/*----------------------------------------------------------------------------- - General type definitions - ----------------------------------------------------------------------------*/ - -struct me4000_user_info { - int board_count; // Index of the board after detection - unsigned long plx_regbase; // PLX configuration space base address - resource_size_t me4000_regbase; // Base address of the ME4000 - unsigned long plx_regbase_size; // PLX register set space - resource_size_t me4000_regbase_size; // ME4000 register set space - unsigned long serial_no; // Serial number of the board - unsigned char hw_revision; // Hardware revision of the board - unsigned short vendor_id; // Meilhaus vendor id (0x1402) - unsigned short device_id; // Device ID - int pci_bus_no; // PCI bus number - int pci_dev_no; // PCI device number - int pci_func_no; // PCI function number - char irq; // IRQ assigned from the PCI BIOS - int irq_count; // Count of external interrupts - - int driver_version; // Version of the driver release - - int ao_count; // Count of analog output channels - int ao_fifo_count; // Count fo analog output fifos - - int ai_count; // Count of analog input channels - int ai_sh_count; // Count of sample and hold devices - int ai_ex_trig_analog; // Flag to indicate if analogous external trigger is available - - int dio_count; // Count of digital I/O ports - - int cnt_count; // Count of counters -}; - -/*----------------------------------------------------------------------------- - Type definitions for analog output - ----------------------------------------------------------------------------*/ - -struct me4000_ao_channel_list { - unsigned long count; - unsigned long *list; -}; - -/*----------------------------------------------------------------------------- - Type definitions for analog input - ----------------------------------------------------------------------------*/ - -struct me4000_ai_channel_list { - unsigned long count; - unsigned long *list; -}; - -struct me4000_ai_timer { - unsigned long pre_chan; - unsigned long chan; - unsigned long scan_low; - unsigned long scan_high; -}; - -struct me4000_ai_config { - struct me4000_ai_timer timer; - struct me4000_ai_channel_list channel_list; - int sh; -}; - -struct me4000_ai_single { - int channel; - int range; - int mode; - short value; - unsigned long timeout; -}; - -struct me4000_ai_trigger { - int mode; - int edge; -}; - -struct me4000_ai_sc { - unsigned long value; - int reload; -}; - -/*----------------------------------------------------------------------------- - Type definitions for eeprom - ----------------------------------------------------------------------------*/ - -struct me4000_eeprom { - unsigned long date; - short uni_10_offset; - short uni_10_fullscale; - short uni_2_5_offset; - short uni_2_5_fullscale; - short bi_10_offset; - short bi_10_fullscale; - short bi_2_5_offset; - short bi_2_5_fullscale; - short diff_10_offset; - short diff_10_fullscale; - short diff_2_5_offset; - short diff_2_5_fullscale; -}; - -/*----------------------------------------------------------------------------- - Type definitions for digital I/O - ----------------------------------------------------------------------------*/ - -struct me4000_dio_config { - int port; - int mode; - int function; -}; - -struct me4000_dio_byte { - int port; - unsigned char byte; -}; - -/*----------------------------------------------------------------------------- - Type definitions for counters - ----------------------------------------------------------------------------*/ - -struct me4000_cnt { - int counter; - unsigned short value; -}; - -struct me4000_cnt_config { - int counter; - int mode; -}; - -/*----------------------------------------------------------------------------- - Type definitions for external interrupt - ----------------------------------------------------------------------------*/ - -struct me4000_int { - int int1_count; - int int2_count; -}; - -/*----------------------------------------------------------------------------- - The ioctls of the board - ----------------------------------------------------------------------------*/ - -#define ME4000_IOCTL_MAXNR 50 -#define ME4000_MAGIC 'y' -#define ME4000_GET_USER_INFO _IOR (ME4000_MAGIC, 0, \ - struct me4000_user_info) - -#define ME4000_AO_START _IOW (ME4000_MAGIC, 1, unsigned long) -#define ME4000_AO_STOP _IO (ME4000_MAGIC, 2) -#define ME4000_AO_IMMEDIATE_STOP _IO (ME4000_MAGIC, 3) -#define ME4000_AO_RESET _IO (ME4000_MAGIC, 4) -#define ME4000_AO_PRELOAD _IO (ME4000_MAGIC, 5) -#define ME4000_AO_PRELOAD_UPDATE _IO (ME4000_MAGIC, 6) -#define ME4000_AO_EX_TRIG_ENABLE _IO (ME4000_MAGIC, 7) -#define ME4000_AO_EX_TRIG_DISABLE _IO (ME4000_MAGIC, 8) -#define ME4000_AO_EX_TRIG_SETUP _IOW (ME4000_MAGIC, 9, int) -#define ME4000_AO_TIMER_SET_DIVISOR _IOW (ME4000_MAGIC, 10, unsigned long) -#define ME4000_AO_ENABLE_DO _IO (ME4000_MAGIC, 11) -#define ME4000_AO_DISABLE_DO _IO (ME4000_MAGIC, 12) -#define ME4000_AO_FSM_STATE _IOR (ME4000_MAGIC, 13, int) - -#define ME4000_AI_SINGLE _IOR (ME4000_MAGIC, 14, \ - struct me4000_ai_single) -#define ME4000_AI_START _IOW (ME4000_MAGIC, 15, unsigned long) -#define ME4000_AI_STOP _IO (ME4000_MAGIC, 16) -#define ME4000_AI_IMMEDIATE_STOP _IO (ME4000_MAGIC, 17) -#define ME4000_AI_EX_TRIG_ENABLE _IO (ME4000_MAGIC, 18) -#define ME4000_AI_EX_TRIG_DISABLE _IO (ME4000_MAGIC, 19) -#define ME4000_AI_EX_TRIG_SETUP _IOW (ME4000_MAGIC, 20, \ - struct me4000_ai_trigger) -#define ME4000_AI_CONFIG _IOW (ME4000_MAGIC, 21, \ - struct me4000_ai_config) -#define ME4000_AI_SC_SETUP _IOW (ME4000_MAGIC, 22, \ - struct me4000_ai_sc) -#define ME4000_AI_FSM_STATE _IOR (ME4000_MAGIC, 23, int) - -#define ME4000_DIO_CONFIG _IOW (ME4000_MAGIC, 24, \ - struct me4000_dio_config) -#define ME4000_DIO_GET_BYTE _IOR (ME4000_MAGIC, 25, \ - struct me4000_dio_byte) -#define ME4000_DIO_SET_BYTE _IOW (ME4000_MAGIC, 26, \ - struct me4000_dio_byte) -#define ME4000_DIO_RESET _IO (ME4000_MAGIC, 27) - -#define ME4000_CNT_READ _IOR (ME4000_MAGIC, 28, \ - struct me4000_cnt) -#define ME4000_CNT_WRITE _IOW (ME4000_MAGIC, 29, \ - struct me4000_cnt) -#define ME4000_CNT_CONFIG _IOW (ME4000_MAGIC, 30, \ - struct me4000_cnt_config) -#define ME4000_CNT_RESET _IO (ME4000_MAGIC, 31) - -#define ME4000_EXT_INT_DISABLE _IO (ME4000_MAGIC, 32) -#define ME4000_EXT_INT_ENABLE _IO (ME4000_MAGIC, 33) -#define ME4000_EXT_INT_COUNT _IOR (ME4000_MAGIC, 34, int) - -#define ME4000_AI_OFFSET_ENABLE _IO (ME4000_MAGIC, 35) -#define ME4000_AI_OFFSET_DISABLE _IO (ME4000_MAGIC, 36) -#define ME4000_AI_FULLSCALE_ENABLE _IO (ME4000_MAGIC, 37) -#define ME4000_AI_FULLSCALE_DISABLE _IO (ME4000_MAGIC, 38) - -#define ME4000_AI_EEPROM_READ _IOR (ME4000_MAGIC, 39, \ - struct me4000_eeprom) -#define ME4000_AI_EEPROM_WRITE _IOW (ME4000_MAGIC, 40, \ - struct me4000_eeprom) - -#define ME4000_AO_SIMULTANEOUS_EX_TRIG _IO (ME4000_MAGIC, 41) -#define ME4000_AO_SIMULTANEOUS_SW _IO (ME4000_MAGIC, 42) -#define ME4000_AO_SIMULTANEOUS_DISABLE _IO (ME4000_MAGIC, 43) -#define ME4000_AO_SIMULTANEOUS_UPDATE _IOW (ME4000_MAGIC, 44, \ - struct me4000_ao_channel_list) - -#define ME4000_AO_SYNCHRONOUS_EX_TRIG _IO (ME4000_MAGIC, 45) -#define ME4000_AO_SYNCHRONOUS_SW _IO (ME4000_MAGIC, 46) -#define ME4000_AO_SYNCHRONOUS_DISABLE _IO (ME4000_MAGIC, 47) - -#define ME4000_AO_EX_TRIG_TIMEOUT _IOW (ME4000_MAGIC, 48, unsigned long) -#define ME4000_AO_GET_FREE_BUFFER _IOR (ME4000_MAGIC, 49, unsigned long) - -#define ME4000_AI_GET_COUNT_BUFFER _IOR (ME4000_MAGIC, 50, unsigned long) - -#endif diff --git a/drivers/staging/me4000/me4000_firmware.h b/drivers/staging/me4000/me4000_firmware.h deleted file mode 100644 index 87c23f6757b..00000000000 --- a/drivers/staging/me4000/me4000_firmware.h +++ /dev/null @@ -1,10033 +0,0 @@ -/* - This file is copyright by Meilhaus Electronic GmbH 2003. - You are not allowed to distribute, sell, modify, reverse engineer or use this - code (or parts of it) for any other purpose or under any other conditions - than stated below. - - 1) You are allowed to distribute verbatim copies of this file together - with device drivers for the Meilhaus ME-4000, board family. - - 2) Derived work (device drivers using this file) can be published 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. Any other license terms have - to be agreed by Meilhaus GmbH in written. - - 2) This file is distributed WITHOUT ANY WARRANTY; - without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under - no means liable for products using this file or parts of it. - - 3) The copyright of this file has to be mentioned in derived work. - - 4) If this license terms are not valid due to any other law - or restrictions imposed on you, you are not allowed to use - this file in any way at all. - */ - -/* Version 18 of standard firmware */ -static unsigned char xilinx_firm[] = { -0x00, 0x01, 0xfb, 0xdc, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00, -0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00, -0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00, -0xF0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C, -0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, -0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x6E, 0x0D, 0x01, 0x49, 0x04, -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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x80, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 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, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 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, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xFE, 0x4B, 0x02, 0x3E, 0x00, 0xEA, 0x00, 0xA8, 0x00, 0xA0, -0x0A, 0x80, 0x2A, 0x00, 0xAE, 0x00, 0xB8, 0x02, 0xA0, 0x02, 0x80, 0x28, 0x00, -0xAA, 0x00, 0xB8, 0x02, 0x60, 0x02, 0x80, 0x0B, 0x00, 0x26, 0x00, 0xB8, 0x00, -0xE0, 0x02, 0x80, 0x0B, 0x00, 0x2E, 0x00, 0xB8, 0x00, 0xE0, 0x02, 0x80, 0x0B, -0x00, 0xAE, 0x00, 0xB8, 0x02, 0x80, 0x0A, 0xFC, 0x23, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x5B, 0x00, 0xF3, 0x04, 0xCC, 0x01, 0xF2, 0x96, 0xC2, -0xDF, 0x30, 0xBB, 0x43, 0xD0, 0x73, 0xB0, 0x8F, 0xC0, 0x3D, 0x02, 0xFB, 0x48, -0xFC, 0x13, 0x30, 0x13, 0xC0, 0x4F, 0x02, 0x3F, 0x01, 0xDC, 0x13, 0xB0, 0x4F, -0xC0, 0x4F, 0x00, 0x3B, 0xC9, 0xCC, 0x04, 0xF2, 0x13, 0xC0, 0xFC, 0x00, 0xFB, -0xC9, 0x8C, 0x27, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x08, 0x57, 0x40, 0xE1, 0x08, 0x44, 0x03, 0xD0, 0x09, 0x40, 0x13, -0x01, 0xD1, 0x04, 0xC4, 0x1B, 0x10, 0x6D, 0x40, 0x3C, 0x02, 0xDD, 0x06, 0xF4, -0x0F, 0x10, 0x11, 0x40, 0x27, 0x11, 0x57, 0x81, 0xC4, 0x0F, 0xD0, 0xBF, 0x40, -0x64, 0x00, 0x51, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x50, 0x34, 0x00, 0xD1, 0x00, -0x54, 0x11, 0x14, 0x19, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0x00, 0x37, 0x00, 0xC1, 0x00, 0x04, 0x00, 0xD8, 0x48, 0x44, 0x21, 0x00, -0xC9, 0x00, 0x14, 0x03, 0xD0, 0xCC, 0x64, 0x33, 0x11, 0xCD, 0x06, 0x34, 0x23, -0x50, 0x00, 0x00, 0x02, 0x01, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x42, 0x01, -0x00, 0xC1, 0x00, 0x14, 0x00, 0xD0, 0x00, 0x44, 0x30, 0x09, 0xCD, 0x44, 0x44, -0x12, 0x10, 0x00, 0x44, 0x47, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA8, 0xB5, 0x01, 0xD1, 0x00, 0x44, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0xD1, -0x40, 0x44, 0x03, 0x50, 0x0D, 0x60, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x50, -0x01, 0x40, 0x27, 0x10, 0xD5, 0x00, 0x44, 0x03, 0xCA, 0x0D, 0x40, 0x65, 0x00, -0xC1, 0x00, 0x44, 0xC6, 0xD0, 0x19, 0x40, 0x30, 0x00, 0xD1, 0x00, 0x54, 0x09, -0x14, 0x11, 0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, -0xE3, 0x00, 0xD3, 0x00, 0x4C, 0x0A, 0xF0, 0x0D, 0xC4, 0xF7, 0x00, 0x9B, 0x40, -0x5C, 0x03, 0xF2, 0x0D, 0xC6, 0x37, 0x10, 0xDB, 0x00, 0x74, 0x03, 0x70, 0xA1, -0x81, 0x37, 0x00, 0xCF, 0x03, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0xC7, 0x01, 0x93, -0x00, 0x5D, 0x0C, 0xF0, 0x31, 0xC0, 0x34, 0x00, 0x5F, 0xC0, 0x0C, 0x07, 0x30, -0x71, 0x80, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, -0x08, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0xFF, 0x18, 0xFF, 0x04, 0xAC, -0x03, 0xB1, 0x0D, 0xC8, 0x3D, 0x00, 0xFF, 0x80, 0x7C, 0x03, 0xB4, 0x13, 0xCA, -0xFF, 0x00, 0xF7, 0x03, 0xE4, 0x43, 0xF0, 0x0E, 0xC1, 0x0E, 0x00, 0xFF, 0x00, -0xFC, 0x40, 0xF0, 0x0B, 0xE2, 0x3F, 0x00, 0xFF, 0x83, 0xFD, 0x25, 0xF0, 0x0B, -0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, -0xD3, 0x00, 0x4C, 0x0A, 0x30, 0x0D, 0xC0, 0xA4, 0x00, 0xD7, 0x00, 0x5C, 0x03, -0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xD7, 0x00, 0x0C, 0x03, 0x30, 0x41, 0xC4, 0x35, -0x00, 0xD3, 0x02, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x05, 0x00, 0xDF, 0x00, 0x7C, -0x0E, 0x30, 0x01, 0xC1, 0x37, 0x10, 0xD7, 0x04, 0x4C, 0x0B, 0x30, 0x21, 0xC0, -0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x01, 0xF5, -0x00, 0x44, 0x2E, 0x10, 0x09, 0x40, 0x25, 0x00, 0xD1, 0x00, 0xC4, 0x03, 0x10, -0x0F, 0xC0, 0x3E, 0x00, 0xF1, 0x00, 0xEC, 0x03, 0x10, 0x11, 0xC0, 0x35, 0x00, -0xD1, 0x01, 0xDC, 0x07, 0x70, 0x2F, 0xC3, 0x23, 0x06, 0xDD, 0x20, 0x64, 0x02, -0xB0, 0x38, 0x41, 0x37, 0x00, 0xD1, 0x03, 0x6C, 0x29, 0x50, 0xA9, 0x40, 0x4E, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0xD1, 0x00, -0x04, 0x29, 0x90, 0x04, 0x40, 0x24, 0x00, 0xD5, 0x00, 0x34, 0x03, 0x50, 0x0D, -0x40, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x5D, 0x00, 0x40, 0x12, 0x20, 0x01, -0x04, 0x10, 0x0B, 0xD0, 0x1C, 0x42, 0x21, 0x80, 0x0D, 0x40, 0x34, 0x08, 0x90, -0x30, 0x40, 0x31, 0x10, 0xD5, 0x03, 0x04, 0x05, 0x18, 0x18, 0x44, 0x1F, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0xE5, 0x01, 0x84, -0x07, 0x98, 0x1B, 0x40, 0x69, 0x80, 0xE1, 0x81, 0x24, 0x07, 0x10, 0x9E, 0x40, -0x78, 0x80, 0xED, 0x01, 0xA4, 0x07, 0x50, 0x52, 0x61, 0x79, 0x00, 0x21, 0x19, -0x90, 0x07, 0x51, 0x1C, 0x40, 0x6A, 0x00, 0x6D, 0x41, 0xA4, 0x06, 0xD2, 0x12, -0x40, 0x7B, 0x00, 0xF1, 0x09, 0xE4, 0x45, 0x54, 0x1A, 0x40, 0x12, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x02, 0xC3, 0x88, 0x44, 0x02, -0xB0, 0x88, 0x40, 0x20, 0x00, 0xD7, 0x08, 0x34, 0x03, 0x70, 0x0C, 0x40, 0x37, -0x02, 0xDD, 0x00, 0x04, 0x03, 0x71, 0x10, 0xC0, 0x16, 0x02, 0x01, 0x80, 0x1C, -0xC3, 0xF0, 0x0C, 0x40, 0x21, 0x00, 0xCF, 0x09, 0x3C, 0x91, 0xB0, 0x88, 0xC0, -0x37, 0x00, 0xC7, 0x10, 0x0C, 0x11, 0x38, 0x84, 0xC1, 0x4B, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x2D, 0x00, 0xFF, 0x02, 0xFC, 0x02, 0x60, -0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x43, 0x70, 0x0F, 0xC0, 0x3F, 0x04, -0xF3, 0x00, 0xFC, 0x0B, 0xB0, 0x02, 0xC0, 0x3F, 0x48, 0xFF, 0x00, 0x7C, 0x2B, -0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x20, 0x3C, 0x03, 0x90, 0x09, 0xC0, 0x3F, -0x00, 0xEE, 0x20, 0x7C, 0x01, 0xD4, 0x01, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA0, 0x27, 0x00, 0xDF, 0x0E, 0x7C, 0x00, 0xC0, 0x0D, -0xC0, 0x75, 0x00, 0xD3, 0x00, 0x7C, 0x53, 0x70, 0x8D, 0xC6, 0xB4, 0x04, 0xDF, -0x00, 0x7C, 0x13, 0xB0, 0x00, 0xC0, 0x34, 0x10, 0x07, 0x80, 0x5C, 0x13, 0x30, -0x5C, 0xC1, 0x04, 0x00, 0x9F, 0x40, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, -0x5F, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x47, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40, -0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x13, 0xD0, 0x4F, 0x40, 0x3A, 0x11, 0xED, 0x00, -0xB4, 0x03, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xAD, 0x00, 0x04, 0x03, 0x10, 0x2E, -0x40, 0x08, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x00, 0xED, -0x20, 0xC4, 0x01, 0x10, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x00, 0x69, 0x00, 0xED, 0x01, 0xB4, 0x06, 0x90, 0x3E, 0x4C, 0x6F, -0x10, 0xE1, 0x01, 0xB4, 0x17, 0xD0, 0x0E, 0x40, 0x7A, 0x00, 0xED, 0x0D, 0x94, -0x27, 0xD0, 0x13, 0x41, 0x7A, 0x80, 0x6D, 0x01, 0x94, 0x37, 0x51, 0x5E, 0x40, -0x6A, 0x04, 0xED, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x48, 0x7B, 0x80, 0xAD, 0x01, -0x84, 0x05, 0x14, 0x1E, 0x42, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x28, 0x23, 0x84, 0xCD, 0x00, 0x34, 0x2E, 0xD0, 0x08, 0x40, 0x23, 0x49, -0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x36, 0x03, -0xD0, 0x0C, 0x40, 0x33, 0x11, 0xCD, 0x03, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x70, -0x00, 0xCD, 0x00, 0x34, 0x6F, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x44, 0x05, -0x21, 0x14, 0x1C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, -0xA8, 0xD9, 0x00, 0x5F, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC4, 0xDF, 0x01, 0x53, -0x00, 0x7C, 0x01, 0x78, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xB0, -0x17, 0xC0, 0x9E, 0x01, 0x7F, 0x0E, 0x5C, 0x01, 0x74, 0x05, 0xC8, 0x1E, 0x00, -0x7F, 0x02, 0xFC, 0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x20, 0x7F, 0x07, 0xCC, 0x05, -0x10, 0x07, 0xC1, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, -0x07, 0x02, 0x1F, 0x00, 0x3C, 0x40, 0xF0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x60, -0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC1, 0x05, 0x10, 0x1F, 0x00, 0x7C, 0x80, 0x91, 0x01, 0xD0, 0x87, 0x01, 0x1F, -0x30, 0x70, 0x08, 0xF0, 0x41, 0xC0, 0x07, 0x18, 0x1F, 0x40, 0x7D, 0x00, 0xF0, -0x11, 0xC0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, -0x01, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x74, -0x02, 0xF0, 0x09, 0xC0, 0x23, 0x40, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, -0x24, 0x00, 0x9F, 0x00, 0x44, 0x02, 0x70, 0x09, 0xC4, 0x67, 0x02, 0x9D, 0x00, -0x4C, 0x16, 0xF0, 0x19, 0xC0, 0x27, 0x80, 0x9F, 0x03, 0x4C, 0x22, 0x34, 0x08, -0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00, -0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, -0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x06, 0xF0, 0xB8, 0x40, 0x24, -0x00, 0x8D, 0x08, 0x01, 0x06, 0x30, 0x29, 0xC0, 0x27, 0x21, 0x8D, 0x00, 0x44, -0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x03, 0x6C, 0x1E, 0x54, 0x29, 0x40, -0x05, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x81, -0x00, 0x44, 0x22, 0x10, 0x08, 0x40, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x26, 0x00, 0x99, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x24, 0x80, -0xDD, 0x80, 0x54, 0x12, 0x00, 0xA9, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, -0xD0, 0x4D, 0x43, 0x27, 0x00, 0x98, 0x10, 0x04, 0x02, 0x10, 0xA9, 0x40, 0x60, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x85, 0x04, -0x04, 0x1A, 0x14, 0x08, 0x40, 0x20, 0x20, 0x8D, 0x08, 0x34, 0x12, 0xD0, 0x88, -0x64, 0x23, 0x01, 0x89, 0x08, 0x34, 0x12, 0xD0, 0x09, 0x40, 0x20, 0x02, 0xDD, -0x00, 0x14, 0x02, 0x14, 0x08, 0x44, 0x23, 0x00, 0x9D, 0x08, 0x04, 0x02, 0xD8, -0x08, 0x42, 0x23, 0x02, 0x9D, 0x08, 0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x88, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x13, 0x0A, 0x4C, -0x09, 0x30, 0xA1, 0xC0, 0x85, 0x02, 0x1D, 0x02, 0x7C, 0x28, 0xF0, 0x61, 0xC1, -0x87, 0x02, 0x19, 0x16, 0x74, 0x00, 0xF0, 0x05, 0xC0, 0x84, 0x00, 0x1F, 0x00, -0x5C, 0x51, 0x70, 0x41, 0x45, 0x07, 0x10, 0x1F, 0x02, 0x4D, 0x01, 0xF0, 0x01, -0xC4, 0x87, 0x00, 0x0D, 0x02, 0x4C, 0x88, 0x30, 0x01, 0xC4, 0x74, 0xC0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x08, 0xFC, 0x0A, -0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x04, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27, -0x02, 0x93, 0x04, 0x7C, 0x22, 0x70, 0x0B, 0xD0, 0x2F, 0x01, 0xBF, 0x00, 0x6C, -0x02, 0x70, 0x09, 0xC0, 0x2D, 0x10, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, -0x27, 0x01, 0xBF, 0x84, 0xFC, 0x12, 0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x8C, 0xE8, 0x02, 0xF0, -0x09, 0xC0, 0x27, 0x02, 0x93, 0x60, 0x7C, 0x52, 0x30, 0xC9, 0xC0, 0x25, 0x00, -0x9B, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCC, 0x02, -0xB0, 0x0B, 0xC0, 0x2B, 0x28, 0x9F, 0x40, 0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x24, -0x20, 0xBF, 0x40, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x0C, 0x44, 0x49, 0xD0, 0x01, -0x41, 0x07, 0x00, 0x11, 0x14, 0x74, 0x10, 0x10, 0xC1, 0x48, 0x84, 0x04, 0x11, -0x10, 0x44, 0x20, 0xD2, 0x01, 0x40, 0x07, 0x01, 0x1D, 0x00, 0x50, 0x08, 0x14, -0x01, 0x40, 0x17, 0x00, 0x1D, 0x14, 0x64, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x0C, -0x5D, 0x90, 0x54, 0x00, 0x14, 0x01, 0x50, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0x27, 0x40, 0x81, 0x04, 0x34, 0x32, 0xD0, 0x08, 0x40, -0x27, 0x40, 0x85, 0x04, 0x34, 0x52, 0x10, 0x48, 0x40, 0x21, 0x03, 0x89, 0x08, -0x14, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x05, 0x9D, 0x00, 0x04, 0x22, 0x12, 0x8C, -0x42, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02, 0x50, 0x09, 0x40, 0x23, 0x01, 0x8D, -0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA8, 0x25, 0x04, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x69, 0x60, 0x27, -0x00, 0x95, 0x00, 0x34, 0x02, 0x10, 0x09, 0x60, 0x21, 0x00, 0x91, 0x00, 0x44, -0x02, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x9C, 0x02, 0x54, 0x02, 0x10, 0x09, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x64, 0x0A, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x8D, 0x08, -0x54, 0x12, 0x12, 0x19, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xA8, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x0E, 0xF0, 0x39, 0xE0, 0x27, 0x21, -0x97, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC2, 0x25, 0x00, 0x9B, 0x00, 0x5C, 0x02, -0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x67, -0x00, 0x9F, 0x24, 0x7C, 0x02, 0xF8, 0x88, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, -0x02, 0x30, 0x59, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x56, 0xF0, 0x19, 0xC0, 0x67, 0x01, 0x9B, -0x04, 0x7C, 0x02, 0xF4, 0x08, 0xCC, 0x26, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xF0, -0x39, 0xC2, 0x27, 0x00, 0x9F, 0x02, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x01, -0x9F, 0x05, 0x7C, 0x22, 0xF0, 0x19, 0xC2, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF0, 0x08, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, -0x05, 0x00, 0x0F, 0x00, 0x5C, 0x08, 0xF0, 0x21, 0xC0, 0x85, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, -0xC1, 0x07, 0x00, 0x1B, 0x06, 0x4C, 0x40, 0xF0, 0x01, 0xC1, 0x04, 0x01, 0x13, -0x02, 0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x20, 0x31, -0x21, 0x80, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x18, -0x00, 0x5D, 0x00, 0xC0, 0x05, 0x70, 0x05, 0x40, 0x10, 0x00, 0x5C, 0x00, 0x74, -0x01, 0xD0, 0x05, 0xC0, 0x15, 0x00, 0x5D, 0x00, 0x74, 0x45, 0xD0, 0x07, 0xC0, -0x15, 0x00, 0x61, 0x00, 0xDC, 0x4D, 0x70, 0x07, 0x40, 0xDD, 0x40, 0x51, 0x00, -0xF4, 0x3D, 0x10, 0x77, 0x40, 0x17, 0x40, 0x71, 0x00, 0x84, 0x0D, 0xF0, 0xA7, -0xC0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20, -0xCD, 0x80, 0x10, 0x0F, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xCC, 0x00, 0x34, 0x03, -0xD0, 0x0C, 0x00, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0xBC, 0x40, 0x33, -0x00, 0xC9, 0x01, 0x24, 0x07, 0x50, 0x0C, 0x40, 0xF0, 0x00, 0xC1, 0x20, 0x34, -0x07, 0x10, 0x4C, 0x60, 0x33, 0x90, 0xC9, 0x00, 0x04, 0x4F, 0x10, 0x2C, 0x42, -0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xCD, -0x04, 0x84, 0x0B, 0x50, 0x1E, 0x40, 0x3A, 0x03, 0xED, 0x08, 0xB4, 0x03, 0xD0, -0x8E, 0x40, 0x39, 0xA1, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x7D, 0x00, -0xFD, 0x42, 0x90, 0x03, 0x50, 0x18, 0x40, 0xFD, 0x10, 0xE1, 0x04, 0xF4, 0x06, -0x10, 0x0E, 0x40, 0x7B, 0x00, 0xE9, 0x00, 0xC5, 0x01, 0x90, 0x0C, 0x60, 0x12, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x07, -0x94, 0x07, 0x70, 0x1F, 0xC8, 0x7B, 0x00, 0xEF, 0x05, 0xB4, 0x0F, 0xF0, 0x1E, -0x40, 0x7B, 0x04, 0xED, 0x01, 0xBC, 0x07, 0xF2, 0x1A, 0xC8, 0x7B, 0x24, 0xFB, -0x01, 0xAC, 0x84, 0x70, 0x1A, 0xC0, 0x78, 0x00, 0xE1, 0x09, 0xB4, 0x06, 0x34, -0x1E, 0xC4, 0x7F, 0x08, 0x79, 0x01, 0xCC, 0x06, 0x32, 0x16, 0xC0, 0x50, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x10, 0xDF, 0x02, 0x7C, -0x03, 0x70, 0xED, 0xC8, 0xB5, 0x21, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC8, -0x37, 0x02, 0xDF, 0x88, 0x7C, 0x03, 0xD0, 0x09, 0xC0, 0x33, 0x01, 0x93, 0x80, -0x7C, 0x01, 0x60, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x2A, 0x7C, 0x00, 0x60, 0x09, -0xC0, 0xB7, 0x06, 0x97, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x43, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00, 0xFF, 0x03, 0xC8, 0x21, -0xE0, 0x3E, 0xC2, 0xFC, 0x12, 0xFF, 0x09, 0xEC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, -0x02, 0xFB, 0x01, 0xDC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x04, 0xB3, 0x41, 0xBC, -0x27, 0xB0, 0x13, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xFC, 0x06, 0xF0, 0x1F, 0xC0, -0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x87, 0x30, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x10, 0xFD, 0x04, 0x84, 0x01, 0xF0, -0x0E, 0xC1, 0x3A, 0x00, 0xED, 0x00, 0xEC, 0x03, 0x15, 0x8E, 0x48, 0x3B, 0x40, -0xF1, 0x00, 0x84, 0x23, 0xD0, 0xA8, 0x40, 0x3B, 0x20, 0x21, 0x00, 0xB4, 0x29, -0x10, 0x62, 0x40, 0x3B, 0x00, 0xDF, 0x00, 0x84, 0x02, 0xF0, 0x0E, 0x40, 0x3B, -0x02, 0xED, 0x08, 0xBC, 0x01, 0xB0, 0x0E, 0x41, 0x57, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x00, 0x86, 0x63, 0xD8, 0x0F, -0x40, 0x38, 0x80, 0xFD, 0x40, 0x84, 0x23, 0x90, 0x0E, 0x40, 0x33, 0x10, 0xE1, -0x00, 0xB4, 0x23, 0xD2, 0x22, 0x60, 0x39, 0x00, 0xA5, 0x00, 0xB4, 0x00, 0x12, -0x02, 0x40, 0x2A, 0x00, 0xED, 0x10, 0x94, 0x02, 0xD0, 0x06, 0x40, 0x3B, 0x00, -0x6D, 0x00, 0xF4, 0x02, 0x10, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x06, 0x58, 0x3C, 0x40, -0x32, 0x00, 0xCD, 0x08, 0x24, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x20, 0xC1, 0x00, -0x16, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0x05, 0x0B, 0x36, 0x01, 0x10, 0x00, -0x40, 0x03, 0x10, 0xCD, 0x40, 0x04, 0x10, 0x51, 0x00, 0x40, 0x33, 0x00, 0x9D, -0x12, 0x14, 0xAF, 0x90, 0x50, 0x00, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA8, 0x25, 0x01, 0xFF, 0x00, 0x4D, 0x22, 0xD0, 0x3F, 0xC0, 0x3C, -0x00, 0xFF, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x00, 0x1C, -0x02, 0xF0, 0x25, 0xC0, 0xBD, 0x02, 0x57, 0x0B, 0x7C, 0x03, 0x11, 0x09, 0xC0, -0xF7, 0x02, 0xEF, 0x00, 0x5C, 0x0A, 0xD0, 0x9D, 0x40, 0x3F, 0x00, 0x9F, 0x02, -0x70, 0x03, 0x10, 0x21, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D, 0xC4, 0x37, 0x10, -0xDF, 0x80, 0x7C, 0x83, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xD7, 0x80, 0x64, 0x02, -0xF0, 0x3D, 0xC0, 0x37, 0x48, 0x5A, 0x00, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x67, -0x00, 0xD7, 0x00, 0x5C, 0x0A, 0xF0, 0x15, 0xC4, 0x37, 0x20, 0x5F, 0x02, 0x7C, -0x09, 0xF0, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -0x08, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0xFF, -0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC2, 0x3F, 0x80, 0xFF, 0x00, 0xFC, 0x03, 0xB1, -0x17, 0xC2, 0x3F, 0x00, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x0B, 0xC0, 0x7F, 0x00, -0xFF, 0x00, 0xCC, 0x02, 0xD0, 0x8F, 0xC0, 0x3F, 0x00, 0x31, 0x00, 0xCC, 0x62, -0x30, 0x03, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, -0x56, 0x00, 0xDD, 0x00, 0x34, 0x0E, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0xDD, 0x00, -0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0xA0, 0xDF, 0x20, 0x74, 0x03, 0x31, 0x9D, -0xC0, 0x31, 0x00, 0x91, 0x0A, 0x74, 0x0F, 0x78, 0x11, 0x40, 0x87, 0x01, 0xDD, -0x00, 0x6C, 0x44, 0x70, 0x01, 0x41, 0x37, 0x00, 0x13, 0x0F, 0x14, 0x44, 0x10, -0x39, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6, -0x02, 0xDD, 0x00, 0x74, 0x0C, 0x90, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x80, 0x74, -0x03, 0xD2, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x05, 0x40, -0x37, 0x00, 0x55, 0x82, 0x74, 0x12, 0xD0, 0x19, 0x40, 0x17, 0x02, 0xD9, 0x00, -0x44, 0x04, 0xD0, 0x09, 0x42, 0x33, 0x00, 0x95, 0x00, 0x44, 0x03, 0x10, 0x19, -0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, -0xCD, 0x00, 0x74, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x03, -0xD0, 0x0C, 0x40, 0x33, 0x20, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x88, 0x48, 0x35, -0x00, 0x45, 0x00, 0x34, 0x00, 0x58, 0x08, 0x60, 0x03, 0x00, 0xDD, 0x00, 0x25, -0x00, 0x50, 0x00, 0x48, 0x33, 0x40, 0x45, 0x00, 0x44, 0x00, 0x11, 0x08, 0x40, -0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0xFF, -0x00, 0x7C, 0x00, 0x10, 0x0F, 0xC0, 0x3D, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0xF0, -0x0D, 0xC0, 0x3F, 0x00, 0xDD, 0x00, 0x7E, 0x03, 0xB0, 0x05, 0x48, 0x3B, 0x00, -0xD5, 0x00, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x07, 0x00, 0xFF, 0x08, 0x4C, 0x00, -0xF0, 0x01, 0xC0, 0x3F, 0x00, 0x17, 0x00, 0x4D, 0x00, 0x30, 0x09, 0xC0, 0x03, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0xFF, 0x00, -0xFC, 0x02, 0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xEF, 0x80, 0xFC, 0x03, 0xF0, 0x0F, -0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x71, 0x43, 0xC0, 0x3D, 0x00, 0x3B, -0x00, 0xFC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xDC, 0x00, 0x78, -0x03, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFF, 0x80, 0xF0, 0x0B, 0xC2, 0x17, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0F, 0x04, 0x33, 0x01, 0xC4, -0x02, 0xB8, 0x0B, 0xC0, 0xBF, 0x01, 0xFB, 0x2C, 0xEC, 0x8E, 0x70, 0x2F, 0xC0, -0x4F, 0x00, 0xF7, 0x18, 0x8C, 0x24, 0xF0, 0x4F, 0xC1, 0x4F, 0x02, 0xFF, 0x44, -0xDC, 0x27, 0x30, 0x8F, 0xC0, 0x3F, 0x00, 0xE7, 0x00, 0xEC, 0x04, 0xF0, 0x0F, -0xC0, 0x6C, 0x00, 0xFB, 0x10, 0x9C, 0x52, 0xF0, 0x13, 0xC0, 0x0C, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x87, 0x00, 0x11, 0x00, 0x6C, 0x02, -0xF0, 0x09, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x4C, 0x13, 0x10, 0x8F, 0x40, 0x67, -0x08, 0xF1, 0x02, 0x44, 0x10, 0xD2, 0x3F, 0xC2, 0x23, 0x08, 0xF1, 0x03, 0x44, -0x13, 0x04, 0x6F, 0x40, 0xFC, 0x20, 0xF1, 0x0B, 0x44, 0x04, 0xD1, 0x3F, 0xC0, -0x44, 0x00, 0xD5, 0x43, 0x74, 0x04, 0xD0, 0x15, 0xC0, 0x06, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x01, 0x00, 0x15, 0x00, 0x92, -0x08, 0x42, 0x33, 0x03, 0xC9, 0x0C, 0x34, 0x03, 0x50, 0x4C, 0x44, 0x07, 0x80, -0xC5, 0x20, 0x04, 0x12, 0xD0, 0x0C, 0x42, 0x13, 0x10, 0xC9, 0x02, 0x14, 0x03, -0x10, 0x2C, 0x40, 0xB1, 0x00, 0xC5, 0x00, 0x07, 0x00, 0x50, 0x2C, 0x40, 0x26, -0x00, 0xC1, 0x20, 0x34, 0x02, 0xD0, 0x05, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA8, 0x41, 0x04, 0x01, 0x01, 0x54, 0x0E, 0x50, 0x19, -0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x47, 0x00, 0xD1, -0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x25, 0x04, 0xD5, 0x00, 0x44, 0x03, 0x18, -0x0D, 0x08, 0x34, 0x00, 0xD1, 0x00, 0x64, 0x04, 0xD0, 0x0D, 0x40, 0x64, 0x00, -0xD5, 0x00, 0x74, 0x06, 0xD0, 0x35, 0x40, 0x0E, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xA8, 0xC7, 0x00, 0x13, 0x03, 0x54, 0x0C, 0x90, 0x51, 0xC0, -0x37, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC4, 0x43, 0x00, 0xD7, 0x00, -0x4C, 0x0E, 0xF0, 0x0D, 0x48, 0x97, 0x02, 0xDF, 0x00, 0x5C, 0x03, 0x32, 0x0D, -0xC0, 0x37, 0x10, 0xD7, 0x00, 0x6E, 0x44, 0xF0, 0x0D, 0xD0, 0x62, 0x00, 0xDB, -0x00, 0x5C, 0x16, 0xF2, 0x1D, 0xE0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x80, 0x05, 0x00, 0x3F, 0x00, 0x6D, 0x80, 0xF0, 0x03, 0xC0, 0x3F, -0x00, 0xEF, 0x00, 0xEC, 0x03, 0xF8, 0x0D, 0xC0, 0x2F, 0x80, 0xEB, 0x40, 0xFC, -0x00, 0xF2, 0x0F, 0xC0, 0x4F, 0x00, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, -0x3B, 0x04, 0xFD, 0x80, 0xDC, 0x40, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, -0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x08, 0x85, 0x00, 0x1B, 0x00, 0x4D, 0x08, 0x30, 0x09, 0xC3, 0x33, 0x00, -0xDF, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x85, 0x00, 0xDF, 0x00, 0x4C, 0x0A, -0x30, 0x0D, 0xC6, 0x16, 0x00, 0xD3, 0x10, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x36, -0x00, 0xDF, 0x20, 0x4C, 0x08, 0x70, 0x0C, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7E, -0x42, 0x70, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0xA0, 0x04, 0x00, 0x11, 0x01, 0x44, 0x4E, 0x00, 0x69, 0x40, 0x3F, 0x10, 0xFD, -0x00, 0x4C, 0x03, 0x10, 0x0F, 0x40, 0xA4, 0x03, 0xFD, 0x00, 0x44, 0x00, 0x12, -0x0F, 0x40, 0x24, 0x00, 0xF0, 0x03, 0x54, 0x03, 0xD0, 0x0F, 0x40, 0x7C, 0x04, -0xED, 0x00, 0x45, 0x04, 0xD0, 0x1F, 0x40, 0x47, 0x00, 0xFD, 0x00, 0x74, 0x0E, -0x10, 0x0D, 0x43, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, -0x42, 0x00, 0x09, 0x24, 0x00, 0x46, 0x90, 0x00, 0x40, 0x33, 0x20, 0xC9, 0x00, -0x52, 0x02, 0xD0, 0x0C, 0x48, 0xA1, 0x00, 0xCC, 0x00, 0x14, 0x00, 0x10, 0x0C, -0x48, 0x27, 0x60, 0xC1, 0x01, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x04, 0x24, 0x04, 0xD0, 0x8C, 0x49, 0x23, 0x12, 0xCD, 0x00, 0x16, 0x04, 0x51, -0x0D, 0x41, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x48, -0x24, 0x21, 0x01, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x01, 0x94, -0x07, 0x90, 0x9E, 0x40, 0x78, 0xA0, 0xED, 0x01, 0xD4, 0x04, 0x14, 0x1E, 0x40, -0x69, 0x00, 0xE1, 0x11, 0x94, 0x07, 0xC0, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x95, -0x84, 0x05, 0xD2, 0x1E, 0x40, 0x4B, 0x00, 0xED, 0x09, 0xB6, 0x44, 0x10, 0x1F, -0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x00, 0x00, -0x1B, 0x10, 0x0D, 0x21, 0xB0, 0x04, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x5C, 0x03, -0xF0, 0x0C, 0xC8, 0x81, 0x00, 0xDE, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33, -0x03, 0xC3, 0x80, 0x1C, 0x83, 0xF0, 0x4C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x0C, -0x40, 0x70, 0x0C, 0xE4, 0x23, 0x22, 0xCF, 0x00, 0x1E, 0x14, 0x70, 0x0C, 0xC0, -0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x12, 0x7F, -0x08, 0xFC, 0x03, 0x54, 0x0F, 0xC0, 0x3F, 0x80, 0xFF, 0x02, 0xEC, 0x03, 0x70, -0x0F, 0xC3, 0x1F, 0x00, 0xFF, 0x08, 0xEC, 0x03, 0xF0, 0x2E, 0xC4, 0x3E, 0x02, -0xEF, 0x10, 0xF8, 0x23, 0xF0, 0x0F, 0xC1, 0x3E, 0x00, 0xFF, 0x06, 0xDC, 0x01, -0xF0, 0x0F, 0xC0, 0x2F, 0x08, 0xFF, 0x20, 0xFE, 0x20, 0xF2, 0x0C, 0xC0, 0x0B, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x07, 0x00, 0x03, 0x00, -0x4C, 0x03, 0xF0, 0x05, 0xC0, 0xB7, 0x01, 0xDB, 0x0E, 0x7C, 0x03, 0xF0, 0x5D, -0xC1, 0x24, 0x00, 0xDF, 0x86, 0x7C, 0x86, 0x70, 0x3D, 0xC0, 0x16, 0x00, 0xDF, -0x10, 0x7C, 0x03, 0xF0, 0x4D, 0xC1, 0x36, 0x01, 0xDF, 0x01, 0x4C, 0x00, 0xF0, -0xAC, 0xC0, 0x24, 0x00, 0xDF, 0x01, 0x4C, 0x06, 0x30, 0x0D, 0xC0, 0x54, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x08, 0x21, 0x00, 0x84, -0x03, 0xD0, 0x0E, 0x40, 0xBB, 0x0D, 0xE1, 0x00, 0x9C, 0x03, 0xD0, 0x4E, 0x50, -0x38, 0x80, 0xED, 0x12, 0xB4, 0x02, 0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x04, -0xB0, 0x83, 0xD0, 0x4E, 0x42, 0xB8, 0x82, 0xCD, 0x04, 0xA5, 0x01, 0xD0, 0x4E, -0x49, 0x29, 0x00, 0xED, 0x00, 0x94, 0x00, 0x11, 0x0E, 0xC0, 0x4A, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x49, 0x04, 0x21, 0x01, 0x84, 0x0D, -0xD0, 0x16, 0x41, 0x73, 0x01, 0xE9, 0x05, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x68, -0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0x9C, 0x50, 0x79, 0x80, 0xED, 0x01, 0xB4, -0x87, 0x58, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x08, 0xA4, 0x04, 0x50, 0x1E, 0x40, -0x78, 0x00, 0xCD, 0x01, 0x04, 0x06, 0x10, 0x1F, 0x40, 0x0C, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77, 0x20, 0xD1, 0x04, 0x04, 0x07, 0xD0, -0x3C, 0x41, 0x33, 0x00, 0xC1, 0x40, 0x14, 0xA7, 0xD8, 0x0C, 0x40, 0xB0, 0x00, -0xCD, 0x00, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0x71, 0x83, 0xCD, 0x00, 0x34, 0x03, -0xD9, 0x0D, 0x50, 0x30, 0x00, 0xDD, 0x00, 0x24, 0x4B, 0xD1, 0x0C, 0x48, 0x11, -0x14, 0xCD, 0x00, 0x16, 0x27, 0x10, 0x0C, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x17, 0xA8, 0x5D, 0x40, 0x73, 0x00, 0xCD, 0x0D, 0xF0, 0x07, -0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x18, 0x02, 0x5F, -0x00, 0xFC, 0x01, 0x70, 0x05, 0xC0, 0x5D, 0x18, 0x5F, 0x00, 0x7C, 0x01, 0xF0, -0x05, 0xC0, 0x14, 0x00, 0x5D, 0x80, 0xC5, 0x01, 0xF8, 0x05, 0xC0, 0x5C, 0x00, -0x5F, 0x00, 0xCC, 0x01, 0x30, 0x67, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xF0, 0x01, 0x40, 0x04, 0x20, 0x1F, 0x82, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x01, 0x00, 0x1F, 0x02, 0x5C, 0x80, 0xF0, 0x21, 0xC0, 0x07, 0x02, 0x1F, -0x00, 0x7C, 0x8C, 0xF0, 0x01, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x67, 0x02, 0x93, 0x00, 0x4C, 0x0E, 0xF0, 0x39, 0xC0, 0x27, -0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x93, 0x00, 0x7C, -0x42, 0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xB2, 0x09, 0xC2, -0xE5, 0x00, 0x97, 0x05, 0x4C, 0x02, 0xF0, 0x08, 0xD0, 0x24, 0x00, 0x9F, 0x00, -0x5E, 0x02, 0xF0, 0x29, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x20, 0xE6, 0x60, 0x91, 0x03, 0x44, 0x06, 0xD0, 0x19, 0x40, 0x27, 0x00, -0x91, 0x00, 0x5C, 0x02, 0xD0, 0x09, 0x46, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02, -0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x74, 0x02, 0x10, 0x09, 0x48, 0xE4, -0x04, 0x91, 0x00, 0x44, 0x26, 0xD1, 0x49, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, -0x4E, 0xD2, 0x18, 0xC0, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x24, 0x04, 0xD1, 0x08, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x95, -0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x99, 0x00, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x27, 0x00, 0x95, 0x02, 0x34, 0x02, 0x90, 0x09, 0x60, 0x25, 0x00, -0x95, 0x40, 0x46, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x54, 0x22, -0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x20, 0x01, 0x81, 0x00, 0x04, 0x13, 0xD0, 0xC8, 0x40, 0x23, 0x11, 0x81, 0x0C, -0x14, 0x22, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x85, 0x04, 0x34, 0x22, 0xD0, 0x48, -0x60, 0x23, 0x02, 0x8D, 0x00, 0x34, 0x22, 0x10, 0x88, 0x40, 0x20, 0x08, 0x91, -0x00, 0x04, 0x06, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x04, 0x34, 0x12, 0xD0, -0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82, -0x02, 0x53, 0x0A, 0x4D, 0x30, 0xF0, 0x45, 0xC1, 0x87, 0x02, 0x17, 0x02, 0x7C, -0x08, 0xF0, 0xA0, 0xC0, 0x07, 0x08, 0x13, 0x0A, 0x3C, 0x08, 0xF0, 0x01, 0xC0, -0x87, 0x00, 0x17, 0x14, 0x7C, 0x08, 0xB0, 0x60, 0xC1, 0x05, 0x85, 0x56, 0x14, -0x44, 0x00, 0xF0, 0x41, 0xD1, 0x04, 0x00, 0x1F, 0x14, 0x5C, 0x00, 0xF0, 0x01, -0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x90, 0x2F, 0x22, -0xBF, 0x00, 0xFC, 0x33, 0xF0, 0x4B, 0xC0, 0x27, 0x02, 0x9F, 0x0C, 0xDC, 0x12, -0xF0, 0x89, 0xC0, 0x2F, 0x30, 0x9F, 0x08, 0xFC, 0x12, 0xF0, 0x89, 0xC8, 0x2F, -0x01, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x49, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0xFC, -0x02, 0xD0, 0x09, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0, -0x65, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x01, 0xBF, -0x00, 0xCC, 0x32, 0xE0, 0x0B, 0xC8, 0x24, 0x00, 0x9F, 0x08, 0x6C, 0x02, 0xE0, -0x49, 0xC1, 0x2E, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x0B, 0xD8, 0x24, 0x20, -0xBF, 0x34, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x2D, 0x00, 0xB3, 0x00, 0xEC, 0x02, -0xF0, 0x4B, 0xC1, 0x2C, 0x20, 0x9F, 0x55, 0xF8, 0x02, 0xF0, 0x0A, 0xC0, 0x60, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1D, 0x04, -0x44, 0xB0, 0xD0, 0x25, 0x41, 0x04, 0x04, 0x1D, 0x08, 0x44, 0x50, 0xD2, 0x41, -0x44, 0x04, 0x00, 0x17, 0x12, 0x74, 0x40, 0x14, 0x81, 0x68, 0x04, 0x05, 0x1D, -0x00, 0x74, 0x10, 0x71, 0x21, 0x41, 0x04, 0x00, 0x15, 0x08, 0x44, 0x00, 0xD0, -0x01, 0x40, 0x05, 0x20, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0xC0, 0x72, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x03, 0x8D, 0x15, 0x04, -0x92, 0xD0, 0xC8, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x24, 0x12, 0xD0, 0x48, 0x41, -0x22, 0x20, 0x8D, 0x0C, 0x36, 0x02, 0x10, 0x08, 0x40, 0x22, 0x21, 0x8D, 0x00, -0x30, 0x12, 0xD1, 0xC8, 0x40, 0x31, 0x02, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x08, -0x40, 0x22, 0x00, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x88, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x65, 0x00, 0x8D, 0x00, 0x44, 0x02, -0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x22, 0xD0, 0x09, 0x40, 0x24, -0x00, 0x95, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x26, 0x06, 0x9D, 0x00, 0x74, -0x02, 0x50, 0x08, 0x48, 0x34, 0x08, 0x95, 0x20, 0x46, 0x43, 0xD0, 0x09, 0x40, -0x67, 0x00, 0x9D, 0x00, 0x76, 0x0E, 0xD0, 0x49, 0x40, 0x62, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0xE7, 0x04, 0x9F, 0x01, 0x4D, 0x02, 0xF0, -0x39, 0xE0, 0x24, 0x00, 0x9D, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04, -0x9F, 0x00, 0x7C, 0x0A, 0x30, 0x09, 0x40, 0x66, 0x00, 0x9F, 0x20, 0x7C, 0x02, -0xD0, 0x09, 0x40, 0x25, 0x00, 0x93, 0x00, 0x5D, 0x8A, 0xF0, 0x09, 0xC0, 0xE6, -0x04, 0x9F, 0x00, 0x7C, 0x0E, 0xF0, 0x08, 0x40, 0x14, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x66, 0xF3, 0x88, -0xD1, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC8, 0x27, 0x00, 0x9F, -0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x8F, 0x00, 0x5C, 0x02, 0xF0, 0x08, 0xC1, 0x25, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x08, 0x85, 0x02, 0x1F, 0x00, 0x4D, 0x08, 0xF8, 0x21, 0xC0, -0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC4, 0x07, 0x00, 0x1F, 0x00, -0x7C, 0x08, 0xF0, 0x00, 0xC0, 0x84, 0x00, 0x1F, 0x01, 0x4C, 0x00, 0xF0, 0x01, -0xC0, 0x02, 0x00, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, -0x00, 0x7C, 0x40, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0xA0, 0x1C, 0x02, 0x7D, 0x02, 0xC4, 0x01, 0xD0, 0x37, 0xC0, 0x15, -0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x48, 0x5F, 0x00, 0x5F, 0x00, 0x74, -0x01, 0xD0, 0x15, 0x01, 0x14, 0x00, 0x7D, 0x05, 0x45, 0x01, 0xF0, 0x05, 0xC0, -0x1D, 0x00, 0x7F, 0x20, 0xF4, 0x4D, 0xD0, 0x07, 0x40, 0x54, 0x20, 0x5D, 0x00, -0xF4, 0x01, 0x34, 0x07, 0xD0, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0xA0, 0x72, 0x80, 0x8D, 0x10, 0x04, 0x03, 0xD0, 0xBC, 0x40, 0x31, 0x00, -0xDD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x06, 0xCD, 0x00, 0x74, 0x03, -0xD0, 0x18, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0xB0, -0x01, 0xC1, 0x12, 0x34, 0x0B, 0xD0, 0x34, 0x50, 0x70, 0x00, 0xCD, 0x00, 0x34, -0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x80, 0x28, 0x01, 0x7D, 0x08, 0x84, 0x43, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED, -0x0C, 0xB4, 0x13, 0xDA, 0xCE, 0x40, 0x1B, 0x00, 0xED, 0x08, 0xB4, 0x13, 0xD1, -0x0B, 0x40, 0x38, 0x21, 0x0D, 0x01, 0x86, 0x23, 0xD2, 0x4C, 0x40, 0x21, 0x00, -0x65, 0x10, 0xB0, 0x01, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xED, 0x00, 0xF4, 0x47, -0x10, 0x0F, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, -0xF8, 0x00, 0xAF, 0x05, 0x8C, 0x07, 0xD0, 0x16, 0xC0, 0x79, 0x00, 0xEF, 0x05, -0xBC, 0x0F, 0xF0, 0x1E, 0xC4, 0x7B, 0x20, 0xED, 0x11, 0xB4, 0x87, 0xD0, 0x0F, -0xC0, 0x78, 0x01, 0x2F, 0x21, 0x8C, 0x57, 0xF0, 0xBE, 0xC4, 0x68, 0x00, 0xE1, -0x01, 0xB0, 0x05, 0xF0, 0x1C, 0xC4, 0x78, 0x00, 0xEF, 0x01, 0xF8, 0x05, 0xB0, -0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, -0x00, 0x8F, 0x40, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0xB5, 0x00, 0xDF, 0x00, 0x7C, -0x03, 0xF1, 0x4D, 0xC1, 0x37, 0x00, 0xD6, 0x44, 0x7C, 0xAB, 0xF0, 0x0D, 0xCC, -0xB7, 0x06, 0x1F, 0x00, 0x6C, 0x03, 0x60, 0x6D, 0xC0, 0x25, 0x00, 0x5F, 0x00, -0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x41, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x4F, 0x00, -0x23, 0x41, 0xDD, 0x27, 0xF8, 0x8F, 0xC0, 0xFF, 0x04, 0xFB, 0x01, 0xDC, 0x07, -0xF0, 0x9F, 0xC0, 0x6C, 0x02, 0xFF, 0x01, 0xEC, 0x2F, 0xF2, 0x9B, 0xC2, 0x7F, -0x42, 0x33, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x48, 0x00, 0xB3, 0x89, 0xAE, -0x25, 0x30, 0x1F, 0xC2, 0x7F, 0x02, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1E, 0xC0, -0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x09, 0x00, 0x61, -0x08, 0x85, 0x01, 0xD8, 0x0E, 0x41, 0x3F, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD2, -0x0F, 0x54, 0x88, 0x20, 0xE7, 0x00, 0x85, 0x23, 0xD0, 0xCA, 0x40, 0x3B, 0x02, -0x21, 0x08, 0xAC, 0x03, 0x70, 0x0F, 0x48, 0x28, 0x00, 0xEB, 0x00, 0x8C, 0x01, -0xB0, 0x4A, 0x40, 0x3B, 0x02, 0xED, 0x00, 0x34, 0x1B, 0xD0, 0x0E, 0x50, 0x54, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x04, 0x21, 0x02, -0x94, 0xC3, 0xD0, 0x86, 0x40, 0x3B, 0x00, 0xE9, 0x00, 0x94, 0x23, 0xD0, 0x0E, -0x42, 0x38, 0x90, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0A, 0x00, 0x3F, 0x04, 0x01, -0x00, 0x84, 0x23, 0xD0, 0x0E, 0x40, 0x09, 0x00, 0xA1, 0x40, 0x97, 0x01, 0x12, -0x0E, 0x48, 0x2B, 0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0xA7, 0x01, 0x01, 0x81, 0x44, -0x0E, 0xD0, 0x31, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD8, 0x0C, 0x40, -0xB0, 0x08, 0xC5, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x33, 0x00, 0x01, 0x00, -0x24, 0x03, 0x58, 0x0C, 0x50, 0x21, 0x00, 0xC9, 0x00, 0x04, 0x40, 0x12, 0x08, -0x40, 0x23, 0x01, 0xCD, 0x00, 0x74, 0x9E, 0xD1, 0x8C, 0x40, 0x10, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xFD, 0x40, 0x33, 0x01, 0x5C, 0x04, -0xD0, 0x19, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xD4, 0x03, 0xF0, 0x0F, 0xC0, 0x74, -0x00, 0xFE, 0x00, 0xCC, 0x03, 0xF0, 0x09, 0xC0, 0xBB, 0x80, 0x13, 0x00, 0xCC, -0x03, 0xF0, 0x0F, 0x40, 0x25, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x10, 0x05, 0xC8, -0x37, 0x00, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x0D, 0xC0, 0x54, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x08, 0x5F, 0x0A, 0x7C, 0x40, 0xF0, -0x29, 0xC1, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x23, 0xF3, 0x0D, 0xC4, 0xC7, 0x00, -0xC4, 0x80, 0x5C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x01, 0x1F, 0x00, 0x7C, 0x03, -0x70, 0x0C, 0xC0, 0x26, 0x00, 0x5F, 0x02, 0x50, 0x05, 0xF0, 0x0D, 0xC0, 0x27, -0x00, 0xDE, 0x40, 0x7C, 0x03, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x02, 0x33, 0x20, 0xCC, 0x00, 0x30, 0x0B, -0xC0, 0x3C, 0x00, 0xFE, 0x00, 0xFE, 0x03, 0xB2, 0x0F, 0xC2, 0x7F, 0x05, 0xFF, -0x00, 0xCD, 0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC2, 0x0E, 0x00, 0x0F, 0x01, 0xCD, 0x01, 0x30, 0x4F, 0xC0, 0x7C, 0x01, -0xEF, 0x00, 0xCC, 0x07, 0x30, 0x1B, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x20, 0x76, 0x20, 0x05, 0x04, 0x44, 0x04, 0x10, 0x39, 0x41, -0x34, 0x00, 0xDD, 0x00, 0x34, 0x03, 0x70, 0x0D, 0x40, 0xA7, 0x80, 0xDD, 0x00, -0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x00, 0x11, 0x03, 0x74, 0x03, 0x72, 0x0D, -0x48, 0x45, 0x00, 0x1D, 0x05, 0x04, 0x08, 0x52, 0x0C, 0x40, 0x24, 0x00, 0xDD, -0x00, 0x44, 0x09, 0x10, 0x9C, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0xA0, 0x14, 0x50, 0x11, 0x00, 0x44, 0x06, 0x10, 0x11, 0x60, 0x36, -0x10, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x4A, 0x07, 0x80, 0xDD, 0x00, 0x44, -0x03, 0xD0, 0x09, 0x68, 0x37, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x0D, 0x40, -0x44, 0x00, 0x9D, 0x08, 0x44, 0x20, 0x10, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00, -0x54, 0x13, 0x50, 0x05, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x22, 0x00, 0x00, 0x51, 0x00, 0x05, 0x04, 0x14, 0x08, 0x50, 0x32, 0x00, -0xCD, 0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x03, 0x00, 0xCD, 0x80, 0x04, 0x03, -0xD0, 0x08, 0x40, 0x34, 0x20, 0x01, 0x00, 0x34, 0x03, 0x52, 0x0C, 0x40, 0x21, -0x10, 0xCD, 0x00, 0x44, 0x00, 0x50, 0x0C, 0x44, 0x20, 0x00, 0xCD, 0x00, 0x45, -0x0B, 0x14, 0x0D, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xB0, 0x32, 0x00, 0x11, 0x00, 0x4D, 0x02, 0x30, 0x01, 0xC2, 0x3E, 0x10, 0xDF, -0x00, 0x74, 0x03, 0x30, 0x0F, 0xC0, 0x17, 0x10, 0xED, 0x00, 0xCC, 0x03, 0xF0, -0x09, 0x88, 0x3F, 0x40, 0x13, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x04, 0x20, -0x1F, 0x00, 0x4E, 0x00, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x0B, -0x30, 0x01, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, -0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xCA, 0x3D, 0x00, 0xFF, 0x20, -0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, -0xC0, 0x39, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x40, 0x0F, 0xC0, 0x0D, 0x00, 0x3F, -0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0, -0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3F, -0x00, 0xFB, 0x1C, 0xEC, 0x05, 0x30, 0x0B, 0xC0, 0x5F, 0x00, 0xBF, 0x00, 0xEC, -0x03, 0xB0, 0x0F, 0xC1, 0x3F, 0x00, 0x3B, 0x81, 0xEC, 0x33, 0x70, 0x0F, 0xC0, -0x4F, 0x00, 0x2F, 0x01, 0xFC, 0x84, 0xF0, 0x4F, 0x80, 0x7C, 0x00, 0x7B, 0x01, -0xBC, 0x04, 0xF0, 0x13, 0xC2, 0x4E, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0xF0, 0x03, -0x44, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0xFF, 0x02, -0xF1, 0x02, 0x44, 0x06, 0x14, 0x19, 0x40, 0x26, 0x00, 0x8D, 0x70, 0x74, 0xAF, -0x10, 0x1F, 0x40, 0xFF, 0x00, 0x9D, 0x01, 0x74, 0x3B, 0x10, 0xBF, 0x40, 0x77, -0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0xBF, 0x40, 0x38, 0x05, 0x91, 0x01, 0x74, -0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x76, 0x86, 0xD2, 0x19, 0x40, -0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x20, 0xC8, -0x04, 0x64, 0x01, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x04, 0x06, 0x03, 0x90, -0x0C, 0x42, 0xB3, 0x00, 0x81, 0x00, 0x34, 0x13, 0x50, 0x0C, 0x60, 0x33, 0x20, -0xCD, 0x80, 0x34, 0x02, 0x52, 0x0C, 0x60, 0x30, 0x40, 0x85, 0x40, 0x16, 0x00, -0xD0, 0x00, 0x42, 0x03, 0x00, 0xC5, 0x80, 0x34, 0x00, 0xD2, 0x00, 0x42, 0x47, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00, -0x44, 0x02, 0x50, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x23, 0x74, 0x03, 0x50, 0x0D, -0x40, 0x37, 0x00, 0x9C, 0x01, 0x34, 0x03, 0x10, 0x0D, 0x00, 0x37, 0x00, 0xDD, -0x06, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x10, 0x95, 0x00, 0x74, 0x0E, 0xD0, -0x11, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xC0, 0x19, 0x40, 0x0F, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDB, 0x80, 0x2C, -0x12, 0x71, 0x11, 0xC1, 0x17, 0x01, 0x1F, 0x03, 0x4C, 0x03, 0xB0, 0x0D, 0xC0, -0x37, 0x00, 0x13, 0x03, 0x6C, 0x03, 0x72, 0x0D, 0xC8, 0x07, 0x01, 0x1E, 0x00, -0x7C, 0x01, 0xF0, 0x0C, 0xC0, 0x34, 0x00, 0x55, 0x05, 0x7C, 0x04, 0xD0, 0x31, -0xC0, 0x47, 0x01, 0xDF, 0xA0, 0x74, 0x04, 0xF0, 0x19, 0xC1, 0x03, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x39, 0x00, 0xEF, 0x00, 0xFC, 0x02, -0xB0, 0x03, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xBC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F, -0x00, 0x3F, 0x00, 0x7C, 0x03, 0xD0, 0x0F, 0xC0, 0x3F, 0x01, 0xFF, 0x41, 0xFC, -0x03, 0xF0, 0x0F, 0xC1, 0x3F, 0x00, 0xB3, 0x09, 0xF8, 0x02, 0xF0, 0x03, 0xC0, -0x0F, 0x00, 0xFF, 0x00, 0xF8, 0x40, 0xF0, 0x09, 0xC1, 0x1F, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, -0x29, 0xC0, 0x37, 0x00, 0x1F, 0x22, 0x6C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x00, -0x13, 0x46, 0x7C, 0x03, 0xB2, 0x0D, 0xC4, 0x34, 0x00, 0xDF, 0x02, 0x4C, 0x17, -0xB0, 0x8D, 0xC2, 0x37, 0x10, 0x9F, 0x80, 0x7E, 0x08, 0xB4, 0x81, 0xC8, 0x27, -0x11, 0xDF, 0x00, 0x5E, 0x00, 0xF0, 0x29, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x00, 0x44, 0x12, 0xD0, 0x09, -0x40, 0x27, 0x22, 0x9D, 0xA0, 0xC4, 0x4B, 0x50, 0x1F, 0x40, 0x3F, 0x00, 0x1A, -0x03, 0xF4, 0x03, 0x10, 0x0F, 0x40, 0x74, 0x01, 0xDD, 0x00, 0x44, 0x0B, 0x10, -0x2F, 0x42, 0x37, 0x00, 0x91, 0x0B, 0x74, 0x02, 0x21, 0x01, 0x40, 0xA7, 0x01, -0xDD, 0x00, 0x46, 0x1A, 0x90, 0x29, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40, -0x32, 0x02, 0x0D, 0x00, 0x24, 0x1F, 0x10, 0x0C, 0x48, 0x33, 0x00, 0x04, 0x00, -0x34, 0x03, 0x90, 0x0C, 0x40, 0x43, 0x01, 0x0D, 0xA0, 0x26, 0x88, 0x10, 0x2C, -0x48, 0x33, 0x00, 0xC4, 0x08, 0x34, 0x00, 0x10, 0x50, 0x48, 0x42, 0x20, 0xC9, -0x80, 0x24, 0x02, 0xD2, 0x20, 0x40, 0x1E, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x80, 0x70, 0x00, 0xC1, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x40, 0x6B, -0x00, 0x6D, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x02, 0xAD, 0x29, 0xB4, -0x07, 0x10, 0x1E, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x07, 0x10, 0x1E, 0x60, -0x7B, 0x22, 0xE1, 0x41, 0xF4, 0x04, 0x90, 0x92, 0x40, 0x7B, 0x00, 0xED, 0x01, -0x84, 0x06, 0x90, 0x12, 0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x03, 0xD0, 0x04, 0xC0, 0x23, 0x00, -0xCF, 0x00, 0x2E, 0x03, 0x30, 0x0C, 0xE8, 0x33, 0x02, 0x87, 0x12, 0x3C, 0x03, -0xB0, 0x0C, 0xC1, 0x03, 0x20, 0x0D, 0x01, 0x2D, 0x16, 0x30, 0x8C, 0xC0, 0x33, -0x00, 0x87, 0x08, 0x34, 0x06, 0x30, 0x50, 0xC2, 0x13, 0x00, 0xCF, 0x00, 0x3C, -0x03, 0xF0, 0x84, 0xC0, 0x4A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xB8, 0x3D, 0x00, 0xFC, 0x22, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x2F, 0x02, 0xFF, -0x00, 0x9C, 0x63, 0xF0, 0xAF, 0xC0, 0x33, 0x4A, 0x93, 0x00, 0xFC, 0x03, 0xF0, -0x0E, 0xC1, 0x0C, 0x92, 0x1F, 0x80, 0x0C, 0x23, 0x74, 0x0F, 0xC0, 0x77, 0x00, -0xB7, 0x08, 0x7C, 0x02, 0x70, 0x87, 0xE0, 0x3F, 0x00, 0xEF, 0x00, 0xFD, 0x02, -0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, -0xB7, 0x03, 0xDF, 0x02, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x37, 0x00, 0x7F, 0x01, -0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x86, 0x13, 0x01, 0x5C, 0x03, 0x71, 0x5D, -0xC0, 0x40, 0x90, 0x13, 0x00, 0x7C, 0x01, 0x38, 0x0D, 0xC4, 0x37, 0x00, 0xD3, -0x80, 0x7C, 0x02, 0xD0, 0x11, 0xC0, 0x24, 0x80, 0xCF, 0x00, 0x4C, 0x00, 0xF1, -0x01, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, -0x03, 0xED, 0x02, 0xB4, 0x02, 0x10, 0x06, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84, -0x93, 0xD0, 0x2E, 0x42, 0x33, 0x21, 0xA1, 0x00, 0x84, 0x13, 0xD0, 0xCE, 0x68, -0x39, 0x30, 0xE1, 0x00, 0xB4, 0x03, 0x10, 0xCE, 0x40, 0x3F, 0x19, 0xE1, 0x20, -0xB4, 0x02, 0xD2, 0x02, 0x44, 0x38, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x02, -0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, -0xED, 0x01, 0x94, 0x07, 0x10, 0x1E, 0x41, 0x7B, 0x08, 0x6D, 0x00, 0xB4, 0x07, -0xD0, 0x5E, 0x40, 0x7B, 0x01, 0xB1, 0x21, 0xB4, 0x27, 0x50, 0x1C, 0x50, 0x3A, -0x00, 0xE1, 0x01, 0x94, 0x07, 0x91, 0x9E, 0x44, 0x3B, 0x03, 0xA1, 0x01, 0xB4, -0x46, 0xD8, 0x13, 0x44, 0x78, 0x00, 0xE5, 0x81, 0x84, 0xC7, 0xD0, 0x1A, 0x40, -0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x08, 0xCD, -0x00, 0x34, 0x2E, 0x15, 0x2C, 0x41, 0x23, 0x20, 0xCD, 0x13, 0x04, 0x03, 0xD0, -0x0C, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x24, 0x03, 0xD0, 0x0C, 0x44, 0x37, 0x00, -0xC1, 0x00, 0x34, 0x87, 0x90, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00, 0x34, 0x47, -0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x87, 0xD0, 0xEC, 0x40, 0x4B, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, -0xBC, 0x0D, 0x30, 0x07, 0xC0, 0x5F, 0x01, 0x7F, 0x40, 0x7C, 0x01, 0xD0, 0x05, -0xC0, 0x17, 0x10, 0x73, 0x03, 0x7C, 0x01, 0x71, 0x05, 0xC0, 0x9E, 0xC0, 0x73, -0x09, 0x9C, 0x05, 0x91, 0x05, 0xC0, 0x17, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xF0, -0x27, 0x40, 0x1C, 0x80, 0x4F, 0x00, 0xC4, 0x8D, 0xF0, 0x37, 0x40, 0x5F, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, -0x48, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xE0, -0x07, 0x40, 0x1F, 0x08, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x26, 0x1F, 0x8A, -0x7C, 0x20, 0x70, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF2, 0x01, -0xC0, 0x87, 0x39, 0x1F, 0x00, 0x7D, 0x40, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x06, -0x30, 0x09, 0xC0, 0x67, 0x00, 0x83, 0x00, 0x0C, 0x02, 0xB2, 0x09, 0xC8, 0x27, -0x02, 0x9B, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x91, 0x00, 0x7C, -0x22, 0xB4, 0x98, 0xC0, 0x25, 0x00, 0x93, 0x40, 0x4C, 0x26, 0x30, 0x09, 0xC1, -0x67, 0x02, 0x9B, 0x00, 0x0C, 0x02, 0x30, 0x39, 0xC0, 0x43, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x14, -0x09, 0xC0, 0x21, 0x02, 0x95, 0x00, 0x44, 0x02, 0x30, 0x09, 0xC0, 0x23, 0x00, -0x90, 0x01, 0x74, 0x02, 0xD0, 0x99, 0x40, 0x27, 0x00, 0x91, 0x04, 0x7C, 0x0E, -0x10, 0x09, 0x40, 0x2C, 0x00, 0x9B, 0x12, 0x2C, 0x0E, 0x14, 0x99, 0x40, 0xE3, -0x40, 0x91, 0x00, 0x44, 0x0A, 0x50, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0x8D, 0x00, 0x54, 0x22, 0x10, 0x09, -0x60, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09, 0x44, 0x27, 0x00, 0x99, -0x00, 0x70, 0x02, 0xD8, 0x09, 0x40, 0x67, 0x00, 0x95, 0x20, 0x76, 0x0A, 0x18, -0x09, 0x41, 0x25, 0x00, 0x91, 0x08, 0x40, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x04, -0x91, 0x01, 0x44, 0x47, 0x11, 0x29, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0xA0, 0x01, 0x8D, 0x04, 0x04, 0x02, 0x10, 0x48, 0x40, -0xA5, 0xA0, 0x85, 0x14, 0x04, 0x02, 0x90, 0x08, 0x40, 0x21, 0x00, 0xC9, 0x00, -0x34, 0x22, 0xD2, 0x08, 0x40, 0x27, 0x00, 0x85, 0x00, 0x74, 0x02, 0x1A, 0x08, -0x40, 0x20, 0x02, 0x99, 0x20, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81, -0x01, 0x04, 0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1D, 0x8A, 0x54, 0x01, 0x31, 0x01, 0xC1, 0x97, -0x00, 0x13, 0x0A, 0x4C, 0x50, 0xB0, 0x41, 0x41, 0x07, 0x05, 0x1B, 0x00, 0x7C, -0x58, 0xD0, 0x41, 0x41, 0x17, 0x00, 0x17, 0x20, 0x7E, 0x00, 0xB0, 0x41, 0xC1, -0xC5, 0x00, 0x13, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x0A, -0x4C, 0x00, 0x33, 0x01, 0xC2, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0xB8, 0x67, 0x02, 0x9F, 0x08, 0xBC, 0x02, 0xD0, 0x0B, 0xC8, 0x2D, 0x01, -0xBF, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xA6, 0x00, 0x7C, 0x12, -0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBB, 0x00, 0x9C, 0x82, 0xF0, 0x09, 0xC0, 0xA7, -0x09, 0xBF, 0x60, 0xDC, 0x82, 0xF0, 0x0A, 0xC0, 0x2F, 0x08, 0x97, 0x00, 0xFD, -0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x48, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x27, 0x05, 0x9F, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0x40, 0x2F, 0x02, 0x9F, -0x84, 0xF4, 0xD2, 0x70, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x22, 0x70, -0x4B, 0xC0, 0x2C, 0x00, 0xB7, 0x20, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x64, 0x03, -0xA5, 0x80, 0xCC, 0x02, 0x71, 0x0B, 0x40, 0x2D, 0x00, 0xBB, 0x20, 0xCC, 0x02, -0xF0, 0x0B, 0x82, 0x64, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, -0x47, 0x05, 0x1D, 0x4C, 0x74, 0x00, 0xC0, 0x01, 0x44, 0x07, 0x20, 0x1D, 0xB4, -0x74, 0x00, 0x70, 0x81, 0x40, 0x84, 0x00, 0x19, 0x80, 0x74, 0xA0, 0xD0, 0x01, -0x44, 0x06, 0x00, 0x13, 0x80, 0x5C, 0x00, 0xD0, 0x01, 0x40, 0x84, 0x10, 0x57, -0x00, 0x4C, 0x00, 0xD0, 0x01, 0xC0, 0x15, 0x20, 0x19, 0x50, 0x6C, 0x00, 0xD0, -0x01, 0x50, 0x70, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, -0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x0C, 0x34, -0x02, 0x50, 0x08, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x34, 0x02, 0x50, 0x88, 0x48, -0x26, 0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0xA0, 0x20, 0x85, 0x00, -0x17, 0x82, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x24, 0x02, 0xD0, 0x08, -0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, -0x9D, 0x00, 0x74, 0x13, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x10, 0x74, 0x02, -0x50, 0x09, 0x40, 0x24, 0x00, 0xD9, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26, -0x00, 0x91, 0x06, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x10, 0x95, 0x08, 0x44, -0x06, 0xD8, 0x19, 0x40, 0x25, 0x00, 0x99, 0x00, 0x64, 0x06, 0xD0, 0x19, 0x00, -0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x2D, 0x00, 0x9F, -0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0xA7, 0x02, 0x9F, 0x03, 0x7C, 0x02, 0x70, -0x09, 0xC4, 0x24, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x60, 0x01, -0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x97, 0x00, 0x5C, 0x46, -0x70, 0x59, 0xCE, 0xE5, 0x02, 0x9B, 0x00, 0x6C, 0x4E, 0xF0, 0x19, 0xC1, 0x14, -0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09, -0x50, 0x27, 0x24, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x65, 0x02, 0x9F, -0x41, 0x78, 0x02, 0xF1, 0x08, 0xD0, 0x27, 0x08, 0x9F, 0x01, 0x78, 0x02, 0xF0, -0x09, 0xC0, 0x67, 0x80, 0x9E, 0x00, 0x78, 0x02, 0xF1, 0x08, 0xC0, 0x53, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x5C, -0x00, 0xF8, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x80, 0xC0, -0x07, 0x00, 0x1F, 0x03, 0x7C, 0x00, 0xD2, 0x00, 0xD0, 0x04, 0x00, 0x1F, 0x12, -0x4C, 0x40, 0xB0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x7C, 0x18, 0xF0, 0x21, -0xC0, 0x07, 0x04, 0x13, 0x00, 0x4C, 0x18, 0x30, 0x01, 0xC0, 0x53, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x5D, 0x00, 0xC4, 0x01, -0x70, 0x05, 0x40, 0x9F, 0x08, 0x51, 0x00, 0xF4, 0x6D, 0xD0, 0x15, 0x40, 0x9F, -0x00, 0x7D, 0x10, 0x74, 0x01, 0xD1, 0x15, 0x43, 0x9C, 0x10, 0x7D, 0x00, 0xEC, -0x11, 0x70, 0x37, 0xC8, 0x16, 0x00, 0x6D, 0x10, 0xC5, 0x01, 0xD0, 0x87, 0x40, -0x5F, 0x04, 0x61, 0x18, 0xC4, 0x09, 0xB0, 0x07, 0x40, 0x53, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x14, 0x01, 0x50, -0x0C, 0x48, 0xB3, 0x04, 0xC1, 0x00, 0x36, 0x0E, 0xD0, 0x08, 0x40, 0xB3, 0x00, -0xCD, 0x01, 0x34, 0x03, 0xD8, 0x1C, 0x44, 0xB2, 0x81, 0xCD, 0x0B, 0x24, 0x03, -0x50, 0x3C, 0x41, 0x31, 0x00, 0xCD, 0x11, 0x04, 0x0E, 0xD0, 0x2C, 0x40, 0x73, -0x00, 0xC1, 0x40, 0x04, 0x03, 0x10, 0xAC, 0x61, 0x53, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x01, 0xED, 0x09, 0x84, 0x01, 0x50, 0x0E, -0x40, 0xFB, 0x40, 0xE1, 0x00, 0xB6, 0x02, 0xD0, 0x0E, 0x40, 0x3B, 0x04, 0xED, -0x20, 0xB4, 0x93, 0xD0, 0x1E, 0x40, 0xAA, 0x08, 0xFD, 0x01, 0xA4, 0x00, 0x51, -0x0E, 0x40, 0x3B, 0x02, 0x2D, 0x00, 0x86, 0x0A, 0xD0, 0x0E, 0x60, 0x7B, 0x08, -0xE1, 0x00, 0x05, 0x87, 0x90, 0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x10, 0x78, 0x01, 0xFF, 0x05, 0x9C, 0x05, 0x70, 0x1E, 0xC0, -0x7F, 0x00, 0xE3, 0x0F, 0xBC, 0x06, 0xF0, 0x1A, 0x40, 0x7B, 0x00, 0x2D, 0x01, -0xB4, 0x3F, 0xF0, 0x0C, 0xCC, 0x4A, 0x80, 0xEF, 0x01, 0xAE, 0x04, 0x70, 0x1C, -0xC0, 0x79, 0x05, 0x2D, 0x01, 0x9C, 0x07, 0xE9, 0x1E, 0xC0, 0x7B, 0x40, 0xE1, -0x21, 0x8C, 0x05, 0x30, 0x16, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x37, -0x00, 0xDF, 0x04, 0x7C, 0x02, 0xF2, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, -0x83, 0xF1, 0x0D, 0xC2, 0x25, 0x00, 0xCF, 0x40, 0x7C, 0x00, 0x60, 0x0D, 0xC0, -0xB6, 0x20, 0x1F, 0x00, 0x58, 0x83, 0xFA, 0x09, 0xC0, 0x13, 0x08, 0xCF, 0x00, -0x74, 0x02, 0xF1, 0x05, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xA2, 0x7F, 0x14, 0xFF, 0x01, 0xFC, 0x11, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, -0xFF, 0x09, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7E, 0x02, 0xFF, 0x09, 0xFC, 0x07, -0x70, 0x1F, 0xC8, 0x6F, 0x02, 0xEF, 0x41, 0xDC, 0x24, 0xF0, 0x1E, 0xC0, 0x7C, -0x00, 0x33, 0x09, 0xF8, 0x07, 0xF0, 0x9F, 0xC0, 0x7F, 0x02, 0xFB, 0x41, 0xCC, -0x05, 0x30, 0x97, 0xC4, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x41, 0xD1, 0x0E, 0xC0, 0x39, 0x23, 0xED, -0x08, 0xB4, 0x02, 0xB0, 0x8E, 0x08, 0x38, 0x00, 0xED, 0x08, 0xDC, 0x23, 0x30, -0x4E, 0x44, 0x6B, 0x2A, 0xC9, 0xC0, 0x10, 0x20, 0xD0, 0x82, 0x40, 0x39, 0x00, -0x2D, 0x0C, 0x34, 0x07, 0xD0, 0x04, 0x00, 0x3B, 0x07, 0xE7, 0x08, 0xAC, 0x29, -0x30, 0xAE, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x79, 0x00, 0xED, 0x00, 0xB4, 0x21, 0xD0, 0x0E, 0x40, 0x1B, 0x24, 0xED, 0x40, -0x96, 0x02, 0x90, 0x8E, 0x48, 0x29, 0x08, 0x2D, 0x00, 0x90, 0x03, 0x50, 0x0A, -0x48, 0x0B, 0x07, 0x65, 0x18, 0x94, 0x40, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0x2D, -0x80, 0xB4, 0x43, 0xD0, 0x0E, 0x48, 0x2B, 0x00, 0x65, 0x00, 0x84, 0x01, 0x90, -0x82, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, -0x00, 0xCD, 0x00, 0x34, 0x0D, 0xD0, 0x2C, 0x40, 0xE1, 0x04, 0xCD, 0x02, 0x34, -0x02, 0x80, 0x0C, 0x50, 0x21, 0x10, 0xCD, 0x12, 0x14, 0x03, 0x10, 0x08, 0x40, -0x63, 0x11, 0x49, 0x01, 0x04, 0x0C, 0xC0, 0x00, 0x42, 0x31, 0x00, 0x0D, 0x00, -0x34, 0x4B, 0xD8, 0x90, 0x42, 0x73, 0x01, 0x45, 0x00, 0x24, 0x2E, 0x14, 0x18, -0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, -0xFF, 0x00, 0x3C, 0x0F, 0xF0, 0x2D, 0xC1, 0x83, 0x00, 0xFF, 0x05, 0x5E, 0x03, -0xB0, 0x08, 0xC0, 0x35, 0x00, 0xCF, 0x81, 0xDC, 0x83, 0x70, 0x09, 0xC2, 0x23, -0x10, 0xD7, 0x00, 0x5C, 0x00, 0xF0, 0x0D, 0xC0, 0x3D, 0x08, 0x17, 0x18, 0x74, -0x03, 0xF0, 0x39, 0x68, 0x37, 0x10, 0xD7, 0x00, 0x4C, 0x82, 0xB8, 0x59, 0xC0, -0x77, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, -0x40, 0x7C, 0x11, 0xF0, 0x4D, 0xC2, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF1, -0x0D, 0x40, 0xB4, 0x00, 0xDF, 0x01, 0x5C, 0x03, 0x70, 0x0D, 0x82, 0xA7, 0x00, -0xDC, 0x44, 0x7C, 0x00, 0xF2, 0x0D, 0xC0, 0x33, 0x00, 0x16, 0x20, 0x7C, 0x03, -0xF0, 0x09, 0xC5, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC9, 0x07, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFB, 0x00, -0xFC, 0x0B, 0x30, 0x0E, 0xC0, 0x2C, 0x00, 0xF3, 0x10, 0xFC, 0x27, 0xF0, 0x09, -0xC0, 0x38, 0x40, 0x33, 0x05, 0xCC, 0x03, 0xF0, 0x0A, 0xC0, 0x0C, 0x00, 0xF3, -0xA0, 0xE8, 0xC0, 0x30, 0x13, 0xC0, 0x3F, 0x00, 0x3B, 0x01, 0xCC, 0x05, 0xF0, -0x03, 0xC2, 0x3D, 0x00, 0xFB, 0x01, 0x7C, 0x42, 0xF0, 0x02, 0x40, 0x04, 0x28, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xD1, 0x00, 0x74, -0x02, 0x14, 0x0D, 0x60, 0x64, 0x81, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, -0x35, 0x81, 0xD1, 0x23, 0x4C, 0x03, 0x30, 0x0D, 0x40, 0xE5, 0x00, 0xC1, 0x00, -0x10, 0x20, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x05, 0x43, 0x44, 0x15, 0xD0, 0x11, -0x43, 0x13, 0x00, 0xD1, 0x00, 0x7C, 0x0E, 0xD1, 0x31, 0x50, 0x04, 0x06, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32, 0x00, 0xD9, 0x00, 0x74, 0x03, -0x92, 0x0D, 0x50, 0x44, 0x08, 0xD1, 0x00, 0x74, 0xC3, 0xDA, 0x0D, 0x00, 0x14, -0x20, 0x11, 0x40, 0x64, 0x03, 0xD0, 0x49, 0x40, 0xC4, 0x00, 0x91, 0x08, 0x74, -0x40, 0x90, 0x4D, 0x40, 0x37, 0x00, 0x15, 0x14, 0x64, 0x23, 0xD1, 0x19, 0x04, -0x37, 0x00, 0x91, 0x04, 0x74, 0x04, 0xD9, 0x19, 0x40, 0x05, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x01, 0x90, -0x0C, 0x40, 0x04, 0x00, 0xC5, 0x00, 0x34, 0x01, 0xD0, 0x0C, 0x40, 0x11, 0x10, -0x01, 0x00, 0x24, 0x03, 0x50, 0x0C, 0x46, 0x05, 0xE1, 0x91, 0x02, 0x54, 0x20, -0x90, 0x00, 0x40, 0x33, 0x00, 0x15, 0x00, 0x05, 0xB3, 0xD8, 0x00, 0x00, 0x33, -0xC0, 0x81, 0x40, 0x24, 0x00, 0xD0, 0x08, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0xFB, 0x00, 0x7C, 0x03, 0xB0, 0x0D, -0x40, 0x04, 0x00, 0xF1, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x11, -0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x04, 0x05, 0x13, 0x02, 0x6C, 0x00, 0xB0, -0x01, 0x40, 0x3F, 0x00, 0x17, 0x00, 0x6C, 0x03, 0xF2, 0xA1, 0xC0, 0x27, 0x00, -0x43, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x05, 0x40, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x70, 0x0F, 0xC0, -0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x00, -0xD0, 0x03, 0x30, 0x0B, 0xC0, 0x07, 0x10, 0x3F, 0x80, 0xEC, 0x90, 0xF0, 0x03, -0xC0, 0x3F, 0x00, 0x3C, 0x00, 0x7C, 0x1B, 0xF0, 0x43, 0xC0, 0x3F, 0x00, 0x7F, -0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x80, 0x0F, 0x06, 0xAF, 0x00, 0xEC, 0x02, 0xE0, 0x1E, 0xC0, 0x0F, -0x05, 0xFB, 0x0C, 0xFC, 0x50, 0x30, 0x43, 0xC0, 0x2C, 0x01, 0x33, 0x00, 0xCC, -0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x05, 0x23, 0x01, 0xEC, 0x03, 0xB0, 0x13, 0xC0, -0x3F, 0x01, 0x3B, 0x01, 0xC4, 0x06, 0xB6, 0x83, 0xC0, 0x0D, 0x03, 0x37, 0x00, -0xAC, 0x27, 0x30, 0x1E, 0xC0, 0x0E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x10, 0x87, 0x01, 0x9D, 0x01, 0x44, 0x00, 0xD0, 0x0D, 0x40, 0x83, 0x00, -0xF1, 0x08, 0x74, 0x10, 0x10, 0x09, 0x40, 0xB4, 0x07, 0x55, 0x10, 0x84, 0x2B, -0x10, 0x41, 0xC3, 0x44, 0x00, 0x11, 0x01, 0xC4, 0x07, 0xB0, 0x15, 0xC0, 0xBD, -0x12, 0xD1, 0x01, 0x44, 0x42, 0x10, 0xE1, 0x40, 0x90, 0x03, 0x11, 0x23, 0x44, -0x12, 0x10, 0x11, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, -0xA0, 0x03, 0x00, 0x8D, 0x80, 0x14, 0x06, 0xC0, 0x0C, 0x40, 0x01, 0x00, 0xC9, -0x04, 0x36, 0x40, 0x10, 0x64, 0x49, 0x20, 0x09, 0x01, 0x08, 0x04, 0xC3, 0x10, -0x44, 0x40, 0x13, 0x00, 0x01, 0x00, 0x14, 0x0B, 0x98, 0x08, 0x42, 0x33, 0x95, -0x15, 0x00, 0x64, 0x13, 0x10, 0x48, 0x48, 0x01, 0x00, 0x05, 0x82, 0x76, 0x11, -0x11, 0x0C, 0x50, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, -0x45, 0x00, 0xDD, 0x22, 0x54, 0x04, 0xD1, 0x0D, 0x40, 0x47, 0x10, 0xD1, 0x00, -0x74, 0x09, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x10, 0x44, 0x03, 0x10, 0x21, -0x40, 0x84, 0x00, 0x11, 0x01, 0x54, 0x03, 0x80, 0x0D, 0x42, 0x35, 0x00, 0x15, -0x10, 0x64, 0x02, 0x10, 0x09, 0x44, 0x25, 0x04, 0xD5, 0x14, 0x54, 0x03, 0x10, -0x09, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x47, -0x00, 0x9F, 0x09, 0x7D, 0x04, 0xF0, 0x9D, 0xC0, 0xC7, 0x20, 0xDB, 0x80, 0x7C, -0x09, 0x31, 0x51, 0xC0, 0x64, 0x02, 0x13, 0x02, 0x4C, 0x03, 0x30, 0x2D, 0xC0, -0xC7, 0x42, 0x13, 0x01, 0x7C, 0x03, 0xB0, 0x89, 0xC0, 0x37, 0x00, 0x9F, 0x02, -0x2D, 0x02, 0xB1, 0xB5, 0xC0, 0x85, 0x00, 0x05, 0x03, 0x7C, 0x6F, 0x24, 0x1C, -0x80, 0x8A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, -0xAF, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0B, 0x10, 0xFF, 0x00, 0xBC, 0x02, -0xF2, 0x91, 0xC0, 0x7B, 0x00, 0x2F, 0x00, 0xBC, 0x03, 0xF0, 0x57, 0xC0, 0x2D, -0x00, 0x3E, 0x00, 0xAC, 0x83, 0xF0, 0x0B, 0xC8, 0x3B, 0x00, 0xFB, 0x49, 0xDC, -0x02, 0xD0, 0x12, 0xC0, 0x1A, 0x40, 0xFB, 0x00, 0xEC, 0x03, 0xF4, 0x5F, 0xC0, -0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x80, 0x9F, -0x07, 0x6C, 0x02, 0x70, 0x8D, 0xC0, 0x06, 0x00, 0xD3, 0x20, 0x5E, 0x09, 0x38, -0x00, 0xC0, 0x24, 0x02, 0x5F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x93, 0x00, -0x1F, 0x06, 0x4C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x20, 0x1B, 0x20, 0x4E, 0x03, -0xF1, 0x0D, 0xC0, 0x96, 0x0A, 0x17, 0x02, 0x6C, 0x43, 0x30, 0x0D, 0xC0, 0x28, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x44, 0x86, 0xDD, 0xC2, -0x44, 0xE8, 0x12, 0x1D, 0x40, 0x04, 0x00, 0xF1, 0x00, 0x6C, 0x03, 0x31, 0x01, -0x40, 0xF4, 0x02, 0xDD, 0x04, 0xC4, 0x03, 0x10, 0x05, 0xC6, 0xE7, 0x81, 0x0F, -0x40, 0xD0, 0x0B, 0xB1, 0x1D, 0x40, 0x3D, 0x00, 0x41, 0x00, 0x4C, 0x02, 0x70, -0x09, 0x44, 0x34, 0x12, 0xDB, 0x1B, 0x08, 0x43, 0x10, 0x7D, 0x40, 0x4D, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x02, 0x30, 0x0D, 0x00, 0x04, -0x06, 0x10, 0x58, 0x50, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x02, 0x90, 0x00, 0x40, -0x30, 0x00, 0x8D, 0x01, 0x04, 0x27, 0x10, 0x09, 0x40, 0x23, 0x21, 0x09, 0x42, -0x04, 0x0F, 0x50, 0xF4, 0x48, 0x30, 0x10, 0x41, 0x00, 0x06, 0x02, 0xDA, 0x00, -0x00, 0x62, 0x40, 0xCC, 0x03, 0x01, 0x07, 0x58, 0x7C, 0x40, 0x0C, 0x20, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x4A, 0x00, 0x6D, 0x01, 0x84, 0x07, -0x12, 0x1F, 0x44, 0x48, 0x00, 0xE1, 0x01, 0x24, 0x04, 0x10, 0x9A, 0x40, 0x78, -0x80, 0x4D, 0x01, 0x84, 0x27, 0x10, 0x1A, 0x42, 0x59, 0x00, 0x35, 0x01, 0x94, -0x03, 0xDC, 0x16, 0x60, 0x71, 0x02, 0xE1, 0x01, 0x84, 0x06, 0x50, 0x94, 0x40, -0x78, 0x83, 0xE9, 0x09, 0xC4, 0x27, 0x50, 0x16, 0x40, 0x35, 0x20, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x82, 0x00, 0x8D, 0x00, 0x4C, 0x23, 0x70, -0x88, 0xC0, 0x80, 0x42, 0xD3, 0x00, 0x34, 0x02, 0x90, 0x84, 0xC4, 0x30, 0x00, -0x8D, 0x00, 0x0C, 0x03, 0x30, 0x44, 0x40, 0x33, 0x01, 0x0D, 0x08, 0x0C, 0x13, -0x50, 0x04, 0x40, 0x30, 0x00, 0x03, 0x08, 0x0C, 0x83, 0xF0, 0xA0, 0xD0, 0x02, -0x01, 0x07, 0x88, 0x0C, 0x23, 0x70, 0x4C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0xFF, 0x08, 0xDE, 0x03, 0xF4, 0x0F, -0xC2, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x8F, 0xC2, 0x3F, 0x00, 0xFF, -0x40, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x08, 0xBC, 0x1B, 0x30, -0x8E, 0xC0, 0x3F, 0x00, 0xA7, 0xA0, 0xFD, 0x02, 0xF0, 0x87, 0xC0, 0x2F, 0x41, -0xEF, 0x08, 0x7C, 0x23, 0xB0, 0x0D, 0xC4, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA8, 0x0F, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xE1, 0x09, 0xC0, -0x07, 0x08, 0xDF, 0x06, 0x5C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x00, -0x4C, 0x27, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x7C, 0x23, 0xF8, 0x11, -0xC0, 0x36, 0x03, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0x13, -0x20, 0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x98, 0x29, 0x00, 0x6D, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x0B, -0x00, 0xFD, 0x12, 0x84, 0x02, 0xD0, 0x0F, 0x48, 0x38, 0x00, 0x21, 0x00, 0x04, -0x33, 0x14, 0x0A, 0x40, 0x3B, 0x40, 0x22, 0x00, 0xB4, 0x13, 0xD0, 0x0A, 0x40, -0x3C, 0x02, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x52, 0x3D, 0x00, 0xC5, 0x00, -0x84, 0x02, 0x10, 0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0xF9, 0x00, 0x8D, 0x01, 0x94, 0x0F, 0xD0, 0x1A, 0x40, 0x5B, 0x08, -0xED, 0x01, 0x94, 0x07, 0xD0, 0x3E, 0x40, 0x78, 0x40, 0xC1, 0x11, 0xA5, 0x07, -0x18, 0x1E, 0x40, 0x73, 0x00, 0x21, 0x01, 0xB4, 0x07, 0x50, 0x17, 0x46, 0x79, -0x01, 0xE9, 0x01, 0xB4, 0x07, 0xD2, 0x1C, 0x70, 0x58, 0x00, 0x21, 0x01, 0x86, -0x47, 0x10, 0x1E, 0x41, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x20, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0xB7, 0x00, 0xCD, -0x00, 0x04, 0x17, 0xD8, 0x0C, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10, -0x2C, 0x40, 0xB3, 0x01, 0xC1, 0x07, 0x34, 0x03, 0xD8, 0x2C, 0x40, 0x31, 0x00, -0xC1, 0x48, 0x74, 0x02, 0xD0, 0x2C, 0x64, 0x71, 0x80, 0xC5, 0x0B, 0x04, 0x9B, -0x12, 0x3C, 0x60, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, -0x1F, 0x00, 0x6F, 0x00, 0xDD, 0x0D, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x00, -0xDC, 0x49, 0xF0, 0x07, 0xD0, 0x14, 0x00, 0x73, 0x01, 0x6C, 0x01, 0x30, 0xD7, -0xC0, 0x9B, 0x40, 0x73, 0x11, 0x7C, 0x01, 0xF0, 0xB7, 0x54, 0x17, 0x00, 0x7B, -0x02, 0x7C, 0x01, 0xF0, 0x47, 0xC0, 0x5C, 0x09, 0x73, 0x80, 0x8C, 0x05, 0x35, -0x06, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, -0x00, 0x1F, 0x00, 0x6C, 0x98, 0xF2, 0x01, 0xC0, 0x07, 0x04, 0x0F, 0x00, 0x7C, -0x00, 0xF0, 0x41, 0xC0, 0x07, 0x08, 0x0F, 0x02, 0x5C, 0x80, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x04, -0x7C, 0x00, 0xB8, 0x01, 0xC1, 0x07, 0x00, 0x0F, 0x12, 0x7C, 0x00, 0xF0, 0x21, -0xC5, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x61, 0x04, -0x93, 0x00, 0x0D, 0x0E, 0x30, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x1C, 0x02, -0xB4, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC8, 0x27, -0x02, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x89, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, -0x02, 0x30, 0x09, 0xC8, 0x23, 0x20, 0x9B, 0x01, 0x4D, 0x22, 0x70, 0x19, 0xC2, -0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x95, -0x02, 0x44, 0x0E, 0x14, 0x09, 0x42, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10, -0x09, 0x48, 0x27, 0x08, 0x91, 0x12, 0x44, 0x42, 0xD0, 0x09, 0x44, 0x67, 0x10, -0x91, 0x00, 0x74, 0x46, 0xD0, 0x39, 0xE0, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x02, -0x50, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x4C, 0x02, 0x10, 0xA9, 0x40, 0x04, -0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x91, 0x02, -0x44, 0x02, 0x90, 0x89, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x09, -0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0xD5, -0x00, 0x74, 0x12, 0xD8, 0x0D, 0x45, 0x23, 0x00, 0x95, 0x00, 0x74, 0x02, 0x10, -0x09, 0x40, 0x27, 0x40, 0x99, 0x88, 0x44, 0x42, 0x50, 0x09, 0x42, 0x71, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x01, 0x85, 0x04, 0x04, -0x1B, 0x90, 0x28, 0x40, 0x23, 0x41, 0x81, 0x0C, 0x04, 0x12, 0x10, 0x48, 0x40, -0x23, 0x01, 0x8D, 0x04, 0x06, 0x12, 0xD0, 0x88, 0x40, 0x23, 0x01, 0xC1, 0x00, -0x36, 0x02, 0xD0, 0x08, 0x44, 0x23, 0x03, 0x81, 0x00, 0x14, 0x02, 0x50, 0x08, -0x44, 0x23, 0x02, 0xC9, 0x00, 0x44, 0x22, 0x10, 0x0D, 0x60, 0x50, 0xA8, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x00, 0x4C, 0x08, -0xB0, 0x25, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x83, -0x42, 0x1F, 0x0A, 0x44, 0x28, 0xD0, 0x21, 0x00, 0x17, 0x00, 0x1F, 0x40, 0x7C, -0x50, 0xF0, 0x01, 0x40, 0x87, 0x00, 0x17, 0x00, 0x7C, 0x28, 0x30, 0xE1, 0xC1, -0x87, 0x45, 0x1B, 0x14, 0x0C, 0x08, 0x70, 0x01, 0xC0, 0x75, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2F, 0x12, 0xBF, 0x08, 0xFC, 0x0A, 0x70, -0x0B, 0xC2, 0x2F, 0x02, 0x9F, 0x0C, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02, -0xB3, 0x08, 0x7C, 0x22, 0xF2, 0x4F, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02, -0xF0, 0x0A, 0xC0, 0x25, 0x03, 0xB6, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, -0x41, 0xB7, 0x00, 0xDC, 0x12, 0xF4, 0x0F, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xCC, 0x02, 0xF0, 0x0B, -0xC0, 0x33, 0x02, 0x93, 0x04, 0x7C, 0xD2, 0xB0, 0xC9, 0xC0, 0x2C, 0x00, 0xB3, -0x00, 0xCC, 0x22, 0x34, 0x09, 0xC0, 0x28, 0x05, 0xBB, 0x00, 0xDC, 0x02, 0xB0, -0x0B, 0xC0, 0x27, 0x02, 0xB3, 0x20, 0x5C, 0x8A, 0xF2, 0x49, 0xC2, 0x2D, 0x40, -0xBE, 0x00, 0xCC, 0x02, 0x30, 0x0A, 0xD0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1C, 0x18, 0x15, 0x01, 0x1D, 0x08, 0x45, 0xC8, 0xD0, 0x01, 0x49, -0x07, 0x02, 0x11, 0x14, 0x30, 0x10, 0x00, 0xC1, 0x42, 0x84, 0x04, 0x01, 0x10, -0x44, 0x20, 0x11, 0x41, 0x83, 0x05, 0x20, 0x57, 0x40, 0x5C, 0x08, 0x01, 0x01, -0x40, 0x03, 0x02, 0x11, 0x00, 0x64, 0x14, 0xD0, 0xD1, 0x41, 0x81, 0x44, 0x55, -0x00, 0x04, 0x01, 0x50, 0x01, 0x40, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x20, 0x31, 0x05, 0x8D, 0x00, 0x34, 0xB2, 0xD0, 0x08, 0x40, 0x23, -0x00, 0x81, 0x2C, 0x34, 0x52, 0x98, 0x48, 0x48, 0x20, 0x03, 0x81, 0xC8, 0x04, -0x02, 0x10, 0x49, 0x04, 0x20, 0x10, 0x81, 0x00, 0x14, 0x22, 0xD1, 0x08, 0x40, -0x23, 0x20, 0x81, 0x00, 0x16, 0x12, 0xD0, 0x08, 0x40, 0x21, 0x4B, 0x8D, 0xC0, -0x45, 0x02, 0x12, 0x09, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x25, 0x01, 0x9D, 0x03, 0x74, 0x0A, 0xD2, 0x09, 0x40, 0xA3, 0x40, -0x91, 0x40, 0x74, 0x02, 0x10, 0x08, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02, -0x10, 0x49, 0x50, 0x26, 0x12, 0x95, 0x00, 0x54, 0x03, 0x50, 0xA9, 0x40, 0x27, -0x00, 0x91, 0x00, 0x64, 0x12, 0xD0, 0x09, 0x40, 0x25, 0x40, 0x95, 0x08, 0x44, -0x12, 0x50, 0x09, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xA8, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x93, -0x60, 0x7C, 0x02, 0xB0, 0x19, 0xD0, 0x24, 0x40, 0x93, 0x02, 0x44, 0x02, 0x30, -0x08, 0xC2, 0x24, 0x08, 0x93, 0x02, 0x5C, 0x82, 0xF0, 0x19, 0xC8, 0x27, 0x40, -0x91, 0x18, 0x5C, 0x06, 0xF0, 0x29, 0xC1, 0x25, 0x00, 0x9F, 0x00, 0x44, 0x02, -0x20, 0x28, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, -0x65, 0x00, 0x8F, 0x00, 0x4C, 0x4E, 0xF0, 0x09, 0xC1, 0xE7, 0x30, 0x9F, 0x40, -0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09, -0xC0, 0x65, 0x00, 0x9F, 0x19, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x10, 0x9F, -0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0xE7, 0x40, 0x8B, 0x10, 0x7C, 0x82, 0xF0, -0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, -0x80, 0x1F, 0x06, 0x4E, 0x08, 0xF0, 0x01, 0xC4, 0x04, 0x80, 0x13, 0x00, 0x7E, -0x80, 0xF0, 0x01, 0xC0, 0x07, 0x06, 0x1F, 0x12, 0x5C, 0x20, 0xF8, 0x21, 0xC0, -0x07, 0x94, 0x13, 0x02, 0x3C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00, 0x1B, 0x0A, -0x7C, 0x00, 0xE1, 0x20, 0xC0, 0x80, 0x04, 0x17, 0x20, 0x4C, 0x00, 0x30, 0x81, -0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x00, -0x7D, 0x00, 0xC4, 0x01, 0x70, 0x57, 0x40, 0x15, 0x80, 0x5B, 0x40, 0x64, 0x01, -0xB2, 0x05, 0xC2, 0x1F, 0x20, 0x7D, 0x11, 0xC4, 0x25, 0x78, 0x05, 0xE0, 0xDB, -0x00, 0x7B, 0x04, 0xFC, 0x2D, 0x70, 0x37, 0x44, 0x17, 0x20, 0x53, 0x40, 0x58, -0x01, 0x70, 0x05, 0xD0, 0x1C, 0x00, 0x71, 0x00, 0xC4, 0x05, 0x14, 0x17, 0x40, -0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, -0x20, 0x06, 0x03, 0x50, 0x3C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0x50, -0x0C, 0x60, 0xF3, 0x08, 0xDD, 0x02, 0x14, 0x0F, 0xD1, 0x0C, 0x40, 0x13, 0x02, -0xC1, 0x03, 0x34, 0x0F, 0x41, 0x4C, 0x60, 0x37, 0x80, 0x81, 0x01, 0x34, 0x03, -0x90, 0x0C, 0x40, 0x32, 0x00, 0xC5, 0x03, 0x44, 0x1F, 0x50, 0x4C, 0x40, 0x50, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x28, 0x00, 0xAD, 0x00, -0x86, 0x41, 0x58, 0x1E, 0x60, 0x3D, 0x10, 0xE9, 0x40, 0xB4, 0x33, 0x10, 0x4E, -0x40, 0x39, 0x08, 0xED, 0x00, 0x84, 0x03, 0x50, 0x4E, 0x40, 0x19, 0x08, 0xE9, -0x00, 0x94, 0x09, 0x50, 0x26, 0x40, 0x3B, 0x03, 0xA1, 0x40, 0xB6, 0x13, 0x50, -0x8E, 0x40, 0x08, 0x04, 0xC1, 0x02, 0x84, 0x40, 0x50, 0x0E, 0x40, 0x05, 0x20, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x68, 0x00, 0xCD, 0x01, 0x85, -0x07, 0x70, 0x17, 0xC0, 0x78, 0x01, 0xE1, 0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40, -0x7B, 0x00, 0xED, 0x01, 0x9C, 0x85, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xE1, 0x01, -0xB4, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x40, 0xA3, 0x01, 0xBC, 0x1F, 0xF1, 0x5F, -0xC0, 0x7A, 0x00, 0xE7, 0x01, 0x8D, 0x07, 0x70, 0x1E, 0xC0, 0x44, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x2D, 0x00, 0x9F, 0x00, 0x7C, 0x01, -0x70, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x6C, 0x43, 0xF1, 0x2D, 0xC1, 0x37, -0x30, 0xDC, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, -0x02, 0x70, 0x0D, 0xC0, 0xB7, 0x04, 0x9B, 0x00, 0x58, 0x83, 0xFA, 0x0D, 0xCC, -0x06, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x6F, 0x00, 0xF3, 0x41, 0xCC, 0x13, 0xF0, -0x1F, 0xC0, 0xFF, 0x04, 0xFB, 0x91, 0xEC, 0x07, 0x80, 0x9F, 0xC1, 0x5C, 0x08, -0x7B, 0x89, 0xCC, 0x06, 0x30, 0x1F, 0xC1, 0x5F, 0x00, 0xB3, 0x01, 0xF8, 0xA7, -0xB0, 0x1F, 0xD0, 0x7C, 0x00, 0xFF, 0x21, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7D, -0x02, 0x77, 0x01, 0xCC, 0x07, 0xB0, 0x1F, 0xC0, 0x03, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x10, 0xAD, 0x40, 0xA1, 0x30, 0x84, 0x03, 0xD0, 0x0E, -0x45, 0x3F, 0x00, 0xE1, 0x00, 0x84, 0x63, 0x10, 0x0E, 0x48, 0x0C, 0x02, 0x31, -0x0C, 0xC5, 0x22, 0x10, 0x0E, 0x43, 0x9B, 0x02, 0xA1, 0x02, 0xB4, 0x01, 0x50, -0xA2, 0x40, 0x38, 0x80, 0xED, 0x10, 0xB4, 0x03, 0x70, 0x4E, 0x50, 0x18, 0x47, -0xFB, 0x00, 0xC4, 0x08, 0x14, 0x0A, 0x48, 0x57, 0x60, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x61, 0x08, 0x84, 0x63, 0xD0, 0x86, 0x40, -0x3B, 0x00, 0xE1, 0x00, 0x24, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x44, 0x61, 0x00, -0xA4, 0x00, 0x14, 0x0E, 0x40, 0x33, 0x44, 0x21, 0x10, 0xB4, 0x03, 0x11, 0x0E, -0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x43, 0xD0, 0x0E, 0x44, 0x39, 0x80, 0xF5, -0x00, 0x84, 0x43, 0x90, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x20, 0x23, 0x14, 0x01, 0x20, 0x04, 0x0E, 0xD0, 0x18, 0x40, 0xB3, -0x04, 0xC1, 0x00, 0x04, 0x03, 0x10, 0x2C, 0x41, 0x40, 0x00, 0x01, 0x03, 0x64, -0x00, 0x11, 0x2C, 0x40, 0xF3, 0x00, 0x01, 0x12, 0x34, 0x03, 0x50, 0x38, 0x40, -0x30, 0x00, 0xCD, 0x03, 0x76, 0x07, 0x50, 0x0D, 0x40, 0x54, 0x00, 0x49, 0x0C, -0x05, 0x0E, 0x10, 0x9C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x28, 0x25, 0x00, 0x93, 0x01, 0x45, 0x0A, 0xF8, 0x09, 0xC0, 0xBF, 0x40, -0xF3, 0x00, 0xEC, 0x0F, 0x30, 0x2F, 0xC0, 0x64, 0x00, 0x93, 0x12, 0x6C, 0x03, -0x30, 0x0E, 0xC0, 0x17, 0x10, 0x13, 0x03, 0x7C, 0x83, 0xB0, 0x18, 0xC0, 0x3C, -0x20, 0x9F, 0x00, 0xF4, 0x07, 0xF0, 0x5F, 0xC0, 0x75, 0x00, 0x97, 0x22, 0x04, -0x2F, 0xB0, 0xBC, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x87, 0x00, 0x0F, 0x80, 0x7E, 0x00, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7, -0x80, 0x7C, 0x13, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x97, 0x02, 0x5C, 0x0A, 0xF0, -0x0D, 0xE0, 0x17, 0x00, 0x9F, 0x20, 0x3C, 0x08, 0xF0, 0xC1, 0xC8, 0x37, 0x00, -0x9F, 0x04, 0x7C, 0x03, 0xF1, 0x0D, 0xC0, 0xA7, 0x44, 0xDF, 0x02, 0x7C, 0x88, -0xF2, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, -0x2D, 0x00, 0x9F, 0x00, 0xEC, 0x42, 0xE0, 0x03, 0xE0, 0x3F, 0x00, 0xDF, 0x00, -0xFC, 0x03, 0xF8, 0x0E, 0xD0, 0x2C, 0x02, 0x3F, 0x10, 0xCD, 0x07, 0x34, 0x0F, -0xC1, 0x3C, 0x04, 0x3F, 0x00, 0xFC, 0x02, 0xB1, 0x8F, 0xC0, 0x3E, 0x00, 0xBF, -0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x74, 0x40, 0xF7, 0x00, 0xFC, 0x17, 0x30, -0x0F, 0x00, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6, -0x08, 0x1D, 0x81, 0x44, 0x44, 0xD0, 0x11, 0x41, 0x37, 0x00, 0xDD, 0x00, 0x74, -0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x08, 0x19, 0x02, 0x4C, 0x0A, 0x10, 0x0D, 0x40, -0x84, 0x00, 0x97, 0x03, 0x74, 0x06, 0xB8, 0x1D, 0x00, 0x34, 0x00, 0x8D, 0x01, -0x54, 0x03, 0x10, 0x0D, 0x40, 0x24, 0x42, 0xD3, 0x09, 0x74, 0x05, 0x10, 0x05, -0x48, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x64, 0x00, -0x9D, 0x01, 0x64, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x54, 0x03, -0xD0, 0x0D, 0x40, 0x34, 0x00, 0xCD, 0x03, 0x44, 0x19, 0x10, 0x0D, 0x50, 0x14, -0x00, 0x18, 0x01, 0x74, 0x21, 0x10, 0x01, 0x00, 0x36, 0x00, 0x9D, 0x04, 0x44, -0x03, 0x10, 0x0D, 0x40, 0x84, 0x40, 0xDD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40, -0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x0D, -0x01, 0x05, 0x00, 0xD1, 0x08, 0x48, 0x33, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0, -0x0C, 0x40, 0x00, 0x00, 0x8D, 0x00, 0x06, 0x00, 0x10, 0x0D, 0x60, 0x10, 0x10, -0x85, 0x00, 0x34, 0x00, 0x91, 0x01, 0x40, 0x30, 0x00, 0x9D, 0x80, 0x16, 0x03, -0x10, 0x0C, 0x50, 0x00, 0x00, 0x81, 0x00, 0x74, 0x00, 0x50, 0x18, 0x50, 0x41, -0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x26, 0x00, 0x1F, 0x00, -0x6C, 0x02, 0xF1, 0x01, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xDC, 0x03, 0xD0, 0x0F, -0xC0, 0x34, 0x00, 0x5D, 0x00, 0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0x1F, -0x00, 0x7C, 0x01, 0x11, 0x05, 0xC0, 0x3E, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0x30, -0x0D, 0xC0, 0x04, 0x00, 0xDF, 0x80, 0x7C, 0x00, 0x31, 0x0D, 0xC0, 0x00, 0xC0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x0F, 0x00, 0x3F, 0x00, 0xFE, -0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x0F, 0x00, 0x3B, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC4, 0x3F, 0x08, 0x37, 0x00, -0xBC, 0x00, 0xF2, 0x02, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, -0xC0, 0x0F, 0x00, 0xF7, 0x40, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x16, 0x21, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x73, 0x01, 0xCC, 0x07, -0xF0, 0x1F, 0xC0, 0x3C, 0x01, 0xB3, 0x01, 0xAC, 0x05, 0xF0, 0x4F, 0xC0, 0x4D, -0x08, 0x3F, 0x03, 0x4C, 0x04, 0xF0, 0x0F, 0xC0, 0x4F, 0x40, 0x33, 0x01, 0xFC, -0x0C, 0x71, 0x90, 0xC0, 0x4C, 0x00, 0xA3, 0x01, 0xED, 0x04, 0xF0, 0x12, 0xC0, -0x4F, 0x00, 0x3F, 0x02, 0xCE, 0x26, 0x34, 0x03, 0xC0, 0x0F, 0x08, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x53, 0x00, 0x51, 0x01, 0xEC, 0x07, 0xD0, -0x1F, 0x40, 0x74, 0x00, 0x95, 0x01, 0x51, 0x06, 0xD0, 0x9F, 0x42, 0x44, 0x00, -0x1D, 0x00, 0x4C, 0x04, 0xD0, 0x3F, 0x40, 0x47, 0x00, 0x11, 0x01, 0x74, 0x00, -0x10, 0x45, 0x44, 0x45, 0x00, 0x11, 0x41, 0x44, 0x00, 0xD0, 0x11, 0x40, 0x47, -0x00, 0x97, 0x82, 0x6C, 0x10, 0x10, 0x11, 0x48, 0x0F, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x11, 0xA0, 0x25, 0x00, 0x81, 0x00, 0x04, 0x03, 0x51, 0x0C, -0x40, 0xB0, 0x00, 0x45, 0x00, 0x04, 0x01, 0x50, 0x0C, 0x40, 0x21, 0x00, 0x05, -0x04, 0x24, 0x03, 0xD0, 0x2C, 0x40, 0x07, 0x00, 0x01, 0x00, 0x74, 0x10, 0xD0, -0x09, 0x40, 0x35, 0x00, 0x95, 0x80, 0x14, 0x50, 0xD1, 0x00, 0x40, 0x01, 0x08, -0x4D, 0x06, 0x44, 0x02, 0x10, 0x08, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x27, 0x00, 0xC1, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40, -0x34, 0x00, 0x55, 0x06, 0x54, 0x02, 0xD0, 0x0D, 0x40, 0x44, 0x00, 0x0D, 0x81, -0x44, 0x23, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x11, 0x04, 0x74, 0x46, 0x10, 0x0D, -0x40, 0x35, 0x40, 0x15, 0x02, 0x50, 0x06, 0xD0, 0x11, 0x60, 0x07, 0x00, 0x95, -0x08, 0x45, 0x06, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA8, 0x73, 0x00, 0x93, 0x02, 0x4C, 0x03, 0xF0, 0x0C, 0xD0, 0x34, -0x80, 0xC7, 0x03, 0x6C, 0x1B, 0xF0, 0x0C, 0xC0, 0x65, 0x01, 0x9F, 0x01, 0x6C, -0x4E, 0xF0, 0x0D, 0xC0, 0x83, 0x01, 0x13, 0x00, 0x3C, 0x04, 0x70, 0x3D, 0xC0, -0xF5, 0x08, 0x87, 0x03, 0x54, 0x44, 0xF0, 0x31, 0xC1, 0x07, 0x11, 0x1F, 0x05, -0x44, 0x06, 0x30, 0x31, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x07, 0x80, 0xFD, 0x40, 0xBF, 0x00, 0xFC, 0x03, 0xF2, 0x0F, 0xC0, 0x3B, 0x20, -0xFF, 0x00, 0xE8, 0x96, 0xF0, 0x0F, 0xC0, 0x0F, 0x20, 0x3F, 0x00, 0xFC, 0x06, -0xE0, 0x0D, 0xC4, 0x4E, 0x02, 0x3F, 0x41, 0xF4, 0x02, 0xF0, 0x2F, 0xC0, 0xBF, -0x00, 0xBB, 0x02, 0xC4, 0x02, 0xD0, 0x03, 0x41, 0x0F, 0x00, 0x1F, 0x01, 0xFC, -0x00, 0xF0, 0x03, 0xC4, 0x3F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x08, 0xA5, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x6E, 0x0B, 0x30, 0x0D, 0xC0, 0xA4, 0x80, 0x9F, 0x02, 0x7C, 0x02, 0xF0, -0x8D, 0xC2, 0x07, 0x02, 0x1E, 0x00, 0x7C, 0x18, 0xF0, 0x0D, 0xC0, 0x36, 0x01, -0x9F, 0x06, 0x6C, 0x08, 0xF2, 0x81, 0xC8, 0x16, 0x44, 0x83, 0x02, 0x4D, 0x8A, -0x30, 0x29, 0xC4, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x24, 0x00, 0x91, 0x00, 0x74, 0x03, 0x50, 0x0D, 0x40, 0x3F, 0x00, 0xDD, 0x07, -0x76, 0x1E, 0xF0, 0xAF, 0x40, 0x44, 0x00, 0x9F, 0x80, 0x74, 0x4F, 0xD0, 0x1F, -0xC0, 0xC4, 0x00, 0x1F, 0x0C, 0x70, 0x02, 0xF0, 0x0C, 0x40, 0xF0, 0x08, 0x9D, -0x02, 0x50, 0x02, 0xD2, 0x11, 0x50, 0x54, 0x04, 0x91, 0x09, 0x64, 0x02, 0x34, -0x39, 0xC0, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x22, -0x00, 0xC1, 0x40, 0x24, 0x03, 0x10, 0x4C, 0x60, 0x33, 0x00, 0x4D, 0x04, 0x34, -0x1E, 0x10, 0x1C, 0x40, 0x40, 0x00, 0x89, 0x00, 0x36, 0x11, 0xD0, 0x4C, 0x60, -0x02, 0x04, 0x09, 0x00, 0x34, 0x0C, 0xDA, 0x00, 0x00, 0x82, 0x02, 0x08, 0x00, -0x14, 0x00, 0xD0, 0x20, 0x40, 0x40, 0x00, 0x09, 0x83, 0x64, 0x32, 0x90, 0xC8, -0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x7A, 0x40, -0xE1, 0x01, 0x34, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x81, 0xF6, 0x26, -0xD0, 0x1C, 0x40, 0x48, 0x00, 0x25, 0x49, 0xB6, 0x25, 0xD0, 0x9E, 0x40, 0x48, -0x00, 0x2D, 0x01, 0xB4, 0x05, 0xD1, 0x53, 0x40, 0x4A, 0x01, 0x7D, 0x81, 0x94, -0x24, 0xD8, 0x12, 0x60, 0x4C, 0x80, 0x69, 0x21, 0xA4, 0x24, 0x10, 0x13, 0x40, -0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0xA2, 0x00, 0x81, -0x00, 0x2C, 0x23, 0x10, 0x0C, 0xC0, 0x33, 0x00, 0x4F, 0x00, 0x34, 0x22, 0x10, -0x0C, 0xC1, 0x60, 0x05, 0x89, 0x07, 0x3C, 0x15, 0xF0, 0x8C, 0xC0, 0x03, 0x02, -0x0F, 0x01, 0x38, 0x46, 0xF0, 0x50, 0xE8, 0x42, 0x10, 0xCD, 0x14, 0x14, 0x23, -0xF0, 0x80, 0xC0, 0x00, 0x00, 0xCB, 0x10, 0x4C, 0x23, 0xB2, 0x2D, 0xE0, 0x4A, -0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D, 0x00, 0xFF, 0x80, -0xFC, 0x07, 0x70, 0x1F, 0xC0, 0x3F, 0x00, 0x7F, 0x08, 0xFC, 0x22, 0x70, 0x0D, -0xD0, 0x27, 0x02, 0xBE, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0F, 0x02, 0x35, -0x40, 0xFC, 0x03, 0x70, 0x0F, 0xE8, 0x3D, 0x00, 0x7F, 0x00, 0xDC, 0x23, 0xF0, -0x03, 0xC8, 0x09, 0x02, 0xF7, 0x00, 0xDC, 0x23, 0xD0, 0x83, 0xD0, 0x0B, 0x60, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x7C, -0x23, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0x57, 0x00, 0x7C, 0x03, 0x30, 0xDC, 0xC0, -0x65, 0x20, 0x9B, 0x20, 0x6C, 0x04, 0xB0, 0x9D, 0xC0, 0x04, 0x00, 0x1F, 0x80, -0x7C, 0x07, 0xBC, 0x01, 0xC0, 0x07, 0x00, 0x5F, 0x01, 0x6E, 0x07, 0x39, 0x01, -0xC0, 0x07, 0x80, 0x5F, 0x00, 0x4C, 0x01, 0x33, 0x09, 0xC0, 0x40, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xAB, 0x00, 0xB4, 0x13, -0xD0, 0x2C, 0x40, 0x38, 0x11, 0x61, 0x00, 0x8C, 0x02, 0x18, 0x4E, 0x41, 0x28, -0x30, 0x31, 0x00, 0x84, 0x03, 0x11, 0xCC, 0x40, 0x08, 0x88, 0x2D, 0x00, 0xB4, -0x03, 0x10, 0x0A, 0x42, 0x3B, 0x80, 0x6D, 0x00, 0x94, 0x03, 0x14, 0x02, 0x40, -0x0B, 0x00, 0x7D, 0xC0, 0xC4, 0x01, 0xB0, 0x0A, 0x40, 0x4D, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0xA1, 0x03, 0x94, 0x07, 0x52, -0x5E, 0x60, 0x70, 0x03, 0x65, 0x43, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x6D, 0x00, -0xA5, 0x01, 0x84, 0x04, 0x10, 0x1E, 0x40, 0xC9, 0x00, 0x25, 0x01, 0xB4, 0x07, -0x10, 0x16, 0x44, 0x4B, 0x10, 0xFD, 0x01, 0x94, 0x87, 0x10, 0x16, 0x44, 0x5B, -0x20, 0xED, 0x01, 0xA4, 0x05, 0x10, 0x1C, 0x64, 0x10, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x04, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x0C, -0x40, 0x30, 0x00, 0x41, 0x45, 0x30, 0x2E, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC5, -0x20, 0x04, 0x1F, 0x10, 0x0C, 0x50, 0xF1, 0x01, 0xCD, 0x48, 0x34, 0x0F, 0x12, -0x3C, 0x41, 0xF3, 0x00, 0xCD, 0x22, 0x14, 0x13, 0x10, 0x1C, 0x40, 0xF3, 0x0C, -0xCD, 0x07, 0x24, 0x4F, 0x10, 0x4C, 0x48, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x17, 0xA0, 0x9F, 0x00, 0x73, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, -0x14, 0x00, 0x77, 0x00, 0xB4, 0x01, 0xB5, 0x05, 0xC0, 0xDD, 0x01, 0x77, 0x08, -0xEC, 0x0D, 0xB0, 0x05, 0xE0, 0xDD, 0x00, 0x7F, 0x0B, 0xFC, 0x15, 0xB1, 0x37, -0xC1, 0xDB, 0x16, 0x7F, 0x02, 0xDD, 0x09, 0x30, 0x27, 0xC1, 0x5F, 0x14, 0x7F, -0x04, 0xE4, 0x1D, 0x10, 0x17, 0x45, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x24, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x80, 0x4C, 0x10, 0xF0, 0x21, 0xC0, 0x07, 0x04, 0x12, 0x00, 0x7D, -0x20, 0xF0, 0x01, 0x00, 0x86, 0x00, 0x1F, 0x00, 0x7C, 0x48, 0xF2, 0x01, 0xC0, -0x87, 0x00, 0x1F, 0x0A, 0x64, 0x20, 0xF0, 0x01, 0xC1, 0x87, 0x00, 0x1F, 0x40, -0x5D, 0x00, 0xF4, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, -0x93, 0x80, 0x7C, 0x0A, 0x30, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, -0xF0, 0x19, 0xC8, 0x26, 0x00, 0x93, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x93, 0x10, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x6C, -0x0A, 0x30, 0x58, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x26, 0x00, 0x8D, 0x00, 0xC4, 0x02, 0xD8, 0x1B, 0x40, 0x27, 0x00, 0x95, -0x01, 0x74, 0x02, 0x50, 0x09, 0x44, 0x27, 0x00, 0x87, 0x00, 0x44, 0x06, 0xD0, -0x29, 0x44, 0xE3, 0x1C, 0x91, 0x01, 0x74, 0x12, 0xD0, 0x09, 0x4A, 0x67, 0x00, -0x95, 0x22, 0x74, 0x82, 0xD0, 0x18, 0x40, 0x24, 0x08, 0x9C, 0x03, 0x04, 0x42, -0x14, 0x19, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, -0x24, 0x00, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x04, -0x54, 0x02, 0x10, 0x69, 0x44, 0x27, 0x80, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x89, -0x41, 0x27, 0x41, 0xD1, 0x0A, 0x74, 0x02, 0xD2, 0x0D, 0x48, 0x37, 0x02, 0x91, -0x82, 0x74, 0x02, 0x52, 0x89, 0x00, 0x24, 0x00, 0x8D, 0x00, 0x42, 0x03, 0x10, -0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0xA0, -0x00, 0x9D, 0x02, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85, 0x20, 0x74, -0x03, 0x50, 0x08, 0x48, 0x23, 0x00, 0x95, 0x08, 0x04, 0x83, 0xD2, 0x08, 0x40, -0x23, 0x00, 0x81, 0x00, 0x34, 0x22, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x85, 0x80, -0x34, 0x22, 0xD0, 0x09, 0x50, 0x30, 0x90, 0xCD, 0x68, 0x45, 0xA2, 0x10, 0x48, -0x50, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x02, 0x00, -0x1F, 0x00, 0x4D, 0x04, 0xD0, 0x11, 0xC0, 0x07, 0x05, 0x13, 0x80, 0x5C, 0x80, -0x30, 0x41, 0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0xF0, 0x41, 0xC1, 0x07, -0x00, 0x13, 0x80, 0x38, 0x08, 0xF0, 0x21, 0xC0, 0x17, 0x20, 0x13, 0x00, 0x3E, -0x08, 0x70, 0x01, 0xC0, 0x04, 0x08, 0x1F, 0x16, 0x4C, 0x08, 0x30, 0x05, 0xC0, -0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x7F, 0x00, 0xBF, -0x01, 0x7C, 0x0E, 0xD0, 0x29, 0xC0, 0x67, 0x10, 0xBF, 0x00, 0xBC, 0x02, 0xF0, -0x09, 0xC0, 0x2B, 0x00, 0xB7, 0x04, 0x9C, 0x02, 0xF2, 0x09, 0xC0, 0x3F, 0x20, -0xFF, 0x40, 0xFC, 0x12, 0xD0, 0x4B, 0xC0, 0x2F, 0x10, 0xAF, 0x80, 0xFE, 0x12, -0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBE, 0x44, 0xDC, 0x13, 0xF0, 0x8B, 0xC0, 0x77, -0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x27, 0x00, 0x9F, 0x42, -0x7C, 0x36, 0xF0, 0x1B, 0xC1, 0x27, 0x02, 0xBF, 0x00, 0xDC, 0x02, 0xF2, 0x4B, -0xC1, 0x2F, 0x00, 0xDB, 0x80, 0xCC, 0x02, 0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBF, -0x00, 0xC4, 0x22, 0xF0, 0x09, 0x40, 0x28, 0x00, 0xBE, 0x00, 0x4C, 0x82, 0x30, -0x0B, 0xC0, 0x2B, 0x08, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x74, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x47, 0x05, 0x1D, 0xC1, 0x34, -0x0C, 0xD0, 0x21, 0x40, 0x43, 0x20, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, -0x07, 0x00, 0x1D, 0x70, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x07, 0x00, 0x1D, 0x00, -0x44, 0x11, 0x72, 0x01, 0x41, 0x04, 0x30, 0x1D, 0x20, 0x54, 0x50, 0x10, 0x01, -0x40, 0x17, 0x00, 0x1D, 0x00, 0x0C, 0x00, 0x10, 0x01, 0x44, 0x61, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x32, -0xD0, 0x08, 0x40, 0x23, 0x03, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x40, 0x23, -0x00, 0x89, 0x04, 0x05, 0x02, 0xD0, 0x08, 0x08, 0x33, 0x00, 0x9D, 0x00, 0x05, -0x12, 0xD8, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x92, 0x10, 0x08, 0x60, -0x23, 0x00, 0x8D, 0x00, 0x04, 0x82, 0x10, 0x09, 0x40, 0x4A, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x27, 0x08, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x20, -0x8D, 0x18, 0x44, 0x02, 0xD0, 0x09, 0x44, 0x66, 0x10, 0x9D, 0x00, 0x44, 0x02, -0x50, 0x28, 0x54, 0xB4, 0x02, 0x9D, 0x10, 0x55, 0x02, 0x10, 0x09, 0x41, 0x27, -0x00, 0xDD, 0x00, 0x04, 0x02, 0x90, 0x19, 0x60, 0x63, 0x28, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0xA8, 0xEF, 0x00, 0xBF, 0x0D, 0xFC, 0x82, 0xF2, 0x09, -0xC0, 0x2F, 0x00, 0x9F, 0x13, 0x4C, 0x02, 0xF0, 0x09, 0xC4, 0xE7, 0x24, 0x9B, -0x81, 0x44, 0x46, 0xF2, 0x09, 0xC8, 0x67, 0x20, 0x9F, 0x00, 0x4C, 0x02, 0xF0, -0x09, 0xC0, 0xE4, 0x00, 0x9F, 0x20, 0x54, 0x1A, 0x30, 0x29, 0xC0, 0x27, 0x00, -0x9F, 0x12, 0x4C, 0x0E, 0x34, 0x59, 0xC0, 0x16, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x80, 0xE5, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, -0x7C, 0x62, 0xE0, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x72, 0x49, -0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C, 0x22, 0xD4, 0x99, 0xC0, 0x27, 0x01, 0x9D, -0x13, 0x7F, 0xD2, 0x70, 0x09, 0xC1, 0x59, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x85, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xB0, 0x01, 0xD0, 0x06, -0x00, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x80, 0x1F, 0x02, 0x5C, -0x88, 0x30, 0x01, 0xC5, 0x85, 0x40, 0x13, 0x30, 0x4C, 0x00, 0xF0, 0x21, 0xC0, -0x07, 0x01, 0x13, 0x23, 0x5C, 0x08, 0xF0, 0x01, 0xC1, 0x05, 0x14, 0x03, 0x00, -0x4C, 0x00, 0x21, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x58, 0x77, 0x40, 0x14, 0x00, -0x65, 0x02, 0xD8, 0x01, 0xD0, 0x17, 0x40, 0x17, 0x80, 0x5C, 0x00, 0xD4, 0x01, -0x11, 0x07, 0x01, 0x9D, 0x00, 0x61, 0x02, 0xC4, 0x85, 0x32, 0x05, 0xC0, 0x9D, -0x40, 0x61, 0x10, 0x48, 0x01, 0xD1, 0x07, 0x40, 0x5F, 0x04, 0x71, 0x00, 0xD4, -0x81, 0x50, 0x07, 0x48, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x78, 0x40, 0x30, 0x00, 0x41, -0x04, 0x24, 0x02, 0xD0, 0xDC, 0x40, 0x33, 0x20, 0xCD, 0x40, 0x14, 0x03, 0x10, -0x0C, 0x0A, 0xB0, 0x0C, 0xC1, 0x08, 0x05, 0x07, 0xD0, 0x0C, 0x40, 0x71, 0x00, -0xC1, 0x80, 0x50, 0x83, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x03, 0x04, 0x2B, -0x1C, 0x2D, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, -0x38, 0x01, 0xED, 0x04, 0xB4, 0x27, 0x58, 0x1A, 0x40, 0x78, 0x01, 0xF5, 0x00, -0x94, 0x02, 0xD8, 0x0A, 0x40, 0x3B, 0x00, 0xED, 0x0C, 0x94, 0x0C, 0x10, 0x1A, -0x4A, 0x7D, 0x00, 0xE1, 0x20, 0x84, 0x43, 0x00, 0x4E, 0x40, 0x4D, 0x24, 0xF1, -0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x7F, 0x08, 0xE1, 0x82, 0x84, 0x01, 0x10, -0x06, 0x44, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0xF8, -0x00, 0xEF, 0x03, 0xBC, 0x07, 0x30, 0x1A, 0xC2, 0x78, 0x01, 0x63, 0x01, 0xAC, -0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0xFD, 0x31, 0x96, 0x04, 0x30, 0x1A, 0x40, -0x79, 0x00, 0x63, 0x01, 0x8C, 0x07, 0xF0, 0x1E, 0xC1, 0x49, 0x20, 0xE3, 0x01, -0x9E, 0x17, 0xF2, 0x1E, 0xC8, 0x79, 0x40, 0xF3, 0x01, 0x8D, 0x06, 0x30, 0x1E, -0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x10, 0xCF, 0x00, 0x7C, 0x02, -0xF1, 0x01, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x2C, 0x00, 0xF0, 0x08, 0xE0, 0x33, -0x00, 0x4F, 0x00, 0x7C, 0x01, 0xA2, 0x4D, 0xC0, 0x05, 0x20, 0xCF, 0x20, 0x5C, -0x1B, 0xF2, 0x09, 0xE0, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0, -0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x79, 0x00, 0xE3, -0x01, 0xCC, 0x13, 0xF8, 0x8F, 0xC0, 0x7D, 0x04, 0x7F, 0x09, 0xCC, 0x06, 0xF0, -0x9F, 0xC0, 0x7F, 0x02, 0xF7, 0x01, 0x3C, 0x24, 0x70, 0x9B, 0xC0, 0x47, 0x22, -0xBF, 0x0D, 0xCC, 0x06, 0xB0, 0x9D, 0x41, 0x4F, 0x02, 0xBF, 0x01, 0xCD, 0x4F, -0x30, 0x9E, 0xC8, 0x7C, 0x12, 0x3B, 0x09, 0xCC, 0x07, 0x34, 0x97, 0xD8, 0x18, -0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x38, 0x00, 0xE1, 0x18, -0x84, 0x03, 0xD8, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x0C, 0xAC, 0x02, 0xD0, 0x0A, -0x44, 0x33, 0x00, 0xCD, 0x08, 0xB4, 0x24, 0x10, 0xCA, 0x08, 0x7B, 0x01, 0x4D, -0x98, 0x44, 0x43, 0x10, 0x5E, 0x40, 0x03, 0x03, 0xAD, 0x04, 0x94, 0x23, 0x10, -0x0E, 0x42, 0x29, 0x03, 0x2D, 0x0C, 0xFC, 0x11, 0x10, 0x86, 0x40, 0x54, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7D, 0x00, 0xF1, 0x01, 0x84, -0x27, 0xD0, 0xC8, 0x40, 0x79, 0x02, 0x7D, 0x00, 0xA6, 0x02, 0x50, 0x0A, 0x48, -0x3B, 0x80, 0xED, 0x00, 0xF4, 0x00, 0xD0, 0x02, 0x0A, 0x09, 0x08, 0x3D, 0x06, -0xA6, 0x22, 0x10, 0x0E, 0x44, 0x0B, 0x14, 0xBD, 0x00, 0xC6, 0x03, 0x10, 0x0E, -0x40, 0x19, 0x10, 0x2D, 0x40, 0xC4, 0x02, 0x12, 0x06, 0x42, 0x60, 0x02, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x31, 0x00, 0xC1, 0x00, 0x04, 0x03, -0xD8, 0x08, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x22, 0xD0, 0x00, 0x40, 0x33, -0x00, 0xCD, 0x20, 0x34, 0x4C, 0x90, 0x00, 0x40, 0xB2, 0x01, 0x4D, 0x01, 0x24, -0x85, 0x9A, 0x2D, 0x48, 0xC3, 0x00, 0x8D, 0x10, 0x14, 0x9B, 0x10, 0x28, 0x41, -0x81, 0x00, 0x8D, 0x08, 0x05, 0x08, 0x10, 0xB8, 0x40, 0x08, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x41, 0xD3, 0x01, 0x4D, 0x03, 0xD0, -0x09, 0xC0, 0x35, 0x00, 0x5F, 0x00, 0x2C, 0x03, 0x70, 0x05, 0xC0, 0x77, 0x04, -0xFF, 0x11, 0x7C, 0x1C, 0xF0, 0x01, 0xC0, 0x35, 0x08, 0xDF, 0x02, 0x6D, 0x09, -0x34, 0x0F, 0xC0, 0xC7, 0x20, 0xCD, 0x81, 0xC4, 0x03, 0x30, 0x2D, 0xC0, 0x21, -0x00, 0xDB, 0x2B, 0x44, 0x0B, 0x30, 0xB9, 0xC0, 0x74, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0xF0, 0x29, -0xC0, 0x37, 0x00, 0x5F, 0x42, 0x7C, 0x4A, 0xF0, 0x05, 0xC0, 0x27, 0x91, 0xDF, -0x24, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x37, 0x0A, 0xDF, 0x02, 0x5C, 0x42, 0x70, -0xCD, 0xC0, 0x07, 0x04, 0x9F, 0x01, 0x6C, 0x03, 0xF0, 0x25, 0x40, 0x07, 0x01, -0xDF, 0x02, 0x7C, 0x09, 0xF0, 0x29, 0xC8, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xC8, 0x03, 0x30, 0x1B, 0xC0, -0x3F, 0x20, 0x7F, 0x41, 0xFC, 0x27, 0x30, 0x46, 0xC0, 0x7E, 0x01, 0xFF, 0x20, -0xCC, 0x0C, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x08, 0xF8, 0x05, 0xB4, 0x0F, -0xC0, 0x0D, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0xE7, -0x01, 0xCC, 0x46, 0xF0, 0x09, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x85, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x50, 0x19, 0x40, 0x37, -0x00, 0x1D, 0x02, 0x74, 0x0D, 0x10, 0x15, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x44, -0x0C, 0xD1, 0x19, 0xC0, 0x07, 0x01, 0x9D, 0x02, 0x74, 0x08, 0x90, 0x0D, 0x40, -0xC4, 0x00, 0x9D, 0x03, 0x6C, 0x03, 0xD2, 0xF5, 0x40, 0x47, 0x00, 0x11, 0x01, -0x44, 0x02, 0xD0, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0xA0, 0x34, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x90, 0x8D, 0x41, 0x37, 0x00, -0x5D, 0x08, 0x74, 0x43, 0x50, 0x0D, 0x40, 0x36, 0x00, 0xC9, 0x00, 0x44, 0xC0, -0xD8, 0x11, 0x00, 0x07, 0x02, 0x9D, 0x02, 0x36, 0x18, 0x12, 0x0D, 0x40, 0x46, -0x00, 0x9D, 0x03, 0x60, 0x03, 0xD0, 0x0D, 0x40, 0xE7, 0x00, 0x11, 0x04, 0x44, -0x9B, 0xD0, 0x11, 0x4D, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x28, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x04, 0x40, 0x32, 0x00, 0xCD, -0x00, 0x34, 0x02, 0x56, 0x0C, 0x42, 0x20, 0x80, 0xCD, 0x00, 0x05, 0x10, 0xD0, -0x18, 0x40, 0x31, 0x09, 0x4D, 0x20, 0x34, 0x22, 0x11, 0x6C, 0x50, 0x02, 0x02, -0x8D, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x42, 0x03, 0x80, 0x01, 0x00, 0x04, 0x00, -0xD0, 0x08, 0x4A, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, -0x3E, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0x5F, 0x00, -0x74, 0x03, 0x70, 0x09, 0xC0, 0x36, 0x10, 0xFB, 0x00, 0x4C, 0x50, 0x71, 0x01, -0x64, 0x07, 0x00, 0x9F, 0x08, 0x7C, 0x00, 0xB0, 0x6F, 0xC0, 0x07, 0xA0, 0x9F, -0x80, 0xDC, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x40, 0x47, 0x80, 0x4E, 0x01, 0xF2, -0x01, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA0, 0x3F, -0x00, 0xFF, 0x00, 0xFC, 0x03, 0x70, 0x07, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC, -0x01, 0xB0, 0x03, 0xC0, 0x2F, 0x04, 0xFC, 0x10, 0xFC, 0x40, 0xF0, 0x03, 0xC0, -0x8F, 0x08, 0x2F, 0x00, 0xFC, 0x10, 0xD2, 0x8F, 0xC0, 0x0D, 0x01, 0x2E, 0x00, -0xBC, 0x03, 0xE0, 0x0F, 0xC2, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x0B, -0xC2, 0x17, 0x64, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x00, -0xA3, 0x40, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x11, 0xB3, 0x20, 0xFC, 0x26, -0xB0, 0x9F, 0xD2, 0x2C, 0x00, 0xFF, 0x21, 0xEC, 0x10, 0xB2, 0x8F, 0xC8, 0x3C, -0x12, 0xFF, 0x04, 0xEC, 0x20, 0x72, 0x0F, 0xC0, 0x7F, 0x02, 0xF3, 0x03, 0xED, -0x1B, 0xB0, 0x9B, 0xC0, 0x7C, 0x0A, 0xDF, 0x01, 0xFC, 0x1A, 0x34, 0x49, 0xC0, -0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3F, 0x00, 0xB1, -0x01, 0x44, 0x82, 0x70, 0x01, 0x02, 0x3F, 0x22, 0x91, 0x00, 0x34, 0x13, 0x10, -0x4C, 0x48, 0xB4, 0x01, 0xD1, 0x01, 0x54, 0x24, 0xD0, 0x6F, 0x60, 0xBC, 0x01, -0xFD, 0x09, 0x44, 0x18, 0x10, 0x9F, 0x40, 0x33, 0x01, 0xD1, 0x00, 0x84, 0x1B, -0x14, 0x48, 0x50, 0x34, 0x21, 0xDD, 0x04, 0x74, 0x12, 0x11, 0x19, 0x40, 0x0D, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x31, 0x00, 0x81, 0x00, -0x04, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x20, 0xC5, 0x20, 0x14, 0x07, 0x50, 0x0C, -0x40, 0x81, 0x04, 0xC5, 0x00, 0x04, 0x00, 0xD0, 0x6C, 0x48, 0xB0, 0x01, 0xCD, -0x00, 0x24, 0x1C, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x04, 0x0B, 0x50, -0x0D, 0x40, 0x30, 0x01, 0xCD, 0x14, 0x34, 0x18, 0x10, 0x81, 0x40, 0x5C, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x37, 0x00, 0x91, 0x41, 0x44, -0x0E, 0x52, 0x11, 0x45, 0x37, 0x10, 0xD5, 0x43, 0x74, 0x07, 0x50, 0x0D, 0x44, -0x55, 0x00, 0xD5, 0x04, 0x56, 0x88, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xDD, 0x00, -0x24, 0x02, 0x13, 0x0D, 0x40, 0x37, 0x80, 0xC1, 0x01, 0x44, 0x03, 0x50, 0x0D, -0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x06, 0x10, 0x11, 0x40, 0x1D, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x4D, 0x04, -0xF0, 0x11, 0xC4, 0x37, 0xC0, 0xD7, 0x03, 0x7C, 0x07, 0xF0, 0x8D, 0xC0, 0xC5, -0x00, 0xDF, 0x01, 0x4C, 0x0C, 0xB2, 0x0D, 0x40, 0x34, 0x00, 0xDF, 0x00, 0x6C, -0x01, 0x70, 0x0D, 0xC0, 0x77, 0x0A, 0xD3, 0x80, 0x6C, 0x03, 0xF0, 0x08, 0xC4, -0x34, 0x00, 0xDF, 0x00, 0x7C, 0x0E, 0x30, 0x39, 0xC0, 0x82, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D, 0x10, 0xEF, 0x00, 0xFC, 0x80, 0x70, -0x03, 0xC0, 0x3F, 0x00, 0xFB, 0x80, 0xF8, 0x03, 0xB4, 0x0F, 0xC0, 0x1A, 0x00, -0xFB, 0x00, 0x5C, 0x22, 0xF0, 0x0F, 0xC2, 0x37, 0x30, 0xEF, 0x00, 0x5C, 0x0D, -0xF3, 0x0F, 0xC0, 0x7F, 0x40, 0xFF, 0x80, 0xDC, 0x03, 0xB0, 0x0B, 0xC0, 0x3F, -0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x0F, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x0A, 0x93, 0x00, 0x4C, 0x0A, 0xF2, 0x69, -0xC0, 0x33, 0x20, 0xDF, 0x02, 0x5D, 0x83, 0xF0, 0xCD, 0xC0, 0x84, 0x00, 0xD3, -0x01, 0x7C, 0x09, 0x70, 0x0D, 0xC0, 0x34, 0x40, 0xD3, 0x84, 0x7C, 0x81, 0x30, -0x8D, 0xC0, 0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x34, 0x00, -0xDB, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0xA0, 0xF8, 0x02, 0x51, 0x20, 0x44, 0x02, 0xD0, 0x09, 0x45, -0x3F, 0x00, 0xDD, 0x01, 0x7C, 0x83, 0x10, 0x3D, 0x40, 0x14, 0x08, 0xC0, 0x20, -0x74, 0x03, 0x12, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x00, 0x74, 0x83, 0x10, 0x1F, -0x40, 0x34, 0x00, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40, 0x34, 0x80, 0xD1, -0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x20, 0x30, 0x00, 0x81, 0x12, 0x04, 0x4C, 0xD9, 0x38, 0x40, 0x33, -0x00, 0xCD, 0x09, 0x54, 0x03, 0x10, 0x2D, 0x40, 0x20, 0x08, 0xC1, 0x00, 0x34, -0x07, 0x11, 0xAC, 0x48, 0xB1, 0x00, 0xC1, 0x01, 0x34, 0x82, 0x10, 0x1C, 0x41, -0x36, 0x00, 0xC9, 0x20, 0x74, 0x03, 0x50, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x00, -0x74, 0x00, 0xD0, 0x01, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x70, 0x00, 0xA1, 0x89, 0x84, 0x07, 0xD8, 0x1E, 0x40, 0x7B, 0x02, -0xFD, 0x09, 0xB4, 0x07, 0x12, 0x1E, 0x40, 0x68, 0x00, 0xE1, 0x81, 0xB4, 0x07, -0x10, 0x1E, 0x40, 0x79, 0x05, 0xE1, 0x11, 0xB4, 0x27, 0x10, 0x1C, 0x40, 0xFA, -0x00, 0xE9, 0x81, 0xB4, 0x07, 0x10, 0x1A, 0x40, 0x78, 0x00, 0xE8, 0x0B, 0xB4, -0x84, 0xD0, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x18, 0x30, 0x00, 0x83, 0x20, 0x0C, 0x41, 0xF0, 0x8C, 0xC4, 0x33, 0x20, 0x4F, -0x00, 0x1D, 0x23, 0x70, 0x8C, 0xC0, 0x84, 0x40, 0xC3, 0x00, 0x3C, 0x43, 0x74, -0x0D, 0xC0, 0x31, 0x00, 0xC3, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xD0, 0x33, 0x00, -0xCA, 0x08, 0x3C, 0x03, 0x74, 0x0C, 0xD0, 0x34, 0x00, 0xC3, 0x1D, 0x3C, 0x08, -0xF0, 0x70, 0xC8, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, -0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x6F, 0x00, -0xFC, 0xA3, 0x70, 0x0F, 0xE0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, -0xC1, 0x3E, 0x0D, 0xFF, 0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC0, 0x3D, 0x00, 0xF7, -0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xF5, 0x28, 0xFC, 0x00, 0xF0, -0x83, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, -0x01, 0xB3, 0x02, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0xB7, 0x00, 0xD3, 0x80, 0x6C, -0x03, 0xF2, 0x0D, 0xC2, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0x30, 0x2D, 0xC0, -0xB4, 0x04, 0xD3, 0x04, 0x7C, 0x86, 0x30, 0x6D, 0xC0, 0x77, 0x00, 0xD3, 0x40, -0x7C, 0x53, 0xB0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x44, 0x82, 0xF0, 0x11, -0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x05, -0xE1, 0x10, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x3F, 0x04, 0xE5, 0x00, 0x84, 0x03, -0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0xA0, 0x9C, 0x02, 0x10, 0x4F, 0x42, 0x3C, -0x21, 0xE1, 0x0A, 0x9C, 0x03, 0x18, 0x8E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, -0x0B, 0x10, 0x0A, 0x48, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, -0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x42, 0x81, -0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x49, 0x01, 0xA4, 0x47, 0x50, -0x1E, 0x40, 0x5B, 0x00, 0xED, 0x01, 0x14, 0x05, 0x14, 0x1E, 0x50, 0x7A, 0x40, -0xE1, 0x21, 0x34, 0x04, 0xD0, 0x9E, 0x60, 0x7B, 0x40, 0xE1, 0x01, 0x34, 0x17, -0x90, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84, 0x04, 0xD0, 0x10, 0x40, 0x02, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0x41, 0x0A, -0x04, 0xC3, 0xC1, 0xBC, 0x44, 0x33, 0x00, 0x5D, 0x01, 0x04, 0x05, 0xD0, 0x08, -0x40, 0x73, 0x0A, 0x8D, 0x20, 0x14, 0x0F, 0x10, 0x0C, 0x40, 0x32, 0x80, 0xC1, -0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x40, 0x34, 0x03, 0x12, -0x89, 0x42, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x83, 0xD8, 0x1C, 0x40, 0x5A, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x73, 0x03, 0xCC, -0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x00, 0x7B, 0x00, 0xEC, 0x05, 0xF0, 0x15, 0xC2, -0x1F, 0x00, 0x5F, 0x05, 0xDC, 0x61, 0x30, 0x05, 0xC0, 0x16, 0x60, 0x53, 0x80, -0xF4, 0x01, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xB0, 0x05, -0xC0, 0x17, 0x10, 0x5F, 0x00, 0xCC, 0x39, 0xF0, 0x37, 0xC0, 0x5E, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x00, 0x0F, 0x04, 0x7C, 0x28, -0xF1, 0x01, 0xC3, 0x07, 0x10, 0x17, 0x08, 0x7C, 0x04, 0xF0, 0xA1, 0xC0, 0x07, -0x01, 0x1F, 0x00, 0x1C, 0x00, 0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x5C, -0x80, 0x34, 0x21, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x3C, 0x80, 0xF0, 0x01, 0xC0, -0x07, 0x80, 0x1E, 0x02, 0x7C, 0x00, 0xF0, 0x81, 0xC1, 0x49, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0x08, 0x6C, 0x06, 0xF0, -0x89, 0xC0, 0x63, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x31, 0x09, 0xD0, 0x24, 0x00, -0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xD0, 0x64, 0xC0, 0x93, 0x08, 0x7C, 0x02, -0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x24, -0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x40, 0x91, 0x00, 0x44, 0x6E, 0xD2, 0x29, -0x40, 0x27, 0x02, 0x91, 0x03, 0x04, 0x02, 0x10, 0x39, 0x41, 0x24, 0x08, 0x91, -0x20, 0x7C, 0x26, 0x11, 0x29, 0x40, 0x24, 0x02, 0x91, 0x02, 0x74, 0x02, 0xD0, -0x79, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0x40, 0x24, 0x00, -0x9D, 0x04, 0x74, 0x02, 0xD0, 0x09, 0x42, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x29, 0x40, -0x27, 0x00, 0x91, 0x10, 0x44, 0x02, 0x10, 0x88, 0x48, 0x20, 0x00, 0x99, 0x04, -0x74, 0x02, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0x50, 0x49, -0x40, 0x67, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x64, 0x00, 0x95, -0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x04, 0x1A, 0x90, 0x08, 0x40, 0x23, -0xC1, 0x81, 0x04, 0x45, 0x02, 0x18, 0x08, 0x40, 0x20, 0x01, 0x89, 0x00, 0x34, -0x12, 0x10, 0x4C, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x40, -0x23, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x90, 0x08, 0x54, 0x20, 0x00, 0x8D, 0x00, -0x34, 0x12, 0xD0, 0x48, 0x60, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB8, 0x96, 0x02, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x81, 0x44, 0x87, 0x02, -0x13, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0xC0, 0x84, 0x02, 0x1B, 0x00, 0x7C, 0x00, -0x30, 0xA1, 0x42, 0x84, 0x02, 0x11, 0x00, 0x7C, 0xA8, 0xF0, 0x01, 0xC0, 0x83, -0x12, 0x1F, 0x0A, 0x7C, 0x58, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x17, 0x0A, 0x7C, -0x28, 0xF0, 0x01, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB0, 0x27, 0x02, 0xBF, 0x08, 0xF4, 0x0A, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0xFF, -0x08, 0xFC, 0x02, 0xF4, 0x0B, 0xC2, 0x2F, 0x02, 0xB7, 0x00, 0xDC, 0x22, 0xF0, -0x89, 0xC8, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x08, -0xBF, 0x00, 0x5C, 0x92, 0x70, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22, -0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, -0x2F, 0x05, 0xB3, 0x84, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04, -0x5C, 0x02, 0x30, 0x8B, 0xE0, 0x25, 0x00, 0xB7, 0x00, 0xDC, 0x02, 0xF0, 0x4B, -0xC0, 0x2F, 0x05, 0xBF, 0x04, 0x4C, 0x03, 0xF4, 0x0B, 0xC0, 0x2F, 0x02, 0xDF, -0x00, 0x4C, 0x52, 0xB0, 0x89, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xE2, -0x09, 0x00, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, -0x01, 0x11, 0x88, 0x74, 0x49, 0xD0, 0x05, 0x41, 0x07, 0x02, 0x15, 0x14, 0x44, -0x90, 0x11, 0x41, 0x42, 0x87, 0x44, 0x11, 0x00, 0x74, 0x20, 0x72, 0x41, 0xC1, -0x05, 0x01, 0x1C, 0x08, 0x54, 0x49, 0x10, 0x01, 0x44, 0x07, 0x00, 0x1D, 0x14, -0x54, 0x10, 0x70, 0x41, 0x40, 0x07, 0x24, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, -0x42, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x20, 0x05, -0x81, 0x00, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x23, 0x20, 0x81, 0x2C, 0x44, 0x56, -0x04, 0x48, 0x40, 0x25, 0x43, 0x85, 0x40, 0x14, 0x02, 0xD0, 0xC8, 0x40, 0x23, -0x25, 0xCD, 0x00, 0x24, 0x32, 0x10, 0x88, 0x40, 0x33, 0x00, 0x9D, 0x04, 0x04, -0x52, 0x90, 0x48, 0x44, 0x23, 0x01, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, -0x4B, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, -0x01, 0x74, 0x83, 0xD0, 0x89, 0x40, 0x23, 0x00, 0x95, 0x00, 0x44, 0x02, 0x10, -0x19, 0x40, 0xA7, 0xC0, 0x91, 0x01, 0x74, 0x06, 0x50, 0x09, 0x00, 0x27, 0x08, -0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x50, 0x02, -0x58, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x74, 0x12, 0xD0, 0x09, 0x43, 0x63, -0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x40, 0x93, 0x05, -0x7C, 0x0E, 0xF0, 0x39, 0xC0, 0x27, 0x00, 0x93, 0x03, 0x1D, 0x02, 0x10, 0x09, -0xC8, 0x25, 0x40, 0x97, 0x20, 0x5C, 0x02, 0xF3, 0x09, 0xC0, 0x27, 0x10, 0x9F, -0x00, 0x6C, 0x02, 0x70, 0x09, 0xC0, 0x67, 0x20, 0x8F, 0x01, 0x49, 0x02, 0xB0, -0x19, 0xC8, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x29, 0xC0, 0x17, 0x08, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x21, 0x10, 0x9F, 0x20, 0x7C, -0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x26, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x25, 0x04, 0x9F, 0x00, -0x5C, 0x02, 0x70, 0x09, 0xC1, 0x27, 0x01, 0x9F, 0x84, 0x6C, 0x02, 0xB0, 0x59, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x04, 0x7E, 0x68, -0xB4, 0x21, 0xD0, 0x04, 0x08, 0x1D, 0x02, 0x6C, 0x00, 0xF0, 0x01, 0xC8, 0x07, -0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x5C, -0x08, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x0C, 0x7C, 0x08, 0x30, 0x21, 0xC2, 0x53, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x40, 0x71, 0x01, 0xE4, 0x0D, 0x30, -0x07, 0x41, 0x14, 0x00, 0x7D, 0x0D, 0x44, 0x01, 0x70, 0x07, 0xC0, 0x11, 0x00, -0x5D, 0x00, 0x76, 0x05, 0x90, 0x07, 0x40, 0x9F, 0x08, 0x61, 0x02, 0x44, 0x01, -0x70, 0x17, 0xC8, 0x9E, 0x02, 0x5D, 0x00, 0x74, 0x01, 0x52, 0x05, 0x40, 0x17, -0x01, 0x7D, 0x03, 0x74, 0x01, 0x10, 0x05, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x00, 0x81, 0x09, 0x24, 0x0B, 0x50, 0x2C, -0x42, 0x30, 0x00, 0xDD, 0x03, 0x24, 0x03, 0xD0, 0x9C, 0x40, 0x33, 0x00, 0x8D, -0x01, 0x34, 0x22, 0xD0, 0x1C, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x54, 0x83, 0x50, -0xB4, 0x40, 0x30, 0x00, 0xCD, 0x40, 0x74, 0x03, 0x10, 0x0C, 0x40, 0x72, 0x00, -0xCD, 0x81, 0x36, 0x83, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x80, 0x20, 0x05, 0xA1, 0x00, 0xA4, 0x07, 0x50, 0x1E, 0x60, -0x38, 0x00, 0xAD, 0x04, 0x84, 0x13, 0xD0, 0x0E, 0x48, 0x3B, 0x00, 0xED, 0x80, -0xB4, 0x03, 0x90, 0x0E, 0x44, 0x6B, 0x10, 0x21, 0x40, 0x84, 0x23, 0x40, 0x1E, -0x40, 0x3A, 0x00, 0xED, 0x08, 0xB4, 0x13, 0x50, 0x4E, 0x40, 0x3B, 0x10, 0xAC, -0x00, 0x34, 0x27, 0x10, 0x0E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x18, 0xE8, 0x00, 0xA1, 0x01, 0xF4, 0x07, 0x70, 0x17, 0xC0, 0x78, -0x00, 0xEF, 0x03, 0xAC, 0x27, 0xF0, 0x1E, 0xC0, 0x7B, 0x22, 0xED, 0x01, 0xB6, -0x07, 0xF0, 0x16, 0x82, 0x73, 0x00, 0x03, 0x01, 0x9C, 0x17, 0x60, 0x1E, 0xC0, -0x78, 0x08, 0xEF, 0x89, 0x3C, 0x17, 0x38, 0xDE, 0xC8, 0x7B, 0x00, 0xAF, 0x01, -0xBC, 0x27, 0x30, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xB8, 0x05, 0x00, 0x9F, 0x00, 0x74, 0x03, 0x30, 0x05, 0xC0, 0x37, 0x08, -0x8F, 0x00, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x35, 0x03, 0xDF, 0x00, 0x7C, 0x83, -0xB1, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x9B, 0x51, 0x0C, 0xC0, 0x37, -0x00, 0xDF, 0x02, 0x7C, 0x4B, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, -0x03, 0xF2, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x20, 0x6D, 0x00, 0xF3, 0x01, 0xCC, 0x11, 0xB0, 0x1F, 0xC0, 0xFF, 0x00, 0xFF, -0x01, 0xCC, 0x47, 0xF0, 0x1B, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x07, 0x30, -0x9F, 0xE0, 0x5C, 0x00, 0x3F, 0x01, 0xF8, 0x2F, 0x38, 0x1F, 0xC8, 0x6E, 0x28, -0xF3, 0x81, 0xFC, 0x47, 0xFA, 0x9F, 0xC8, 0x6F, 0x00, 0x33, 0x21, 0x7C, 0x27, -0x30, 0x9F, 0xC4, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, -0x29, 0x20, 0xE1, 0x08, 0x84, 0x21, 0x31, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, -0x84, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x14, 0xED, 0x80, 0x9C, 0x23, 0x70, 0x8A, -0xC0, 0x28, 0x01, 0x2D, 0x20, 0x9C, 0x03, 0x30, 0x4E, 0x40, 0x0C, 0x12, 0xE1, -0x18, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x2F, 0x30, 0x01, 0x00, 0xB4, 0x07, 0xB0, -0x0C, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, -0x00, 0xA1, 0x00, 0x84, 0x01, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0x6D, 0x00, 0x84, -0x0B, 0x50, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x06, 0x70, -0x18, 0x10, 0x2D, 0x00, 0x14, 0x43, 0x1D, 0x0E, 0x40, 0x28, 0x44, 0xE5, 0x00, -0xB4, 0x03, 0xD0, 0x0E, 0x44, 0x2B, 0x02, 0xA9, 0x00, 0xB4, 0x03, 0x10, 0x0E, -0x40, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, -0x81, 0x06, 0x05, 0x80, 0x10, 0x08, 0x40, 0x37, 0x00, 0x4D, 0x00, 0x04, 0x87, -0xD0, 0x00, 0x46, 0x73, 0x08, 0xCD, 0x00, 0x14, 0x93, 0x51, 0x08, 0x40, 0x20, -0x08, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x0C, 0x40, 0x40, 0x10, 0xD5, 0x80, 0x34, -0x03, 0x50, 0x0C, 0x60, 0x23, 0x00, 0x89, 0x20, 0x76, 0x13, 0x1C, 0xED, 0x48, -0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2D, 0x40, 0x93, -0x00, 0x44, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCD, 0x07, 0xF0, -0x05, 0xC0, 0xFF, 0x02, 0xDF, 0x00, 0x7C, 0x0B, 0x30, 0x09, 0xC4, 0x34, 0x00, -0x1F, 0x00, 0xDC, 0x07, 0x30, 0x0D, 0xD0, 0x54, 0x00, 0xF7, 0x01, 0xFC, 0x03, -0xF0, 0x0F, 0xC0, 0x37, 0x40, 0x1B, 0x00, 0xFC, 0x03, 0x10, 0x3D, 0xC4, 0x77, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x0F, 0x01, -0x7C, 0x68, 0x70, 0x29, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x1D, -0xC8, 0x37, 0x00, 0xDF, 0x01, 0x1C, 0x03, 0x72, 0x25, 0xC0, 0x95, 0x00, 0x1F, -0x82, 0x1C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70, -0x0D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x87, 0xF0, 0x0D, 0xC4, 0x17, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0x93, 0x00, 0x4C, -0x02, 0xF0, 0x02, 0xC1, 0x3C, 0x00, 0xF3, 0x02, 0xCC, 0x03, 0xF0, 0x07, 0xC0, -0x3C, 0x00, 0xFF, 0x03, 0xCC, 0x03, 0x30, 0x82, 0xC0, 0x6C, 0x40, 0x33, 0x00, -0xFC, 0x43, 0x30, 0x0D, 0xC0, 0x4F, 0x00, 0xF3, 0x00, 0x8D, 0x03, 0x30, 0x0F, -0xC0, 0x6F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xD0, 0x04, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x02, 0x11, 0x02, 0x54, 0x06, -0x90, 0x71, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x03, 0xD0, 0x20, 0x40, 0x34, -0x00, 0xCD, 0x00, 0x6C, 0x03, 0x10, 0x25, 0x41, 0x84, 0x06, 0x11, 0x01, 0x74, -0x03, 0x10, 0x1D, 0xC0, 0x41, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x50, 0x0D, 0x40, -0x67, 0x00, 0x9D, 0x05, 0x74, 0x03, 0x10, 0x0D, 0xC2, 0x06, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x22, 0x00, 0xD1, 0x02, 0x44, 0x06, 0xD0, -0x11, 0x40, 0x64, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD8, 0x21, 0x40, 0x34, 0x00, -0xDD, 0x00, 0x44, 0x07, 0x10, 0x09, 0x40, 0x10, 0x80, 0x11, 0x03, 0x74, 0x03, -0x90, 0x1D, 0x41, 0x37, 0x01, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37, -0x01, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x0D, 0x44, 0x04, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x00, 0x98, 0x08, -0x40, 0x20, 0x00, 0x81, 0x80, 0x05, 0x03, 0xD0, 0x09, 0x40, 0x30, 0x00, 0xDD, -0x00, 0x24, 0x03, 0x14, 0x00, 0x50, 0x10, 0x00, 0x01, 0x00, 0x34, 0x03, 0x90, -0x0C, 0x40, 0x57, 0x00, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x33, 0x80, -0x0D, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x4C, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x98, 0x22, 0x40, 0x93, 0x00, 0x4C, 0x02, 0xF1, 0x01, 0x50, -0x3C, 0x00, 0x43, 0x00, 0xCC, 0x03, 0xF0, 0x05, 0xD0, 0x3C, 0x00, 0xDF, 0x00, -0x44, 0x03, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x13, 0x00, 0xFC, 0x03, 0xB0, 0x0D, -0xC0, 0x27, 0x40, 0xF3, 0x00, 0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x27, 0x00, 0x1F, -0x02, 0xBC, 0x13, 0x30, 0xAD, 0xC2, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xB0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF8, 0x0B, 0xC0, 0x3F, -0x00, 0x7F, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x3F, 0x00, 0xFF, 0x00, 0xFC, -0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x74, 0x0B, 0xE0, -0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC8, 0x2F, 0x30, 0xBF, 0x04, -0x7C, 0x0B, 0xF0, 0x4F, 0xC0, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA0, 0x7F, 0x00, 0x7E, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0x44, 0x3C, 0x05, -0xF7, 0x00, 0xEC, 0x23, 0xB0, 0x4F, 0xC0, 0x49, 0x00, 0x37, 0x03, 0xFC, 0x03, -0x32, 0x2F, 0x40, 0x3D, 0x02, 0x23, 0x03, 0xDC, 0x24, 0x78, 0x93, 0xC0, 0x48, -0x00, 0x23, 0x01, 0xE4, 0x03, 0xB0, 0x17, 0xC0, 0x4C, 0x00, 0xFF, 0x21, 0xCC, -0x06, 0xE0, 0x03, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x08, 0x7F, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0x10, 0x1F, 0x40, 0xF4, 0x00, 0xF1, -0x03, 0x84, 0x3B, 0x10, 0x9D, 0xC0, 0x64, 0x00, 0x1D, 0x00, 0xF4, 0x2F, 0x14, -0x6F, 0x44, 0xBC, 0x03, 0x11, 0x84, 0x4C, 0x00, 0xD0, 0x41, 0xC0, 0x54, 0x48, -0x51, 0x01, 0x44, 0x2F, 0x10, 0x11, 0x50, 0x44, 0x00, 0xFD, 0xA1, 0x44, 0x04, -0xD1, 0x09, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x33, 0x00, 0x0D, 0x40, 0x34, 0x03, 0x91, 0x0C, 0x40, 0x30, 0x00, 0xC5, 0x22, -0x24, 0x13, 0x91, 0x0C, 0x40, 0x01, 0x08, 0x0D, 0x84, 0x34, 0x03, 0x90, 0x2C, -0x40, 0x31, 0x21, 0x01, 0xC0, 0x14, 0x14, 0x50, 0x01, 0x40, 0x32, 0x20, 0x91, -0x00, 0x04, 0x03, 0x90, 0x0D, 0x40, 0x02, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0, -0x01, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, -0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x60, 0x44, -0x03, 0x10, 0x0D, 0x40, 0x64, 0x24, 0x1D, 0x01, 0x74, 0x03, 0x92, 0x0D, 0x40, -0x32, 0x88, 0x01, 0x01, 0x54, 0x04, 0xC0, 0x19, 0x50, 0x94, 0x01, 0x90, 0x08, -0x44, 0x03, 0xD0, 0x09, 0x40, 0x46, 0x04, 0xDD, 0x00, 0x44, 0x46, 0xD1, 0x31, -0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, -0x9F, 0x04, 0x3C, 0x03, 0x94, 0x0C, 0xD0, 0x34, 0x10, 0xD7, 0x00, 0x6C, 0x03, -0xB0, 0x0D, 0xC8, 0x45, 0x10, 0x9F, 0x03, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x35, -0x00, 0x13, 0x11, 0x5C, 0x04, 0x71, 0x30, 0xC0, 0x26, 0x00, 0x13, 0x83, 0x6C, -0x03, 0xB0, 0x48, 0xC0, 0xC6, 0x00, 0xCF, 0x00, 0x4D, 0x0E, 0xF0, 0x31, 0xD0, -0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x3D, 0x00, 0xBF, -0x00, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x3B, 0x00, 0xED, 0x40, 0xFC, 0x83, 0xF0, -0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x0E, 0xC4, 0x3D, 0x00, -0xBF, 0x00, 0xEC, 0x02, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0x3C, 0x03, -0x10, 0x4B, 0xC0, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x09, 0xC0, 0x1E, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x20, 0x9F, 0x00, -0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x83, 0x70, 0x0D, -0xC0, 0x07, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x34, 0x00, 0x9F, -0x02, 0x5C, 0x02, 0xF0, 0x29, 0xC2, 0xA7, 0x01, 0x93, 0x06, 0x7C, 0x47, 0x30, -0x49, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC4, 0x08, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x20, 0x9D, 0x80, 0x74, -0x03, 0xD0, 0x4D, 0x60, 0x3F, 0x00, 0xFD, 0x00, 0xC4, 0x83, 0x10, 0x0F, 0x44, -0xA7, 0x1A, 0x91, 0x00, 0xBC, 0x13, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00, -0x44, 0x02, 0xD0, 0x19, 0x40, 0x83, 0x01, 0xC1, 0x51, 0xC4, 0x0B, 0x50, 0x09, -0x40, 0x87, 0x00, 0xDC, 0x00, 0x74, 0x0A, 0xD0, 0x99, 0x40, 0x6D, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x13, -0xD0, 0x2C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x58, 0x0C, 0x41, 0x23, -0x00, 0x81, 0x00, 0x34, 0x13, 0x90, 0x0C, 0x44, 0x30, 0x00, 0x0D, 0x80, 0x14, -0x00, 0xD1, 0x00, 0x40, 0x82, 0x08, 0xC5, 0x63, 0x14, 0x03, 0x10, 0x3C, 0x40, -0xC3, 0x03, 0xCD, 0x00, 0x34, 0x16, 0xD0, 0x19, 0x40, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00, 0xED, 0x81, 0xB4, 0x27, 0xD0, -0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x89, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x6F, 0x01, -0x21, 0x01, 0xB4, 0x07, 0xC0, 0x1C, 0x48, 0x78, 0x00, 0xBD, 0x41, 0x84, 0x07, -0xD0, 0x1A, 0x41, 0x5F, 0x00, 0xE5, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x4B, -0x01, 0xED, 0x21, 0xB4, 0x04, 0xD0, 0x5A, 0x40, 0x3D, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x08, 0x3C, 0x03, 0xF0, 0x8C, -0x40, 0x33, 0x00, 0xCF, 0x00, 0x1C, 0x23, 0x70, 0x1C, 0xC0, 0x63, 0x21, 0x83, -0x02, 0x3E, 0x03, 0xB0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x1C, 0x02, 0xF0, -0x04, 0xC0, 0x33, 0x01, 0x87, 0x04, 0x1C, 0x23, 0x38, 0x0C, 0xC1, 0x03, 0x02, -0xCF, 0x00, 0x3C, 0xE3, 0xF0, 0x00, 0xC1, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x87, 0xF0, 0x9F, 0xC0, -0x3F, 0x00, 0xFF, 0x50, 0xFC, 0x03, 0xF2, 0x8F, 0xC0, 0x2F, 0x42, 0xBF, 0x08, -0xDC, 0x03, 0xF8, 0x0F, 0xC2, 0x3F, 0x94, 0xFF, 0x40, 0xFC, 0x23, 0xF0, 0x8D, -0x40, 0x3F, 0x40, 0xBB, 0x00, 0x5C, 0x63, 0xF0, 0x0F, 0xC8, 0x0F, 0x03, 0xFF, -0x01, 0xFC, 0x03, 0xF0, 0x43, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA0, 0x37, 0x80, 0x9E, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, -0x02, 0xDF, 0x11, 0x4C, 0x53, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x20, 0x4C, -0x03, 0xF0, 0x4D, 0xC0, 0xF7, 0x01, 0x5B, 0x00, 0x7C, 0x01, 0x72, 0x1D, 0xC0, -0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x08, 0xC0, 0x44, 0xC0, 0xDB, 0x01, -0x4C, 0x01, 0xD0, 0x1D, 0x40, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0x88, 0x39, 0x01, 0xAD, 0x00, 0x34, 0x8B, 0x10, 0x2E, 0x48, 0x3B, 0x31, -0xED, 0x04, 0xAC, 0x03, 0xD0, 0x2E, 0x40, 0x0B, 0x28, 0x3D, 0x00, 0x84, 0x3B, -0xD0, 0xAE, 0xC0, 0x39, 0x0A, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x00, 0x38, -0x00, 0xED, 0x80, 0x84, 0x13, 0xD2, 0x0A, 0x40, 0x08, 0x00, 0xC5, 0x02, 0x94, -0x01, 0xD0, 0x0F, 0x40, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x79, 0x02, 0xA5, 0x43, 0xB4, 0x17, 0x10, 0x5E, 0x40, 0x7B, 0x00, 0xED, -0x01, 0x84, 0x27, 0x58, 0x5E, 0x44, 0x6B, 0x10, 0xAD, 0x11, 0x85, 0x07, 0xD0, -0x1E, 0x46, 0x73, 0x01, 0xE9, 0x91, 0xB4, 0x87, 0x42, 0x1E, 0x40, 0x7A, 0x00, -0xFD, 0x01, 0x94, 0x07, 0xD0, 0x0A, 0x41, 0xC8, 0x40, 0xED, 0x05, 0x84, 0x05, -0xD0, 0x1A, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, -0x33, 0x00, 0x8D, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, -0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0xCD, 0x03, 0x44, 0x03, 0xD0, 0x0C, -0x40, 0x31, 0x00, 0xC9, 0x01, 0x34, 0x17, 0xD0, 0x5C, 0x42, 0xF2, 0x00, 0xCD, -0x80, 0x04, 0x03, 0xD0, 0x38, 0x40, 0x70, 0x41, 0xCD, 0x40, 0x14, 0x63, 0xD0, -0x3C, 0x49, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, -0x00, 0x7F, 0x00, 0x3C, 0x01, 0xB0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C, -0x01, 0xF0, 0x04, 0xC0, 0x9F, 0x00, 0x7F, 0x01, 0x44, 0x01, 0xF0, 0x05, 0xC4, -0x17, 0x00, 0x7B, 0x02, 0xF4, 0x15, 0x70, 0x17, 0xD0, 0x9A, 0x10, 0x7F, 0x10, -0x5C, 0x01, 0xF0, 0x07, 0xC0, 0x1C, 0x00, 0x5F, 0x00, 0xCC, 0x05, 0xF0, 0x57, -0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, -0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x3C, 0x00, -0xF0, 0x01, 0xC4, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x88, 0xF0, 0x01, 0xC0, 0x05, -0x00, 0x17, 0x10, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x05, 0x02, 0x1F, 0x00, 0x75, -0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x80, 0x7C, 0x08, 0xF0, 0x01, 0xC0, -0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, -0x00, 0x4C, 0x12, 0x30, 0x29, 0xC2, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, -0x49, 0xC0, 0x24, 0x06, 0x9F, 0x10, 0x4C, 0x22, 0x30, 0x09, 0xE0, 0x27, 0x00, -0x97, 0x00, 0x7C, 0x02, 0x32, 0x59, 0xC0, 0x27, 0x26, 0x93, 0x80, 0x7D, 0x0A, -0xF0, 0x19, 0xC1, 0x67, 0x02, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x59, 0xC0, 0x43, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x2E, 0x00, 0x8D, 0x00, -0xC4, 0x1E, 0x10, 0x2B, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x79, -0x40, 0x65, 0x00, 0x9D, 0x80, 0x68, 0x06, 0x50, 0x09, 0x60, 0x27, 0x00, 0x9D, -0x00, 0x5C, 0x02, 0xB1, 0x39, 0xC2, 0xE7, 0x00, 0x81, 0x82, 0x6C, 0x1A, 0xD0, -0x89, 0xC0, 0x25, 0x00, 0xBD, 0x03, 0x34, 0x1A, 0x12, 0x49, 0x40, 0x07, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x9D, 0x40, 0x44, -0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x18, 0x09, 0x42, -0x24, 0x00, 0x8D, 0x00, 0x44, 0x82, 0x12, 0x09, 0x40, 0x27, 0x00, 0x95, 0x60, -0x34, 0x02, 0x58, 0x2D, 0x40, 0xA7, 0x80, 0xD1, 0x98, 0x64, 0x02, 0xD0, 0x09, -0x40, 0x27, 0x00, 0x9D, 0x40, 0x74, 0x22, 0x14, 0x09, 0x40, 0x63, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x9D, 0x02, 0x04, 0x02, -0x10, 0x08, 0x40, 0xA0, 0x00, 0x8D, 0x06, 0x34, 0x02, 0x10, 0x08, 0x40, 0x21, -0x00, 0x8D, 0x08, 0x45, 0x83, 0x5A, 0x88, 0x60, 0x23, 0x82, 0x8D, 0x08, 0x34, -0x22, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x02, 0xD0, 0x08, 0x40, -0x31, 0x80, 0xCD, 0x00, 0x74, 0x02, 0x10, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x4D, 0x04, 0x34, -0x11, 0x50, 0x04, 0x05, 0x0F, 0x00, 0x7C, 0x78, 0x30, 0x41, 0x41, 0x04, 0x00, -0x1D, 0x02, 0x44, 0x50, 0x31, 0x61, 0x41, 0x87, 0x05, 0x17, 0x42, 0x74, 0x08, -0x74, 0x20, 0xC0, 0x07, 0x00, 0x13, 0x40, 0x6C, 0x50, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x81, 0x7C, 0x00, 0x30, 0xA1, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0x7C, 0x0A, 0xF1, 0x29, -0xC0, 0x67, 0x00, 0x9F, 0x09, 0x7C, 0x82, 0xF4, 0x09, 0xC0, 0x2F, 0x20, 0xBF, -0x04, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xFF, 0x24, 0xDC, 0x12, 0x00, -0x4B, 0xC0, 0x2D, 0x40, 0xAF, 0x00, 0x6C, 0x02, 0xF0, 0x0B, 0xC8, 0x39, 0x00, -0x9F, 0x22, 0xFC, 0x03, 0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x67, 0x01, 0x93, 0x02, 0xCC, 0x06, 0xF0, 0x1B, 0xC0, -0x25, 0x02, 0x9B, 0xE0, 0x7C, 0x12, 0xF0, 0x4B, 0xC5, 0x2F, 0x00, 0x93, 0x00, -0xDC, 0x02, 0x38, 0x89, 0xC0, 0x27, 0x49, 0x93, 0x00, 0x5E, 0x22, 0x30, 0x0B, -0x40, 0x2C, 0x00, 0xA3, 0x00, 0xCC, 0x12, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBB, -0x11, 0xFC, 0x82, 0xE0, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1C, 0x08, 0x07, 0x08, 0x0B, 0x01, 0x45, 0x00, 0xD0, 0x01, 0x46, 0x47, -0x01, 0x1D, 0x9D, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x10, 0x5C, -0x00, 0x14, 0x81, 0x00, 0x07, 0x25, 0x11, 0x04, 0x5C, 0x10, 0x10, 0x01, 0x51, -0x04, 0x20, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x05, 0x48, 0x07, 0x10, 0x13, 0x42, -0x74, 0x00, 0xD0, 0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0xA0, 0xA3, 0x00, 0x81, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x23, 0x02, -0x8D, 0x00, 0x34, 0x32, 0xD0, 0x08, 0x40, 0x21, 0x00, 0x81, 0x04, 0x14, 0x22, -0x90, 0x08, 0x44, 0x23, 0x03, 0x89, 0x14, 0x54, 0x12, 0x18, 0x48, 0x40, 0x22, -0x40, 0x81, 0x00, 0x04, 0x22, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34, -0x02, 0xD1, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x88, 0x25, 0x00, 0x89, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D, -0x80, 0x74, 0x02, 0xD0, 0x09, 0x00, 0xA7, 0x42, 0x91, 0x02, 0x54, 0x02, 0x98, -0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x0C, 0x40, 0x26, 0x20, -0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x91, 0x00, 0x74, 0x02, -0xD0, 0x0D, 0x40, 0x60, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, -0x25, 0x00, 0xB3, 0x81, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x2F, 0x08, 0xBB, 0x80, -0x7C, 0x02, 0xF1, 0x09, 0x80, 0x65, 0x00, 0x93, 0x00, 0x1C, 0x02, 0x90, 0x09, -0x48, 0x27, 0x00, 0x9B, 0x03, 0x1C, 0x1A, 0x30, 0x59, 0xC0, 0x22, 0x01, 0x83, -0xA7, 0x4C, 0x02, 0xD0, 0x29, 0xC4, 0x67, 0x00, 0x9B, 0x80, 0x7C, 0x2A, 0xF0, -0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25, -0x00, 0x9F, 0x01, 0x70, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x80, 0x9C, 0xA0, 0x7C, -0x82, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x03, 0x7E, 0x02, 0x50, 0x09, 0xC4, -0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0xF4, 0x49, 0xE0, 0x65, 0x01, 0x9C, 0x44, -0x5C, 0x42, 0xF0, 0x09, 0x00, 0x67, 0x04, 0x9F, 0x20, 0x7E, 0x06, 0xD0, 0x58, -0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00, -0x1F, 0x00, 0x5C, 0x40, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, -0x31, 0x01, 0xE0, 0x06, 0x11, 0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC8, 0x03, -0x00, 0x1F, 0x00, 0x7C, 0x80, 0xF8, 0x01, 0xC0, 0x86, 0x00, 0x1F, 0x80, 0x5C, -0x00, 0x60, 0x01, 0xC0, 0x85, 0x00, 0x1F, 0x04, 0x4D, 0x00, 0xF0, 0x21, 0xC0, -0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D, -0x00, 0xD4, 0x0D, 0xD8, 0x07, 0x60, 0x17, 0x10, 0x5E, 0x00, 0x74, 0x01, 0x10, -0x57, 0xE0, 0x9B, 0x80, 0x5D, 0x20, 0xF4, 0x01, 0xB2, 0x05, 0xC0, 0x17, 0x80, -0x5D, 0x00, 0x7C, 0x01, 0x70, 0x17, 0xC0, 0x1C, 0x00, 0x7D, 0x02, 0xC4, 0x01, -0xB0, 0x17, 0x40, 0x98, 0x00, 0x7F, 0x03, 0xC4, 0x45, 0xD2, 0x07, 0x48, 0x41, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, -0x04, 0x2E, 0x50, 0x08, 0x40, 0x31, 0x80, 0xC9, 0x00, 0x34, 0x03, 0x13, 0x18, -0x60, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x02, 0x18, 0x0C, 0x40, 0x33, 0x10, 0xCD, -0x00, 0x34, 0x03, 0xD0, 0x7C, 0x50, 0x20, 0x00, 0xCD, 0x1A, 0x16, 0x0B, 0x10, -0x04, 0x00, 0xF1, 0x02, 0x8D, 0x00, 0x04, 0x1E, 0xD0, 0x8C, 0x40, 0x40, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x04, 0x94, -0x02, 0xD0, 0x0A, 0x40, 0x3B, 0x01, 0xED, 0x04, 0x34, 0x07, 0x18, 0x0A, 0x40, -0x3B, 0x00, 0xED, 0x04, 0x34, 0x02, 0x92, 0x4E, 0x40, 0x3B, 0x01, 0xED, 0x00, -0xB4, 0x03, 0x50, 0x0E, 0x41, 0x28, 0x10, 0xAD, 0x40, 0x84, 0x04, 0x90, 0x3E, -0x40, 0x38, 0x00, 0xAD, 0x83, 0x86, 0x03, 0xD0, 0x0A, 0x40, 0x11, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x03, 0x94, 0x07, -0x70, 0x1A, 0xC0, 0x79, 0x01, 0xED, 0x05, 0xB4, 0x37, 0x31, 0x1E, 0x40, 0x7A, -0x08, 0xED, 0x0B, 0xB4, 0x06, 0x34, 0x1E, 0xC0, 0x7B, 0x02, 0xED, 0x85, 0xBC, -0x27, 0xD8, 0x17, 0xE0, 0x68, 0x00, 0xAF, 0x81, 0x9C, 0x04, 0x78, 0x16, 0xC0, -0x79, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1B, 0xC0, 0x50, 0x60, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x10, 0xDF, 0x40, 0x7C, 0x03, 0xF0, -0x09, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x2B, 0xF4, 0x0D, 0xC0, 0x35, 0x00, -0xDF, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0, 0x35, 0x82, 0xDF, 0x3E, 0x5C, 0x3B, -0x70, 0x01, 0xE0, 0x25, 0x20, 0x9F, 0x00, 0x3C, 0x00, 0x70, 0x0D, 0xC2, 0x27, -0x00, 0xC7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xEF, 0x09, 0xCC, 0x32, 0xF8, 0x8B, -0xC0, 0x7C, 0x04, 0xFF, 0x11, 0xFC, 0x07, 0xF0, 0x1B, 0xC8, 0x7F, 0x00, 0xFF, -0x01, 0xDE, 0x06, 0xF0, 0xBD, 0xC1, 0x74, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, -0x1B, 0xC0, 0x6C, 0x00, 0x9B, 0x89, 0xFC, 0x25, 0xF0, 0x17, 0xC0, 0x7C, 0x00, -0xBB, 0x01, 0xBC, 0x07, 0x38, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x1C, 0x84, 0x22, 0xD8, 0x0A, 0xC0, -0x3A, 0xA0, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x00, 0xED, 0x00, -0x8C, 0x12, 0xD0, 0x5E, 0x40, 0x78, 0x02, 0xED, 0x00, 0x9C, 0x43, 0xD0, 0x0B, -0x60, 0x28, 0x06, 0xAD, 0x05, 0xB4, 0x24, 0xD2, 0x0E, 0xC0, 0x3A, 0x80, 0xA5, -0x00, 0xB4, 0x09, 0xF2, 0xC2, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x08, 0x39, 0x00, 0xFD, 0x81, 0xA4, 0x03, 0xD8, 0x88, 0x40, 0x78, -0x02, 0xE5, 0x01, 0xB4, 0x03, 0x50, 0x0A, 0x40, 0x3B, 0x02, 0xFD, 0x18, 0x94, -0x02, 0xD1, 0x4E, 0x54, 0x3A, 0x10, 0xED, 0x00, 0xB4, 0x23, 0xD0, 0x0E, 0x40, -0x28, 0x00, 0xA9, 0x14, 0xB4, 0x80, 0xD8, 0x86, 0x40, 0x39, 0x00, 0xE1, 0x00, -0xB4, 0x03, 0x10, 0x0E, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x01, 0xD0, 0x08, 0x64, 0x32, 0x00, -0xCD, 0x80, 0x34, 0x03, 0xD0, 0x08, 0x60, 0x13, 0x00, 0xCD, 0x81, 0x04, 0x02, -0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x40, 0x54, 0x0F, 0xD1, 0x28, 0x44, 0xE0, -0x10, 0x8D, 0x40, 0x34, 0x00, 0xD0, 0x88, 0x40, 0x63, 0x00, 0xC5, 0x00, 0x34, -0x09, 0x52, 0x30, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA8, 0x35, 0x00, 0xDF, 0x41, 0x6D, 0x02, 0xD0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, -0x00, 0xFC, 0x03, 0xF0, 0x09, 0xC8, 0xF7, 0x08, 0xFF, 0x03, 0x54, 0x83, 0xD2, -0x0F, 0x48, 0x3E, 0x00, 0xFF, 0x08, 0xF4, 0x0B, 0xD0, 0x2D, 0xD0, 0x34, 0x02, -0x8B, 0x01, 0x7C, 0x00, 0xD0, 0x0C, 0xC0, 0xB5, 0x06, 0x93, 0x00, 0x7C, 0x0A, -0x10, 0x21, 0xC0, 0x57, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x33, 0x00, 0xDF, 0x10, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x29, 0xC4, 0x77, 0x04, 0xDF, 0x04, 0x1C, 0x0A, 0xF0, 0x0D, -0xC0, 0x35, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0xA7, 0x08, 0x9F, -0x60, 0x7C, 0x88, 0xF1, 0x2D, 0x40, 0xB6, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0xA1, 0xC8, 0x37, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, -0x00, 0xF3, 0x00, 0xFC, 0x12, 0x30, 0x2F, 0xC0, 0x3F, 0x20, 0xF3, 0x40, 0xFC, -0x03, 0xF0, 0x1F, 0xC0, 0x2C, 0x02, 0xFF, 0x80, 0xFC, 0x87, 0x30, 0x0F, 0xD0, -0x3C, 0x00, 0xF5, 0x00, 0xCD, 0x43, 0xB0, 0x07, 0xC0, 0x7F, 0x00, 0xBF, 0x00, -0xCC, 0x80, 0xF0, 0x0F, 0x80, 0x3C, 0x00, 0xB3, 0x04, 0xFC, 0x40, 0xF0, 0x0A, -0xC1, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x20, -0xD1, 0x00, 0x74, 0x06, 0x94, 0x05, 0xC0, 0x35, 0x00, 0xD1, 0x00, 0x74, 0x03, -0xD0, 0x84, 0x41, 0x25, 0x00, 0xDD, 0x20, 0x74, 0x01, 0x10, 0x0D, 0x40, 0x34, -0x00, 0xD1, 0x00, 0x44, 0x03, 0xB0, 0x21, 0x40, 0x17, 0x00, 0x9D, 0x23, 0x44, -0x4C, 0xD0, 0x0D, 0x50, 0x60, 0x84, 0x95, 0x07, 0x74, 0x0C, 0xD0, 0x39, 0x50, -0x04, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0xC0, 0xD1, -0x00, 0x74, 0x02, 0x90, 0x0D, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, -0x09, 0x40, 0x34, 0x00, 0xDD, 0x00, 0x64, 0x1B, 0x10, 0x0D, 0x40, 0x34, 0x00, -0xD5, 0x00, 0x64, 0x03, 0x10, 0x01, 0x40, 0xB7, 0x01, 0x9D, 0x11, 0x44, 0x04, -0xD0, 0x0D, 0x41, 0x45, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x11, 0x40, 0x04, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0xC1, 0x00, -0x34, 0x02, 0x90, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08, -0x40, 0x11, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x14, 0x4C, 0x40, 0x30, 0x04, 0xC5, -0x20, 0x04, 0x03, 0xD4, 0x00, 0x44, 0x23, 0x80, 0x8D, 0x30, 0x05, 0x40, 0xD0, -0x0D, 0x40, 0x25, 0x00, 0x85, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x42, 0x40, 0x81, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0xF3, 0x40, 0x7C, -0x03, 0x30, 0x0D, 0xC4, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x2D, 0xC2, -0xA4, 0x02, 0xFD, 0x00, 0x7C, 0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x01, 0xF7, 0x00, -0xCC, 0x03, 0x32, 0x05, 0xC2, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x10, 0xF0, 0x0D, -0xC0, 0x25, 0x00, 0x51, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x04, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x01, -0x78, 0x07, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x47, 0xC1, 0x0F, -0x00, 0xEF, 0x00, 0xFC, 0x01, 0xF0, 0x2F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFC, -0x03, 0x30, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0x7C, 0x00, 0xF0, 0x0A, 0x40, -0x2A, 0x08, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x08, 0xA3, 0x00, 0xFC, 0x33, 0x30, -0x9B, 0xC0, 0xEF, 0x00, 0xFF, 0x03, 0x9D, 0x27, 0xB0, 0x1F, 0xC0, 0x7C, 0x02, -0xFB, 0x09, 0xCD, 0x07, 0x70, 0x1F, 0xC8, 0x7A, 0x08, 0xFF, 0x01, 0xFC, 0x07, -0x31, 0x9F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0x30, 0x1F, 0xC0, 0x7A, -0x40, 0xB3, 0x01, 0xFC, 0x00, 0x30, 0x26, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x3B, 0x38, 0xD1, 0x43, 0xF4, 0x13, 0x12, 0x4C, -0x44, 0x27, 0x11, 0x1C, 0x84, 0x44, 0x10, 0x10, 0x11, 0x50, 0x04, 0x01, 0x11, -0x04, 0x44, 0xD0, 0x50, 0x11, 0x40, 0x07, 0x05, 0x0D, 0x10, 0x34, 0x40, 0x10, -0x41, 0x40, 0x07, 0x00, 0x1D, 0x44, 0x5C, 0x10, 0x10, 0x11, 0x40, 0x44, 0x00, -0x91, 0x01, 0x5C, 0x0C, 0x14, 0x45, 0x40, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0xA0, 0x23, 0x05, 0x81, 0x22, 0x14, 0x33, 0x10, 0x0C, 0x48, -0x21, 0x01, 0xCD, 0x00, 0x44, 0x13, 0x54, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x80, -0x04, 0x03, 0x56, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x04, 0x34, 0x13, 0x90, 0x4C, -0x40, 0x33, 0x05, 0xCD, 0x20, 0x34, 0x13, 0x10, 0x0D, 0x40, 0x30, 0x00, 0x01, -0x01, 0x34, 0x0A, 0xD0, 0x40, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x88, 0x35, 0x40, 0xD1, 0x84, 0x74, 0x03, 0x14, 0x3D, 0x40, 0x27, -0x20, 0x0D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x42, 0x05, 0x00, 0x01, 0x00, 0x44, -0x00, 0x54, 0x01, 0x60, 0x07, 0x00, 0x1D, 0x80, 0x70, 0x00, 0x90, 0x01, 0x40, -0x07, 0x00, 0x1D, 0x20, 0x14, 0x00, 0x18, 0x01, 0x40, 0x04, 0x00, 0x51, 0x01, -0x74, 0x00, 0xD1, 0x01, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x5C, 0x03, 0x30, 0x3D, 0xC0, 0x65, 0x0A, -0xDF, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC8, 0x35, 0x40, 0xDB, 0x80, 0x08, 0x03, -0x74, 0x0D, 0xC4, 0x36, 0x10, 0xDF, 0x00, 0x78, 0x03, 0xA0, 0x0D, 0xC0, 0x37, -0x80, 0xDF, 0x00, 0x74, 0x03, 0x34, 0x0C, 0xC2, 0x36, 0x00, 0x91, 0x01, 0x3C, -0x15, 0xF0, 0x15, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x88, 0x3D, 0x00, 0xFF, 0x21, 0xF4, 0x03, 0xD0, 0x0F, 0xC0, 0x2F, 0x00, 0x3F, -0x40, 0xE4, 0x00, 0x30, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xFC, 0x40, 0xF0, -0x03, 0x00, 0x0F, 0x00, 0x3F, 0x30, 0xFC, 0x80, 0x70, 0x03, 0xC0, 0x0F, 0xA0, -0x3F, 0x40, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x14, 0xFF, 0x00, 0xDC, 0x24, -0x30, 0x47, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, -0x61, 0x10, 0x9B, 0x01, 0x6C, 0x03, 0x34, 0x3D, 0xC0, 0x24, 0x00, 0xD3, 0x50, -0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x77, 0x00, 0xD3, 0x08, 0x4C, 0x07, 0xB0, 0x4D, -0xC0, 0x37, 0x00, 0xD7, 0x01, 0x4C, 0x83, 0x30, 0x1D, 0xC1, 0x37, 0x00, 0xDF, -0x01, 0x7C, 0x97, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x10, 0x7C, 0x20, 0x30, -0x25, 0xD0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, -0x02, 0xD1, 0x20, 0xD4, 0x2B, 0x10, 0x2D, 0x40, 0x64, 0x01, 0x1A, 0x03, 0x3C, -0x00, 0x14, 0x40, 0x42, 0x87, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x51, 0xC0, -0x05, 0x40, 0x15, 0x01, 0x44, 0x04, 0x10, 0x11, 0x40, 0x07, 0x00, 0x1D, 0x21, -0x74, 0x0C, 0xD0, 0x01, 0x44, 0xC0, 0x04, 0x59, 0x03, 0x74, 0x20, 0x00, 0xB5, -0x40, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x30, 0x00, -0x89, 0x40, 0x44, 0x03, 0x90, 0x2C, 0x41, 0x60, 0x00, 0xC9, 0x02, 0x34, 0x03, -0x10, 0x1C, 0x40, 0xB7, 0x04, 0xC1, 0x01, 0x14, 0x03, 0x90, 0x2C, 0x40, 0x33, -0x00, 0xC9, 0x02, 0x54, 0x27, 0x91, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, -0x0B, 0xD0, 0x0C, 0x40, 0xF0, 0x40, 0x89, 0x03, 0x14, 0x0C, 0x10, 0x9C, 0x40, -0x4C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x78, 0x00, 0xF1, -0x01, 0x14, 0x07, 0x90, 0x1E, 0x40, 0x68, 0x00, 0x29, 0x11, 0xC4, 0x04, 0x10, -0x92, 0x48, 0x4B, 0x00, 0x21, 0x03, 0x94, 0x04, 0x12, 0x12, 0x40, 0x4D, 0x20, -0x29, 0x09, 0x95, 0x0C, 0x50, 0x12, 0x40, 0x4B, 0x20, 0x2C, 0x41, 0xB0, 0x04, -0xD0, 0x13, 0x40, 0x48, 0x00, 0xA9, 0x29, 0xB4, 0x17, 0x10, 0x1F, 0x40, 0x3C, -0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x18, 0x20, 0x00, 0x8B, 0x00, -0x0C, 0x03, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xCB, 0x88, 0x34, 0x23, 0x31, 0x0C, -0xC0, 0x37, 0x00, 0xD3, 0x80, 0x5C, 0x23, 0xB0, 0x8C, 0xC0, 0x33, 0x02, 0xCF, -0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCE, 0x00, 0x3C, 0x03, 0xF2, -0x0C, 0xC4, 0x30, 0x00, 0x43, 0x30, 0x1C, 0x03, 0x30, 0x7C, 0xC0, 0x48, 0x40, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x3D, 0x00, 0xFF, 0x00, 0xDC, -0x4B, 0x50, 0x0F, 0xC0, 0x2F, 0x02, 0x3F, 0x28, 0xFE, 0x00, 0xF2, 0x03, 0x48, -0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x00, -0xEC, 0x00, 0xB0, 0x83, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x02, -0xC0, 0x4F, 0x40, 0x77, 0x00, 0x3C, 0x13, 0xF2, 0x8D, 0xC0, 0x0B, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13, -0xF0, 0x0D, 0xC0, 0x24, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x1C, 0xC0, 0x30, -0x40, 0xD3, 0x00, 0x6F, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4D, -0x03, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0xDF, 0x21, 0x4D, 0x07, 0x24, 0x0D, 0xC0, -0x33, 0x00, 0x53, 0x00, 0x4C, 0x07, 0x32, 0x15, 0xC0, 0x40, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x22, 0xED, 0x00, 0xB4, 0x03, 0xD0, -0x0F, 0x50, 0x28, 0x00, 0x2D, 0x00, 0xBC, 0x00, 0xD0, 0x02, 0x48, 0x09, 0x00, -0x21, 0x00, 0x84, 0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0x84, 0x00, -0xD0, 0x03, 0x40, 0x08, 0x00, 0x3D, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x44, 0x0B, -0x00, 0xE1, 0x20, 0xAC, 0x03, 0xB0, 0x07, 0xC0, 0x4E, 0x68, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x69, 0x10, 0xED, 0x03, 0x94, 0x17, 0xD0, 0x1E, -0x40, 0x68, 0x04, 0xED, 0x41, 0xB4, 0x07, 0x50, 0x1E, 0x44, 0x7C, 0x20, 0xF9, -0x81, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x84, 0x07, 0xD0, -0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x84, 0x87, 0x18, 0x1E, 0x40, 0x7B, 0x40, -0x71, 0x01, 0x04, 0x07, 0x10, 0x16, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0xD0, 0x24, 0x4C, -0x30, 0x10, 0x0D, 0x00, 0x12, 0x00, 0xD0, 0x00, 0x40, 0x01, 0x10, 0x09, 0xC0, -0x04, 0x80, 0xD0, 0x00, 0x42, 0x03, 0x08, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x00, -0x40, 0x01, 0x00, 0x0D, 0x00, 0x06, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x51, -0x03, 0x24, 0xCF, 0x12, 0x34, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x17, 0xA0, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x27, 0xC0, 0x54, -0x00, 0x5F, 0x00, 0x74, 0x01, 0x70, 0x05, 0xC4, 0x14, 0x00, 0x4B, 0x00, 0x6C, -0x01, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0, -0x15, 0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x13, 0x00, 0x71, 0x07, -0xCC, 0x11, 0x14, 0x17, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x07, 0x00, -0x3D, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x02, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0E, -0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x1F, 0x06, 0x7C, -0x00, 0xF0, 0xA1, 0xC9, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x21, 0x00, 0x93, 0x00, 0x3C, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x10, 0x9F, -0x01, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0xE7, 0x00, 0x93, 0x00, 0x6C, 0x06, 0xF0, -0x99, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x34, 0x59, 0xC0, 0x27, 0x00, -0x9F, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9B, 0x00, 0x6C, 0x02, -0xF0, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, -0x26, 0x40, 0x91, 0x80, 0x74, 0x42, 0x10, 0xA9, 0x41, 0x24, 0x00, 0x8D, 0x09, -0x5E, 0x2A, 0xD0, 0x19, 0x40, 0x63, 0x40, 0x91, 0x02, 0x45, 0x1A, 0xD0, 0x69, -0xC2, 0x26, 0x08, 0x9D, 0x02, 0x44, 0x42, 0x10, 0x39, 0x40, 0x27, 0x00, 0x9D, -0x02, 0x74, 0x0A, 0xD0, 0x09, 0x48, 0x67, 0x04, 0x91, 0x82, 0x44, 0x86, 0xD0, -0x69, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x64, -0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x24, 0x00, 0x9D, 0x00, 0xC4, -0x42, 0xD0, 0x4B, 0x40, 0x2F, 0x00, 0xB9, 0x03, 0xC4, 0x12, 0xD0, 0x0B, 0x40, -0x2C, 0x00, 0xBD, 0x00, 0xC4, 0x06, 0x92, 0x0B, 0x44, 0x2F, 0x00, 0xBD, 0xC0, -0xF4, 0x02, 0xD0, 0x1B, 0x40, 0x2F, 0x41, 0x91, 0x08, 0x64, 0x22, 0xD0, 0x09, -0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x20, 0x01, -0x81, 0x04, 0x34, 0x12, 0x18, 0x08, 0x50, 0x20, 0x00, 0xBC, 0x00, 0x84, 0x02, -0xD0, 0x0A, 0x40, 0x6F, 0x00, 0xB9, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0x2A, -0x00, 0xAD, 0x01, 0x84, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xAD, 0x41, 0xB4, -0x06, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0x91, 0x00, 0x24, 0x02, 0xD0, 0x48, 0x40, -0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x86, 0x02, 0x13, -0x00, 0x7C, 0x28, 0x34, 0xA1, 0xC0, 0x84, 0x02, 0x1F, 0x0A, 0x44, 0x28, 0xF0, -0x01, 0xC0, 0x87, 0x02, 0x1B, 0x0A, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x85, 0x02, -0x1F, 0x0A, 0x4C, 0x28, 0xB3, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x0A, 0x7C, 0x28, -0xF0, 0x01, 0xC0, 0x0F, 0x10, 0x53, 0x00, 0x6C, 0x51, 0xFA, 0xA1, 0xC0, 0x77, -0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x88, 0x2F, 0x02, 0xBF, 0x08, -0x7C, 0x22, 0x78, 0x0B, 0xC0, 0x2F, 0x20, 0x9E, 0x00, 0x5D, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x87, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, -0x00, 0x7D, 0x02, 0x71, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x7C, 0x82, 0xF0, -0x09, 0xC2, 0x27, 0x00, 0xA7, 0x00, 0xDC, 0x02, 0xF0, 0x8B, 0xC0, 0x67, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xB3, 0x14, 0xCC, -0xB2, 0x30, 0x0F, 0xC0, 0x2D, 0x00, 0xBF, 0x08, 0xCC, 0x02, 0x10, 0x0B, 0xC0, -0x2F, 0x02, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x00, -0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0xDC, 0x02, 0x30, 0x0B, -0xC0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x82, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x0D, 0x11, 0x00, 0x45, 0x30, -0x10, 0x01, 0x43, 0x04, 0x04, 0x1D, 0x00, 0x04, 0x50, 0x10, 0x01, 0x40, 0x03, -0x01, 0x1D, 0x10, 0x4C, 0x40, 0x14, 0x01, 0x50, 0x04, 0x05, 0x01, 0x04, 0x74, -0x10, 0xD0, 0x00, 0x41, 0x00, 0x24, 0x01, 0x40, 0x5C, 0x50, 0x10, 0x01, 0x40, -0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x81, 0x40, 0x73, 0x60, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03, 0x91, 0x20, 0x04, 0x12, 0x90, -0x49, 0x40, 0x21, 0x80, 0x8D, 0x00, 0x04, 0x12, 0x10, 0x0C, 0x40, 0x23, 0x01, -0x8D, 0x04, 0x65, 0x02, 0x10, 0x09, 0x40, 0x24, 0x41, 0x81, 0x14, 0x34, 0x12, -0xD8, 0x48, 0x50, 0x20, 0x00, 0x81, 0x00, 0x14, 0x12, 0x10, 0x08, 0x40, 0x23, -0x00, 0x89, 0x00, 0x34, 0x02, 0x10, 0x08, 0x48, 0x4B, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x41, 0x91, 0x00, 0x44, 0x03, 0x90, 0x29, -0x40, 0x24, 0x02, 0x8D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x8D, -0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x24, 0x00, 0xD1, 0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x37, 0x20, -0x99, 0x00, 0x74, 0x0A, 0x12, 0x89, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x83, 0x89, 0x0C, 0x02, 0xB4, 0x18, 0xC0, -0x65, 0x20, 0x9F, 0x00, 0x4D, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x80, 0x9F, 0x00, -0x6C, 0x02, 0x30, 0x08, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x24, 0x40, 0x93, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x99, -0x12, 0x7C, 0x02, 0x34, 0x19, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x41, 0x7C, 0x02, 0x74, 0x29, 0xC0, 0x27, -0x00, 0x9F, 0x50, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x97, 0x15, -0x7E, 0x52, 0xF0, 0x09, 0xE0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x08, 0x41, 0x40, 0x13, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x07, 0x00, -0x1F, 0x08, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, -0xF0, 0x11, 0xF0, 0x04, 0x00, 0x1F, 0x20, 0x4C, 0x04, 0xD0, 0x01, 0xC0, 0x06, -0x40, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02, 0x0C, -0x08, 0x14, 0x01, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA0, 0x5C, 0x00, 0x51, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xC0, 0x15, 0x00, 0x7D, -0x00, 0xC6, 0x05, 0x50, 0x05, 0x40, 0x5F, 0x04, 0x73, 0x02, 0xB4, 0x29, 0xD1, -0x07, 0xC2, 0x12, 0x00, 0x7D, 0x45, 0xC4, 0x15, 0xD0, 0x07, 0xC0, 0x14, 0x00, -0x71, 0x02, 0xCC, 0x01, 0xD0, 0x15, 0x40, 0x9B, 0x08, 0x71, 0x02, 0xD4, 0x0D, -0x50, 0xF7, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, -0x32, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0x20, 0xCD, 0x00, -0x64, 0x0F, 0x50, 0x08, 0x44, 0x73, 0x00, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x04, -0x40, 0x32, 0x10, 0xCD, 0x01, 0x05, 0x03, 0x50, 0x0D, 0x40, 0x34, 0x00, 0xC1, -0x06, 0x65, 0x07, 0xD0, 0x98, 0x40, 0x63, 0x03, 0x41, 0x08, 0x04, 0x23, 0x10, -0x0C, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x08, -0x04, 0xE1, 0x00, 0xB4, 0x43, 0x90, 0x0E, 0x40, 0x39, 0x00, 0x7D, 0x00, 0xA5, -0x0B, 0x50, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x41, -0x38, 0x01, 0xED, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x0A, 0xE1, 0x83, -0xA4, 0x43, 0xD0, 0x0E, 0x40, 0x1F, 0x00, 0x71, 0x01, 0x14, 0x03, 0x10, 0x12, -0x58, 0x06, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x60, 0x00, -0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x79, 0x00, 0xEF, 0x01, 0xA4, 0x06, -0x70, 0x1E, 0xC0, 0x6B, 0x40, 0xE3, 0x01, 0xB0, 0x05, 0xF0, 0x1E, 0x40, 0x7A, -0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xC0, 0x78, 0x05, 0xE3, 0x01, 0xAC, -0x07, 0xF1, 0x1E, 0xC0, 0x6B, 0x00, 0x63, 0x81, 0x84, 0x07, 0x30, 0x18, 0xC0, -0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x05, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x10, 0x0F, 0x00, 0x5C, 0x02, 0xB0, -0x0D, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x0C, 0xC0, 0x37, 0x04, -0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0xB5, 0x00, 0x9F, 0x00, 0x5C, 0x01, -0xF0, 0x0D, 0xC0, 0x33, 0x20, 0x4F, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x41, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x4D, 0x00, 0xE7, 0x21, -0xCC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x02, 0xBF, 0x01, 0xCC, 0x07, 0x30, 0x1F, -0xC0, 0x7C, 0x00, 0x73, 0x01, 0xEC, 0x05, 0x32, 0x1F, 0xC0, 0x7F, 0x04, 0xF3, -0x01, 0xFC, 0x04, 0xB0, 0x1F, 0xC0, 0x7F, 0x10, 0xB3, 0x01, 0xCC, 0x07, 0xF0, -0x1E, 0xC0, 0x3C, 0x00, 0xF3, 0x05, 0xCC, 0x06, 0xF0, 0x13, 0x84, 0x0B, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x8D, 0x10, 0xE1, 0x08, 0x84, -0x21, 0x78, 0x0E, 0x44, 0x38, 0x00, 0x7D, 0x06, 0xC5, 0x03, 0x10, 0x0E, 0x40, -0x28, 0x00, 0x71, 0x40, 0x84, 0xE0, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x10, -0xB4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x02, 0xBB, 0x18, 0x8C, 0x0A, 0xD0, 0x8E, -0x40, 0x19, 0x02, 0xA1, 0x06, 0xAC, 0x03, 0xD0, 0x20, 0x40, 0x57, 0x60, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xE5, 0x00, 0x85, 0x01, -0x50, 0x87, 0x40, 0x38, 0x8C, 0xAD, 0x00, 0x86, 0x01, 0x90, 0x0F, 0x40, 0x3A, -0x40, 0xE1, 0x00, 0xC4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xF4, -0x0A, 0x10, 0x0E, 0x40, 0x3F, 0x00, 0x61, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, -0x29, 0x42, 0x61, 0x0C, 0x94, 0x43, 0xD0, 0x02, 0x40, 0x23, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xC1, 0x00, 0x04, 0x01, 0x50, -0x31, 0x40, 0x70, 0x00, 0x1D, 0x41, 0x02, 0x45, 0x90, 0x3C, 0x50, 0x82, 0x04, -0x01, 0x10, 0x04, 0x08, 0x10, 0x2C, 0x42, 0x77, 0x01, 0x01, 0x05, 0x30, 0x04, -0x10, 0xD0, 0x40, 0xB3, 0x04, 0x09, 0x05, 0x06, 0x34, 0xD0, 0x1C, 0x40, 0x91, -0x00, 0x81, 0x13, 0x34, 0x0E, 0xD0, 0x00, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x80, 0x05, 0x00, 0xD7, 0x00, 0x4C, 0x03, 0x70, 0xE9, -0xC0, 0x74, 0x00, 0xDF, 0x05, 0x4C, 0x09, 0xB0, 0x0D, 0xC0, 0x16, 0x00, 0x93, -0x01, 0x4C, 0x07, 0x34, 0x7C, 0x40, 0xBF, 0x00, 0x13, 0x03, 0x3C, 0x03, 0x10, -0x21, 0xC0, 0x3B, 0x00, 0x53, 0x03, 0x4C, 0x08, 0xF0, 0x3D, 0xC0, 0xB5, 0x02, -0x43, 0x11, 0x50, 0x0D, 0xF0, 0x09, 0x40, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x00, 0x47, 0x00, 0x9F, 0x01, 0x7C, 0x83, 0x70, 0x09, 0xD2, -0x27, 0x00, 0xDF, 0x04, 0x7C, 0x21, 0x70, 0x8D, 0xC0, 0xB5, 0x02, 0xDF, 0x08, -0x7C, 0x8B, 0xF2, 0x0D, 0xC0, 0x37, 0x42, 0x9F, 0x00, 0x7C, 0x23, 0x70, 0x29, -0xC0, 0x77, 0x00, 0x57, 0x02, 0x5C, 0x02, 0xF0, 0xCD, 0xC0, 0xF7, 0x40, 0x5F, -0x40, 0x2C, 0x0B, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x0B, 0x40, 0xE3, 0x00, 0xEC, 0x03, 0xF0, 0x8F, 0xC0, 0x3C, -0x00, 0xFB, 0x00, 0xCC, 0x02, 0x30, 0x0F, 0xC1, 0x0F, 0x00, 0xBF, 0x09, 0xFC, -0x40, 0xF0, 0x0F, 0xC1, 0x3C, 0x00, 0x33, 0x05, 0xFC, 0x03, 0xB0, 0x47, 0xC0, -0x3D, 0x00, 0x73, 0x00, 0xCC, 0x20, 0x30, 0x9F, 0xC0, 0xFF, 0x00, 0xB3, 0x00, -0xCC, 0x43, 0x32, 0x0B, 0xC4, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x81, 0x20, 0xC6, 0x00, 0x91, 0x00, 0x44, 0x0F, 0xF0, 0x11, 0x60, 0x61, 0x02, -0x91, 0x02, 0x44, 0x02, 0x10, 0x0D, 0x40, 0x87, 0x04, 0x1D, 0x00, 0x5C, 0x1E, -0xD1, 0x1D, 0x40, 0x34, 0x08, 0x11, 0x12, 0x74, 0x00, 0x10, 0x71, 0x40, 0x34, -0x00, 0x11, 0x02, 0x4C, 0x0C, 0x10, 0x0D, 0x40, 0x33, 0x00, 0x11, 0x01, 0x44, -0x2F, 0x15, 0x19, 0x40, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0xA0, 0x46, 0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x01, 0x40, 0x37, 0x20, 0x19, -0x00, 0x04, 0x10, 0x10, 0x1D, 0x48, 0x17, 0x10, 0x1D, 0x00, 0x74, 0x05, 0x50, -0x1D, 0x44, 0x34, 0x40, 0x51, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x36, 0x00, -0x81, 0x00, 0x04, 0x01, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD9, 0x01, 0x64, 0xC3, -0x10, 0x19, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x00, 0x18, 0x81, 0x00, 0x04, 0x00, 0xD8, 0x08, 0x40, 0x26, 0x80, 0x41, 0x00, -0x05, 0x04, 0x18, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x00, 0x34, 0x03, 0xD0, 0x1D, -0x40, 0x30, 0x00, 0x81, 0x00, 0x74, 0x01, 0x18, 0x08, 0x50, 0x36, 0x00, 0x81, -0x00, 0x04, 0x02, 0x14, 0x0C, 0x40, 0x37, 0x00, 0x89, 0x00, 0x04, 0x03, 0x10, -0x00, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x06, -0x00, 0xD3, 0x00, 0x6C, 0x00, 0xF0, 0x05, 0x50, 0x37, 0x00, 0x1B, 0x00, 0x4C, -0x00, 0x20, 0x0D, 0xC0, 0x13, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x50, -0x38, 0x00, 0x53, 0x00, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00, -0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x37, 0x10, 0x9B, 0x20, 0x6C, 0x81, 0x30, 0xA9, -0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, -0xBF, 0x00, 0xFC, 0x00, 0x70, 0x02, 0xC0, 0x2D, 0x00, 0x3F, 0x00, 0xFC, 0x00, -0xF0, 0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0x9C, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, -0x00, 0x3F, 0x00, 0xBC, 0x00, 0x78, 0x03, 0xC0, 0x39, 0x00, 0x3E, 0x00, 0xDC, -0x80, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xA7, 0x00, 0xFE, 0x03, 0xF0, 0x4B, 0xE0, -0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xDF, 0x00, 0xB3, -0x08, 0xFC, 0x06, 0x70, 0x9F, 0xC8, 0x7E, 0x12, 0xF3, 0x09, 0xEC, 0x27, 0x11, -0x1F, 0xC0, 0x7C, 0x00, 0xE3, 0x09, 0xDC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x40, -0xF3, 0x09, 0xBC, 0x0F, 0xF8, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0x9C, 0x07, -0xF0, 0x1F, 0xC0, 0x5C, 0x00, 0x33, 0x01, 0xCC, 0x06, 0xF0, 0x1B, 0xC8, 0x0D, -0x08, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x27, 0x01, 0x91, 0x20, -0x44, 0x53, 0x10, 0x01, 0x40, 0x06, 0x00, 0x15, 0x00, 0x50, 0x00, 0x50, 0x11, -0x40, 0x44, 0x08, 0x15, 0x00, 0x04, 0x10, 0xD2, 0x01, 0x41, 0x45, 0x00, 0x11, -0x80, 0x74, 0x00, 0xD0, 0x11, 0x42, 0x03, 0x25, 0x11, 0x04, 0x64, 0x04, 0xD1, -0x1F, 0x48, 0x74, 0x40, 0x15, 0x81, 0x54, 0x02, 0xD2, 0x09, 0x42, 0x0F, 0x60, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x44, 0x14, -0x13, 0x50, 0x4D, 0x48, 0x37, 0x11, 0xD1, 0x84, 0x46, 0x13, 0x10, 0x0C, 0x62, -0x30, 0x20, 0xC5, 0x04, 0x14, 0x03, 0xD0, 0x4D, 0x40, 0x30, 0x00, 0xC9, 0x44, -0x14, 0x13, 0xD0, 0x0C, 0x40, 0x36, 0x10, 0xD5, 0x00, 0x14, 0x03, 0x58, 0x0C, -0x40, 0x21, 0x00, 0x15, 0x20, 0x14, 0x00, 0xD8, 0x00, 0x40, 0x4F, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x25, 0x10, 0xD1, 0x21, 0x64, 0x07, -0x10, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0x50, 0x01, 0x70, 0x04, -0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x19, 0x00, 0x74, -0x00, 0xD0, 0x01, 0x42, 0x07, 0x00, 0x11, 0x00, 0x64, 0x00, 0xD0, 0x0D, 0x00, -0x25, 0x00, 0x15, 0x01, 0x54, 0x44, 0xD0, 0x11, 0x41, 0x0F, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x13, 0x03, 0xD3, 0x31, 0x7C, 0x17, 0x70, -0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x30, -0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0x02, 0x34, 0x00, 0xDB, 0x00, 0x7C, 0x03, -0xD0, 0x0D, 0x40, 0x37, 0x20, 0xC7, 0x40, 0x5C, 0x03, 0xF0, 0x0D, 0xD0, 0x15, -0x00, 0x06, 0x01, 0x5C, 0x0E, 0xF0, 0x39, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0x80, 0x2D, 0x40, 0xDF, 0x00, 0xDC, 0x03, 0xF0, 0x03, -0xC0, 0x0C, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x3B, -0x00, 0xEC, 0x00, 0xF0, 0x03, 0x08, 0x0F, 0x00, 0x37, 0x00, 0xFC, 0x00, 0xF0, -0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xD0, 0x0F, 0xC0, 0x3E, 0x81, -0xBB, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x08, 0xB5, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x70, 0x8D, 0xC0, -0x37, 0x01, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x01, 0xD7, 0x00, -0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, -0xC2, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x13, 0xB0, 0x0C, 0xC0, 0x24, 0x01, 0x9F, -0x00, 0x7C, 0x08, 0xF0, 0x21, 0x48, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x11, 0x40, 0x00, -0x04, 0x0B, 0x00, 0x5C, 0x00, 0xB0, 0x00, 0x40, 0x83, 0x00, 0x1B, 0x00, 0x6E, -0x00, 0x10, 0x00, 0x40, 0xC3, 0x00, 0x1D, 0x00, 0x5C, 0x00, 0x10, 0x01, 0xE8, -0x03, 0x00, 0x11, 0x80, 0x44, 0x40, 0x10, 0x0D, 0xC0, 0x20, 0x01, 0x9D, 0x00, -0x5C, 0x00, 0xD0, 0x11, 0x41, 0x4F, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x20, 0x22, 0x00, 0x9D, 0x00, 0x44, 0x03, 0x50, 0x0C, 0x40, 0xB1, 0x00, -0xC5, 0x00, 0x14, 0x03, 0x10, 0x1C, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x04, 0x03, -0x10, 0x0C, 0x48, 0x73, 0x00, 0xC9, 0x00, 0x34, 0x83, 0x90, 0x0C, 0x40, 0x30, -0x00, 0xC5, 0x00, 0x24, 0x07, 0x80, 0x0C, 0x40, 0xE3, 0x00, 0x4D, 0x05, 0x36, -0x12, 0xD0, 0x48, 0x40, 0x4F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x08, 0x6A, 0x00, 0xED, 0x09, 0x86, 0x07, 0x10, 0x13, 0x60, 0x4C, 0x00, 0x2D, -0x01, 0xD4, 0x04, 0x90, 0x12, 0x40, 0x4F, 0x00, 0x38, 0x01, 0xA4, 0x04, 0x1C, -0x12, 0x40, 0x4B, 0x04, 0x2D, 0x01, 0xD4, 0x04, 0x00, 0x13, 0x40, 0x49, 0x00, -0x21, 0x01, 0xC4, 0x04, 0x50, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x11, 0x94, 0x07, -0xD0, 0x9A, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, -0x32, 0x02, 0x0D, 0x08, 0x4C, 0x03, 0x50, 0x0C, 0x40, 0x31, 0x12, 0xD7, 0x00, -0x1C, 0x03, 0x30, 0x0C, 0x40, 0x33, 0x00, 0xC7, 0x00, 0x04, 0x03, 0x30, 0x0C, -0xC0, 0x33, 0x00, 0xCF, 0x08, 0x34, 0x13, 0xB0, 0x0D, 0x40, 0x30, 0x02, 0xD7, -0x00, 0x2C, 0x03, 0xB0, 0x0C, 0xD0, 0x23, 0x02, 0xCF, 0x20, 0x3C, 0x42, 0xF0, -0x8C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D, -0x00, 0x7F, 0x08, 0xF8, 0x03, 0xE0, 0x02, 0x80, 0x09, 0x00, 0x3B, 0x00, 0xA8, -0x20, 0xF2, 0x81, 0xC0, 0x0B, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC8, -0x07, 0x00, 0x3F, 0x28, 0x7C, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40, -0x54, 0x24, 0x20, 0x9D, 0xC0, 0x2C, 0x08, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x8F, -0xC2, 0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x27, 0x00, -0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x1D, 0xC0, 0x35, 0x00, 0xDE, 0x00, 0x7C, 0x07, -0x30, 0x1D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0x1D, 0xC0, 0x34, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C, -0x03, 0xB0, 0x0D, 0xC4, 0x24, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0x30, 0x0D, 0xC2, -0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xFD, -0x00, 0x84, 0x03, 0xD0, 0x03, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50, -0x02, 0x00, 0x08, 0x88, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x09, 0x00, -0x2F, 0x00, 0xA4, 0x00, 0xD1, 0x02, 0x48, 0x0B, 0x00, 0x2D, 0x20, 0xB6, 0x00, -0x18, 0x4E, 0x40, 0x38, 0x20, 0xED, 0x00, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x4C, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0x6D, 0x00, -0x84, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x81, 0xF4, 0x07, 0x18, 0x1F, -0x48, 0x78, 0x80, 0xED, 0x01, 0xF6, 0x07, 0x13, 0x1F, 0x44, 0x7B, 0x80, 0xED, -0x01, 0xB4, 0x87, 0x58, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xF4, 0x07, 0xD8, -0xDE, 0x40, 0x6A, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x23, 0x00, 0x4C, 0x00, 0x04, -0x05, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40, -0x00, 0xA0, 0x0D, 0x00, 0x74, 0x00, 0x50, 0x00, 0x40, 0x03, 0x10, 0x05, 0x00, -0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x20, 0x34, 0x00, 0x51, 0x0C, -0x50, 0x22, 0x00, 0x8D, 0x0F, 0x74, 0x0F, 0x1A, 0x6D, 0x40, 0x58, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x1F, 0x00, 0x7F, 0x10, 0xCC, 0x0D, -0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xD0, 0x14, -0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5D, 0x00, 0x7C, -0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x3C, 0x01, 0xF0, 0x04, 0xC0, -0x1A, 0x00, 0x7F, 0x00, 0xFC, 0x0D, 0x34, 0x07, 0xD0, 0x5C, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x20, 0x7C, 0x40, 0xF2, -0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x8F, 0x00, -0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xE4, 0x00, -0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x08, 0x90, 0x01, 0xC0, 0x05, -0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x81, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x65, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x19, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F, -0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE7, 0x80, 0x9F, 0x00, 0x4D, 0x02, 0x34, -0x09, 0xC0, 0x27, 0x00, 0x9B, 0x00, 0x7C, 0x06, 0x72, 0x09, 0xC0, 0x24, 0x00, -0x93, 0x05, 0x7C, 0x42, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x28, 0x66, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x19, 0x40, -0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0xD8, 0x19, 0x40, 0xE7, 0x20, 0x9D, 0x00, -0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x04, 0x97, 0x20, 0x44, 0x02, 0x30, 0x09, -0x40, 0x23, 0x00, 0x91, 0x20, 0x70, 0x16, 0x30, 0x0B, 0xD0, 0x24, 0x00, 0x91, -0x00, 0x74, 0x96, 0x50, 0x39, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1C, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x89, 0x40, 0x6F, -0x00, 0xBD, 0x00, 0xD4, 0x02, 0xD0, 0xAB, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xF4, -0x02, 0x10, 0x0B, 0x60, 0x2F, 0x00, 0xAD, 0x00, 0x84, 0x02, 0x10, 0x0B, 0x40, -0x2F, 0x80, 0xB9, 0x00, 0xF4, 0x12, 0x10, 0x69, 0x60, 0x36, 0x00, 0xD9, 0x02, -0x74, 0x06, 0x10, 0x19, 0x41, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x28, 0xA0, 0x00, 0x8D, 0x1C, 0x34, 0x22, 0xD0, 0x2A, 0x40, 0xEB, 0x00, -0xBD, 0x08, 0x84, 0x22, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB0, 0x22, -0x10, 0x8A, 0x40, 0x2B, 0x00, 0xA5, 0x88, 0x84, 0x22, 0x10, 0x0A, 0x40, 0x2F, -0x02, 0xA1, 0x08, 0xB4, 0x02, 0x14, 0x08, 0x64, 0x24, 0x08, 0x89, 0x00, 0x34, -0x02, 0x50, 0x09, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB0, 0x06, 0x00, 0x1F, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, -0x02, 0x5C, 0x08, 0xD0, 0x01, 0xC0, 0x17, 0x00, 0x1D, 0x8A, 0x7C, 0x08, 0x34, -0x21, 0xC0, 0x07, 0x00, 0x1D, 0x02, 0x44, 0x08, 0x30, 0x01, 0xC0, 0x87, 0x00, -0x1B, 0x02, 0xFC, 0x00, 0x70, 0x11, 0xC0, 0x06, 0x40, 0x1B, 0x00, 0x7C, 0x28, -0x32, 0xA1, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, -0x6F, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0, 0x19, 0x40, 0x67, 0x00, 0x9F, 0x44, -0x3C, 0x12, 0xF2, 0x08, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x12, 0xF0, 0x48, -0xC0, 0x27, 0x00, 0x97, 0x84, 0x7C, 0x12, 0x70, 0x09, 0xC2, 0x27, 0x01, 0x9F, -0x84, 0x7C, 0x02, 0x70, 0x28, 0xC0, 0x2D, 0x00, 0xB7, 0x00, 0xFC, 0x02, 0xF0, -0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, -0x00, 0x93, 0x2C, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0xAB, 0x00, 0x97, 0x00, 0x7C, -0x02, 0xF0, 0x0B, 0xC0, 0x28, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC8, -0x2D, 0x00, 0x93, 0x08, 0x5C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00, -0xDC, 0x02, 0xB0, 0x1B, 0xC3, 0x2B, 0x00, 0xBF, 0x60, 0xFC, 0x82, 0x30, 0x0B, -0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x54, 0x45, -0x51, 0x4C, 0x74, 0x40, 0xD0, 0x51, 0x41, 0x47, 0x01, 0x11, 0x14, 0x74, 0x10, -0xD0, 0x01, 0x40, 0x04, 0x08, 0x1D, 0x05, 0x74, 0x80, 0xD2, 0x41, 0x41, 0x04, -0x00, 0x11, 0x04, 0x4C, 0x40, 0x10, 0x01, 0xC0, 0x05, 0x00, 0x1D, 0x14, 0x74, -0x00, 0x10, 0x21, 0x42, 0x07, 0x08, 0x5D, 0x00, 0x74, 0x00, 0x50, 0x05, 0x40, -0x73, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x00, 0x81, -0x04, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x04, 0x34, 0x52, 0xD0, -0x09, 0x62, 0x21, 0x00, 0x8D, 0x10, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x25, 0x00, -0x91, 0x04, 0x54, 0x12, 0x50, 0x08, 0x48, 0x23, 0x80, 0x8D, 0x04, 0x14, 0x02, -0xD2, 0x08, 0x48, 0x23, 0x20, 0x8D, 0x20, 0x74, 0x02, 0x18, 0x08, 0x40, 0x4B, -0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x25, 0x00, 0x91, 0x00, -0x74, 0x0A, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, -0x00, 0x25, 0x80, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, -0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, -0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x76, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x6F, 0x00, 0x93, 0x02, 0x78, -0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0, -0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x48, 0x21, 0x40, 0x81, 0x00, -0x54, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x1C, 0x02, 0xB0, 0x09, -0xC0, 0xE7, 0x81, 0x9F, 0x02, 0x78, 0x42, 0x32, 0x29, 0xC0, 0x17, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA5, 0x00, 0x9F, 0x04, 0x7C, 0x26, -0xF1, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x26, -0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0x4C, -0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xBC, 0x09, 0xC0, -0x67, 0x01, 0x9F, 0x09, 0x7C, 0x02, 0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x4D, 0x00, 0xF0, -0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x00, -0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xE2, 0x07, 0x08, 0x1B, 0x00, 0x4C, 0x00, -0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x41, 0xC8, 0x87, -0x40, 0x17, 0x00, 0x7C, 0x00, 0x34, 0x01, 0x87, 0x40, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x80, 0x54, 0x80, 0x5D, 0x00, 0x44, 0x01, 0x70, 0x45, -0x40, 0x1C, 0x00, 0x5B, 0x00, 0x74, 0x01, 0x70, 0x07, 0x60, 0x9C, 0x00, 0x51, -0x00, 0x74, 0x01, 0xD8, 0x05, 0xC0, 0x1F, 0x00, 0x55, 0x00, 0x1E, 0x01, 0x72, -0x05, 0x40, 0x17, 0x08, 0x53, 0x00, 0xCC, 0x0D, 0xC0, 0x07, 0xC0, 0xDD, 0x01, -0x70, 0x0A, 0xF0, 0x35, 0x10, 0x17, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0xA0, 0x36, 0x10, 0xCD, 0x00, 0x16, 0x03, 0x50, 0x0C, 0x40, -0x62, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x58, 0x98, 0x48, 0xF3, 0x06, 0xCD, 0x00, -0x34, 0x03, 0xD2, 0x0D, 0x40, 0xB3, 0x01, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C, -0x40, 0x33, 0x80, 0xC9, 0x00, 0x14, 0x0A, 0x90, 0x34, 0x40, 0xE3, 0x01, 0x81, -0x02, 0x74, 0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x88, 0xB8, 0x11, 0xED, 0xA5, 0x96, 0x13, 0x50, 0x5E, 0x40, 0x9C, -0x01, 0xE9, 0x08, 0xB4, 0x03, 0x50, 0x0B, 0x40, 0x5F, 0x00, 0xE9, 0x04, 0xB4, -0x13, 0xD8, 0x0E, 0x40, 0x3D, 0x00, 0xF5, 0x00, 0x96, 0x13, 0x50, 0x0E, 0x40, -0x7F, 0x03, 0xE1, 0x05, 0x90, 0x0B, 0xD0, 0x26, 0x60, 0x6D, 0x00, 0xE1, 0x82, -0xB4, 0x02, 0x90, 0x1E, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0x10, 0xF8, 0x00, 0xFD, 0x07, 0x9C, 0x17, 0x70, 0x1F, 0xC0, 0xFA, 0x01, -0xE3, 0x01, 0xB4, 0x17, 0x70, 0x1E, 0x50, 0x6B, 0x00, 0xED, 0x05, 0xBC, 0x47, -0xD0, 0x9E, 0x68, 0x7B, 0x08, 0xEB, 0x01, 0x84, 0x17, 0x70, 0x1E, 0xC0, 0x7B, -0x00, 0xFB, 0x09, 0x9C, 0x07, 0xF0, 0x1E, 0x80, 0x6B, 0x00, 0xE6, 0x21, 0xFC, -0x06, 0xB0, 0x1B, 0xC0, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA8, 0x35, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0x70, 0x89, 0xC0, 0x17, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC0, 0x24, 0x18, 0xD7, 0x00, 0x7C, 0xB3, 0xF0, -0x4D, 0xC2, 0x23, 0x00, 0xC7, 0x92, 0x7C, 0x4B, 0x70, 0x0D, 0xC0, 0xB3, 0x04, -0xDB, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0x80, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02, -0x70, 0x01, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -0x79, 0x00, 0xE3, 0x04, 0xCD, 0x53, 0x70, 0x1B, 0xC0, 0x7F, 0x40, 0xF2, 0x01, -0xDC, 0x67, 0xF0, 0x1B, 0xC0, 0x6F, 0x00, 0xEF, 0x19, 0xCC, 0x07, 0x30, 0x1F, -0x85, 0x7F, 0x00, 0xF3, 0x11, 0xFC, 0x67, 0x70, 0x1F, 0xC0, 0x7D, 0x00, 0xF7, -0x01, 0xCD, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0xC1, 0xF4, 0x07, 0xF2, -0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, -0x00, 0xE1, 0x00, 0xAC, 0x03, 0x10, 0x0A, 0x40, 0x1B, 0x00, 0xE1, 0x08, 0xDC, -0xC3, 0x11, 0x0A, 0xC0, 0x09, 0x09, 0xED, 0x00, 0x94, 0x23, 0x50, 0x0E, 0x42, -0x1B, 0x00, 0xE1, 0x04, 0xDC, 0x03, 0x10, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00, -0x84, 0x2B, 0xD0, 0x86, 0x40, 0x2B, 0x06, 0x6D, 0x08, 0xB4, 0x11, 0xD0, 0x4F, -0xC0, 0x56, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, -0xF1, 0x00, 0xC4, 0x23, 0x50, 0x8E, 0x41, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x03, -0x59, 0x8A, 0x41, 0x2A, 0x30, 0xFD, 0x10, 0xE6, 0x03, 0x90, 0x0E, 0x40, 0x3F, -0x06, 0xE1, 0x20, 0xA6, 0x03, 0x51, 0x0F, 0x40, 0x39, 0x02, 0xED, 0x00, 0xA4, -0x43, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0A, 0x40, -0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x25, 0x02, 0xC1, -0x09, 0x24, 0x07, 0x10, 0x08, 0x60, 0x53, 0x0E, 0xC1, 0x0A, 0x34, 0x07, 0x12, -0x08, 0x41, 0xA3, 0x20, 0xCD, 0x02, 0x34, 0x1F, 0x50, 0x3C, 0x40, 0x43, 0x00, -0xD1, 0x0B, 0x14, 0x37, 0x10, 0x3C, 0x40, 0x74, 0x00, 0xCD, 0x05, 0x24, 0x17, -0xD1, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x26, 0x34, 0x18, 0xD0, 0x00, 0x42, 0x12, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x40, 0xF3, 0x00, -0xCD, 0x1B, 0x70, 0x2D, 0xC0, 0xB3, 0x00, 0xF3, 0x8A, 0xFC, 0x0B, 0x70, 0x18, -0xC0, 0x26, 0x04, 0xFE, 0x01, 0xEC, 0x4F, 0xB0, 0x5F, 0xC0, 0x27, 0x40, 0xF3, -0x00, 0xFC, 0x0B, 0x70, 0x9C, 0xC0, 0xBD, 0x02, 0xE7, 0x06, 0x6C, 0x0F, 0xD0, -0x05, 0xC0, 0xE7, 0x00, 0x8D, 0x06, 0x7E, 0x00, 0xF0, 0x01, 0xD0, 0x56, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x04, 0xDF, 0x00, 0x7C, -0x43, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x70, 0x29, 0xC0, -0x05, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0xA7, 0x88, 0xDF, 0x00, -0x7C, 0x03, 0x72, 0x8D, 0xC0, 0x37, 0x82, 0xDF, 0x00, 0x5C, 0x0B, 0xB0, 0x25, -0x88, 0xA7, 0x09, 0x9F, 0x02, 0x7C, 0x0C, 0xF0, 0x01, 0xC1, 0x05, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xFB, 0x00, 0xFC, 0x03, -0xF0, 0x0F, 0xC1, 0x5F, 0x08, 0xF3, 0x00, 0xFC, 0x43, 0xF0, 0x03, 0xC2, 0x2C, -0x0C, 0xFF, 0x10, 0xF8, 0x83, 0xF0, 0x0F, 0xC1, 0x0D, 0x04, 0xFB, 0x90, 0xCC, -0x03, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0xF7, 0x40, 0xE8, 0x03, 0xD0, 0x27, 0xC0, -0x6F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x13, 0x22, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x08, 0xD1, 0x00, 0x74, 0x83, 0xD0, -0x09, 0x60, 0x16, 0x0A, 0xD1, 0x00, 0x74, 0x03, 0xD2, 0x15, 0x40, 0x64, 0x00, -0xDD, 0x00, 0x5C, 0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x04, 0xDD, 0x00, 0x44, 0x03, -0xD8, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x07, 0xC0, 0x25, 0x42, 0xE3, -0xC0, 0x13, 0x05, 0x44, 0x4E, 0xD0, 0x31, 0x40, 0x17, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xA2, 0x64, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x09, -0x48, 0x37, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x41, 0x45, 0x20, 0xDD, -0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x64, 0x03, 0xD0, -0x0D, 0x40, 0x36, 0x00, 0xD5, 0x00, 0x76, 0x07, 0xD0, 0x05, 0x40, 0xB7, 0x01, -0x91, 0x01, 0x44, 0x04, 0xD2, 0x39, 0x42, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, -0x33, 0x08, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x09, 0x40, 0x40, 0x00, 0xCD, 0x00, -0x14, 0x03, 0xD0, 0x0C, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0D, -0x40, 0x30, 0x00, 0xD1, 0x00, 0x16, 0x83, 0xD0, 0x04, 0x40, 0x13, 0x10, 0x01, -0x00, 0x05, 0x00, 0xD0, 0x08, 0x60, 0x43, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xB0, 0x26, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x48, 0x13, -0x40, 0xD3, 0x80, 0x7C, 0x03, 0xF1, 0x01, 0xD0, 0x04, 0x00, 0xDE, 0x00, 0xFC, -0x03, 0x72, 0x0F, 0xC4, 0x05, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xD0, 0x0D, 0xC0, -0x3E, 0x00, 0xE7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x37, 0x88, 0x11, 0x00, -0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xA8, 0x2F, 0x10, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x0B, 0xC0, 0x1E, 0x00, -0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x0E, 0x00, 0xFF, 0x00, 0x9C, 0x03, -0xF0, 0x0F, 0xC8, 0x0B, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0x40, 0x3F, -0x00, 0xFF, 0x00, 0xEC, 0x01, 0xF0, 0x0B, 0xC2, 0x1F, 0x08, 0x37, 0x00, 0xFC, -0x00, 0xE1, 0x03, 0xC0, 0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA0, 0x2F, 0x00, 0x3B, 0x14, 0xBC, 0x0F, 0x34, 0x1F, 0xC0, 0x7E, 0x02, 0xFF, -0x09, 0xFC, 0x07, 0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0x8C, 0x27, 0x72, -0x1F, 0xC4, 0x7E, 0x02, 0xFB, 0x29, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x20, -0xF3, 0x09, 0xCC, 0x27, 0x30, 0x83, 0xC2, 0x7C, 0x02, 0xF3, 0x24, 0xEE, 0x1A, -0x30, 0x4B, 0xC4, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, -0x27, 0x20, 0x01, 0x02, 0x74, 0x13, 0x18, 0x11, 0x40, 0x00, 0x00, 0x1D, 0x80, -0x74, 0x04, 0x40, 0x11, 0x40, 0x00, 0x04, 0x11, 0x00, 0x44, 0x10, 0x10, 0x40, -0x40, 0x00, 0x00, 0x11, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x41, 0x44, 0x00, 0x13, -0x44, 0x44, 0x10, 0x30, 0x65, 0x40, 0x34, 0x00, 0xF5, 0x0B, 0x6E, 0x10, 0x10, -0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x02, -0x40, 0x01, 0x40, 0x36, 0x03, 0x50, 0x0D, 0x50, 0x30, 0x01, 0xCD, 0x84, 0x34, -0x03, 0x81, 0x0D, 0x50, 0x30, 0x01, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x0C, 0x41, -0x30, 0x01, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x4D, 0x40, 0x34, 0x00, 0xC9, 0x04, -0x24, 0x03, 0x10, 0x28, 0x40, 0x31, 0x81, 0xCD, 0x20, 0x04, 0x1A, 0x11, 0x88, -0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x15, 0x00, -0x11, 0x22, 0x34, 0x03, 0x50, 0x01, 0x44, 0x04, 0x00, 0x1D, 0x00, 0x74, 0x80, -0x90, 0x01, 0x40, 0x04, 0x00, 0x01, 0x00, 0x24, 0x00, 0x90, 0x01, 0x40, 0x04, -0x00, 0x01, 0x00, 0x67, 0x00, 0xD0, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x64, -0x00, 0x10, 0x4D, 0x42, 0x36, 0x08, 0xDD, 0x00, 0x47, 0x04, 0x10, 0x19, 0x41, -0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x40, 0x1B, -0x01, 0x7C, 0x27, 0x50, 0x0C, 0xC8, 0x34, 0x20, 0xDF, 0x80, 0x3C, 0x03, 0xB4, -0x0C, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, -0xD3, 0x00, 0x6C, 0x03, 0xF2, 0x0C, 0x80, 0x30, 0x00, 0xDB, 0x00, 0x6D, 0x03, -0x34, 0x01, 0xD1, 0x35, 0x00, 0xDF, 0x40, 0x44, 0x04, 0x22, 0x31, 0xC0, 0x01, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x01, 0x3F, 0x03, -0xF8, 0x03, 0xB0, 0x03, 0x80, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x03, -0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDD, 0x00, 0x70, 0x03, 0xD0, 0x0D, 0x00, 0x37, -0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, -0x07, 0xC0, 0x3D, 0x20, 0xF7, 0x00, 0xF4, 0x00, 0xF5, 0x03, 0xC3, 0x1E, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x81, 0x37, 0x0A, 0x4D, -0x03, 0x30, 0x0D, 0xC0, 0x77, 0x41, 0xD3, 0x05, 0x5C, 0x03, 0x30, 0x8D, 0xC0, -0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x01, -0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x34, 0x02, 0xD7, 0x01, 0x7C, 0x03, 0xF0, 0x09, -0xC0, 0x37, 0x00, 0xDF, 0x10, 0x74, 0x8A, 0x33, 0x21, 0xC4, 0x0B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x11, 0x81, 0x44, 0x03, -0x10, 0x41, 0x44, 0x47, 0x00, 0x11, 0x03, 0x74, 0x00, 0xB0, 0x11, 0x40, 0x04, -0x00, 0x11, 0x20, 0x74, 0x00, 0x14, 0x01, 0x48, 0x04, 0x00, 0x10, 0x01, 0x44, -0x44, 0xD0, 0x11, 0x40, 0x44, 0x08, 0x11, 0x01, 0x64, 0x00, 0xD0, 0x0D, 0xC0, -0x37, 0x10, 0xE0, 0x13, 0x34, 0x04, 0x10, 0x30, 0x00, 0x4F, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x41, 0x00, 0x25, 0x03, 0x50, -0x1C, 0x40, 0xB3, 0x00, 0xC9, 0x02, 0x34, 0x43, 0x90, 0x0C, 0x41, 0x35, 0x80, -0xC1, 0x00, 0x34, 0x03, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xC1, 0x00, 0x34, 0x07, -0x50, 0x8C, 0x40, 0x71, 0x80, 0xC9, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x36, -0x08, 0xC4, 0x02, 0x34, 0x02, 0x54, 0x28, 0x02, 0x1F, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x40, 0x61, 0x09, 0xE4, 0x07, 0x10, 0x12, -0x40, 0x4B, 0x00, 0x29, 0x09, 0xB4, 0x24, 0x90, 0x92, 0x40, 0x48, 0x00, 0x21, -0x01, 0xF6, 0x24, 0x10, 0x12, 0x40, 0x4A, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD0, -0x13, 0x40, 0x4D, 0x08, 0x29, 0x09, 0xA6, 0x04, 0xC0, 0x12, 0x40, 0x7B, 0x30, -0xE9, 0x01, 0xB4, 0x66, 0x50, 0x12, 0x41, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x10, 0x04, 0x40, 0x45, 0x00, 0x2C, 0x03, 0x70, 0x8C, 0xC0, -0x33, 0x00, 0xCB, 0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x31, 0x90, 0xC3, 0x00, -0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x32, 0x00, 0xD3, 0x00, 0x34, 0x03, 0x70, 0x0C, -0xC0, 0x31, 0x00, 0xCE, 0x80, 0x3E, 0x03, 0xF0, 0x00, 0xC0, 0x37, 0x00, 0xC7, -0x08, 0x3C, 0x22, 0x70, 0x08, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xB0, 0x1D, 0x00, 0x7F, 0x00, 0xDE, 0x03, 0xF0, 0x03, 0x60, 0x0F, -0x00, 0x37, 0x00, 0xBC, 0x20, 0xF0, 0x02, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4, -0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00, 0xCD, 0x00, 0xF0, 0x02, 0xC0, -0x0A, 0x00, 0x37, 0x80, 0xEE, 0x04, 0xF0, 0x03, 0xC0, 0x3D, 0x82, 0xF7, 0x38, -0xBC, 0x22, 0xB0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0x37, 0x40, 0x13, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x40, -0xD3, 0x01, 0x0D, 0x03, 0xB0, 0x1C, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x07, -0xB4, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x0D, 0x07, 0x30, 0x0D, 0xC0, 0x37, -0x00, 0xDF, 0x01, 0x6D, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x80, 0xDF, 0x04, 0x3C, -0x00, 0x30, 0x19, 0xC0, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x88, 0x39, 0x00, 0x31, 0x00, 0x85, 0x03, 0xD0, 0x02, 0x40, 0x0F, 0x00, 0x31, -0x00, 0x84, 0x00, 0x30, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x10, -0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xA4, 0x00, 0x70, 0x02, 0x40, 0x0B, 0x00, -0x37, 0x00, 0x8C, 0x80, 0xD0, 0x0E, 0xC0, 0x39, 0x00, 0xED, 0x14, 0x9C, 0x00, -0x14, 0x03, 0xC0, 0x4A, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -0x79, 0x00, 0x29, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x01, -0x94, 0x07, 0x90, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x10, 0x1E, -0x40, 0x7B, 0x00, 0xED, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xED, -0x01, 0x84, 0x87, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x85, 0x94, 0x06, 0x55, -0x1B, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77, -0x02, 0x91, 0x10, 0x04, 0x06, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x01, 0x00, 0x14, -0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x0C, 0x00, 0x34, 0x00, 0x10, 0x00, 0x40, -0x03, 0x00, 0x0D, 0x00, 0x24, 0x00, 0x50, 0x01, 0x40, 0x03, 0x10, 0x05, 0x40, -0x04, 0x00, 0xD0, 0xEC, 0x40, 0x31, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0x50, 0x8C, -0x40, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x9D, 0x00, -0x7B, 0x87, 0x6C, 0x41, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x5C, 0x01, -0xB4, 0x05, 0xC8, 0x14, 0x10, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC4, 0x17, -0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C, -0x01, 0x70, 0x37, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x9E, 0x21, 0x50, 0xB7, 0x40, -0x5D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x04, 0x1F, -0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xE8, 0x00, 0x70, -0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, -0x3F, 0x00, 0xDC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x20, 0xDC, 0x00, -0xF0, 0x01, 0xE0, 0x05, 0x00, 0x1F, 0x00, 0x5E, 0x80, 0x90, 0x01, 0x80, 0x4A, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x26, 0x02, 0x93, 0x00, -0x5C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x16, 0x30, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93, -0x00, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30, -0x09, 0xC0, 0x24, 0x10, 0x9F, 0x80, 0x7E, 0x26, 0x30, 0x89, 0xC2, 0x43, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00, 0x91, 0x20, 0x44, -0x02, 0x90, 0x19, 0x44, 0xA7, 0x00, 0x91, 0x02, 0x34, 0x02, 0x10, 0x09, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x50, 0x20, 0x40, 0x91, 0x02, -0x74, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9F, 0x02, 0x34, 0x02, 0x10, 0x09, -0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x06, 0x14, 0x39, 0x40, 0x07, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02, -0xD0, 0x09, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x2F, -0x00, 0xBD, 0x00, 0xF4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xB1, 0x00, 0xF4, -0x22, 0xD0, 0x4B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x08, 0x40, -0x24, 0x00, 0x9D, 0x0A, 0x54, 0x03, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x05, 0x02, 0x90, -0x0A, 0x40, 0x6B, 0x00, 0xA1, 0x01, 0xF4, 0x02, 0x15, 0x0E, 0x42, 0x2B, 0x00, -0xAD, 0x00, 0xB4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xB6, 0x02, -0xD0, 0x0A, 0x40, 0x28, 0x00, 0xAD, 0x01, 0xF4, 0x02, 0x14, 0x48, 0x40, 0x20, -0x02, 0x8D, 0x04, 0x34, 0x12, 0x10, 0x4C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82, 0x02, 0x13, 0x0A, 0x5C, 0x28, 0xF0, 0x01, -0xC0, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F, -0x0A, 0x7C, 0x28, 0xD0, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0, -0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0xFC, 0x28, 0x30, 0xA1, 0xD0, 0x84, 0x10, -0x1F, 0x00, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x19, 0xB8, 0x3F, 0x02, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x21, 0x9F, -0x08, 0xFC, 0x23, 0xF8, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x19, 0xA0, 0x2F, 0x05, 0xA3, 0x8C, 0x5C, 0x02, 0x35, 0x0B, 0xC0, 0x2F, -0x02, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x0B, 0xE0, 0x25, 0x00, 0x9F, 0x00, 0x4D, -0x22, 0xF1, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, -0x2E, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0x30, 0xC9, 0xE2, 0x24, 0x80, 0xBF, 0xA0, -0xC8, 0x83, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x08, 0x03, 0x01, 0x11, 0x0C, 0x45, 0x40, 0x10, 0x01, 0x40, 0x03, 0x00, -0x1D, 0x14, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x04, 0x1D, 0x10, 0x44, 0x00, -0xD0, 0x41, 0x41, 0x04, 0x01, 0x0D, 0x04, 0x74, 0x00, 0xD0, 0x01, 0x41, 0x04, -0x10, 0x0D, 0x54, 0x74, 0x10, 0x50, 0xC1, 0x50, 0x04, 0x24, 0x1D, 0x00, 0x45, -0x00, 0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA0, 0x23, 0x05, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D, -0x04, 0x34, 0x02, 0x50, 0x08, 0x40, 0x20, 0x01, 0x8D, 0x00, 0x14, 0x02, 0xD0, -0x49, 0x50, 0x20, 0x05, 0x8D, 0x04, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x22, 0x00, -0x8D, 0x04, 0x34, 0x52, 0x50, 0x58, 0x40, 0x21, 0x01, 0x8D, 0xA8, 0x04, 0x82, -0x10, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, -0x25, 0x40, 0x91, 0x02, 0x44, 0x22, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00, -0x74, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x56, 0x02, 0xC0, 0x09, -0x40, 0x24, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0xDD, -0x00, 0x34, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x06, 0x02, 0x14, -0x49, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0xA3, -0x00, 0x93, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0x50, 0x08, 0x50, 0x25, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0xF2, 0x09, 0xC8, -0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x9D, 0x00, -0x7C, 0x02, 0x34, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x80, 0x4C, 0x0A, 0x20, 0x09, -0xC1, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x02, -0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC4, 0x27, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x10, 0x64, -0x02, 0xB0, 0x08, 0xC0, 0x27, 0x00, 0x8F, 0x10, 0x7C, 0x0A, 0xF0, 0x09, 0xC2, -0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x85, 0x20, 0x13, -0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x90, 0xE2, -0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x6C, 0x00, 0xD0, 0x01, 0xC0, 0x07, 0x00, -0x1F, 0x08, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x13, 0x00, 0x4C, 0x00, -0xF0, 0x01, 0xC0, 0x05, 0x08, 0x1D, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x50, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x02, 0x51, 0x81, -0x45, 0x01, 0x70, 0x15, 0x40, 0x5F, 0x01, 0x71, 0x00, 0x84, 0x0D, 0x10, 0x97, -0x40, 0x17, 0x00, 0x5D, 0x00, 0x70, 0x01, 0x98, 0x04, 0x40, 0x17, 0x00, 0x7D, -0x00, 0x44, 0x01, 0x70, 0x05, 0x40, 0x57, 0x00, 0x7B, 0x03, 0x44, 0x01, 0xC0, -0x05, 0x40, 0x17, 0x10, 0x7C, 0x02, 0x74, 0x01, 0x10, 0x07, 0x00, 0x50, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x00, 0xD1, 0x00, 0x44, -0x03, 0x50, 0x88, 0x40, 0x73, 0x40, 0xC5, 0x08, 0x04, 0x0B, 0x50, 0x2C, 0x40, -0x33, 0x00, 0xDD, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x10, -0x25, 0x02, 0x50, 0x1D, 0x40, 0x63, 0x00, 0xC1, 0x0A, 0x25, 0x03, 0xD0, 0x0C, -0x60, 0x33, 0x00, 0x4D, 0x0B, 0x34, 0x02, 0x50, 0x0C, 0x00, 0x50, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x04, 0xB1, 0x02, 0x84, 0x33, -0x50, 0x0E, 0x40, 0x5B, 0x00, 0x65, 0x01, 0x84, 0x43, 0x10, 0x0A, 0x41, 0x3B, -0x01, 0xED, 0x04, 0xB4, 0x23, 0x90, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x01, 0xA4, -0x03, 0x50, 0x2E, 0x40, 0x7B, 0x00, 0xE9, 0x21, 0xA6, 0x03, 0xD0, 0x4E, 0x40, -0x3B, 0x01, 0x69, 0x00, 0xB4, 0x03, 0x58, 0x1C, 0x44, 0x10, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x02, 0xE3, 0x01, 0x9C, 0x27, 0x71, -0x1E, 0xC0, 0x7B, 0x20, 0xF7, 0x01, 0x8D, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x00, -0xED, 0x05, 0xAC, 0x87, 0xD0, 0x3E, 0xC0, 0x7B, 0x02, 0xEF, 0x01, 0xAC, 0x07, -0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xAC, 0x97, 0xF0, 0x9E, 0xE0, 0x7B, -0x20, 0x6D, 0x21, 0xBC, 0x07, 0x74, 0x1E, 0xC2, 0x50, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xB0, 0xBD, 0x40, 0x9F, 0x06, 0x7C, 0x03, 0x70, 0x0D, -0xC0, 0x17, 0x00, 0x5B, 0x00, 0x3C, 0x02, 0x70, 0x09, 0xC0, 0x37, 0x04, 0xDF, -0x02, 0x7C, 0x0B, 0xF0, 0x2D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x60, -0x0D, 0xC0, 0x33, 0x00, 0x9F, 0x00, 0x5C, 0x0B, 0xF0, 0xAD, 0xC0, 0x37, 0x00, -0x1F, 0x00, 0x3C, 0x5B, 0xB0, 0x09, 0xC2, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xA0, 0x4F, 0x40, 0xB3, 0x03, 0xCC, 0x13, 0xF0, 0x1E, 0xC0, -0x6C, 0x00, 0xBF, 0x01, 0x8C, 0x06, 0x30, 0x1B, 0xC0, 0x7B, 0x04, 0xF3, 0x13, -0xCC, 0x0F, 0x30, 0x3F, 0xC0, 0x7F, 0x04, 0xFF, 0x81, 0xFC, 0x87, 0xB0, 0x1F, -0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xFC, 0x4F, 0xF0, 0x1F, 0xC0, 0x7C, 0x04, 0x7F, -0x09, 0xCC, 0x06, 0x30, 0x9D, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x88, 0x09, 0x00, 0xA1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x08, -0x04, 0x2D, 0x44, 0x84, 0x02, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xC4, -0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xAD, 0x10, 0xB4, 0x03, 0x10, 0x0E, 0x40, -0x3B, 0x00, 0xAD, 0x10, 0xBC, 0x23, 0xD0, 0x0E, 0xC0, 0x3A, 0x00, 0x6D, 0x08, -0x84, 0x03, 0x11, 0x3E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x11, 0x00, 0x81, 0x00, 0x84, 0x63, 0xD0, 0x0F, 0x40, 0x2A, 0x00, -0xAD, 0x00, 0xC6, 0x02, 0x10, 0x0A, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x84, 0x23, -0x10, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x10, 0x0E, 0x40, 0x3B, -0x02, 0x6D, 0x08, 0xB4, 0x03, 0xD0, 0x0C, 0x40, 0x38, 0x02, 0xCD, 0x48, 0x86, -0x03, 0x50, 0x8E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x28, 0x13, 0x00, 0x81, 0x42, 0x06, 0x07, 0xD0, 0x4C, 0x40, 0x42, 0x01, 0x0D, -0x0D, 0x04, 0x0E, 0x10, 0x68, 0x40, 0x73, 0x00, 0xC1, 0x01, 0x04, 0x43, 0x10, -0x1C, 0x41, 0x33, 0x04, 0x0D, 0x05, 0x34, 0x43, 0x18, 0x38, 0x40, 0x73, 0x00, -0x1D, 0x05, 0x16, 0x2B, 0xD1, 0x0C, 0x50, 0x30, 0x08, 0x0D, 0x00, 0x40, 0x0B, -0x58, 0x28, 0x41, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, -0x21, 0x11, 0xD1, 0x02, 0xCC, 0x07, 0xF0, 0x2C, 0xC0, 0xF6, 0x00, 0xDF, 0x02, -0x4D, 0x44, 0x34, 0x1D, 0xC0, 0x3F, 0x00, 0xE3, 0x04, 0xC4, 0x07, 0x30, 0x0F, -0x40, 0x7B, 0x00, 0x1F, 0x03, 0x3C, 0x0B, 0x30, 0x9D, 0x40, 0xB7, 0x04, 0x5F, -0x03, 0xB4, 0x07, 0xF0, 0x0F, 0x00, 0x3C, 0x00, 0xDF, 0x00, 0x4C, 0x22, 0x72, -0x3D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x87, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x8D, 0xC0, 0x37, 0x22, 0xDF, 0x00, 0x7C, 0x23, 0xF0, 0x8D, 0xC0, -0x37, 0x02, 0x1F, 0x02, 0x7C, 0x07, 0x70, 0x8D, 0xC0, 0x37, 0x01, 0x5F, 0x40, -0x7C, 0x43, 0xF0, 0x1D, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x7C, 0x07, 0x96, 0x1D, -0x40, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x2F, 0x80, -0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x1F, 0xC0, 0x9C, 0x20, 0x7F, 0x00, 0xCC, 0x51, -0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x20, 0xCC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F, -0x80, 0x33, 0x00, 0xFC, 0x03, 0x31, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xCC, -0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x00, 0xFF, 0xA0, 0x4C, 0x83, 0x30, 0x17, 0xC2, -0x07, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x20, 0x46, 0x01, 0xC1, -0x09, 0x45, 0x03, 0xD0, 0x1D, 0x40, 0xC4, 0x10, 0x1D, 0x5B, 0x04, 0x1F, 0x50, -0x75, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40, -0x11, 0x02, 0x74, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x20, 0x1D, 0x02, 0x6C, 0x03, -0xB0, 0x0D, 0x40, 0x35, 0x10, 0x8D, 0x07, 0x54, 0x03, 0x14, 0x3D, 0x40, 0x87, -0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0x99, 0x00, -0x44, 0x03, 0xD0, 0x8D, 0x40, 0x34, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x50, 0x1D, -0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xD1, -0x08, 0x74, 0x07, 0x90, 0x0D, 0x40, 0x37, 0x02, 0x9D, 0x00, 0x44, 0x03, 0x10, -0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x65, 0x02, 0x10, 0x8D, 0x40, 0x07, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x04, 0x00, 0x91, 0x80, 0x04, -0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x50, 0x0C, 0x40, -0x37, 0x00, 0xD1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00, -0x64, 0x03, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x65, 0x03, 0x90, 0x0C, -0x40, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x03, 0x10, 0x4C, 0x40, 0x43, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x0E, 0x00, 0xBB, 0x40, 0xCC, 0x03, -0xF0, 0x0D, 0xC0, 0x14, 0x00, 0x4F, 0x00, 0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x3F, -0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3F, 0x00, 0x51, 0x00, 0x7C, -0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x10, 0x5F, 0x40, 0xCC, 0x03, 0x30, 0x0F, 0xC0, -0x34, 0x00, 0x9F, 0x20, 0xCC, 0x03, 0x30, 0x05, 0xC2, 0x07, 0x40, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, -0xEF, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F, 0x80, 0xBC, 0x03, -0x70, 0x0B, 0xC0, 0x3F, 0x10, 0x3F, 0x80, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, -0x20, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00, 0xFF, 0x01, 0xCC, 0x27, 0xE0, 0x1F, -0xC0, 0x7C, 0x02, 0xFB, 0x01, 0xBE, 0x0F, 0x11, 0x3F, 0xC0, 0x7C, 0x82, 0xF3, -0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0xFF, 0x00, 0xFB, 0x01, 0xDC, 0x07, 0x30, -0x9F, 0xC0, 0x5E, 0x02, 0xB3, 0x84, 0xEC, 0x31, 0xF0, 0x1F, 0xE4, 0x7F, 0x00, -0xFF, 0xC1, 0xEC, 0x24, 0xB0, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x08, 0x07, 0x00, 0x1D, 0x10, 0x69, 0x00, 0xF1, 0x11, 0x40, -0x00, 0x20, 0x11, 0x01, 0x74, 0x00, 0x10, 0x01, 0x40, 0x00, 0x01, 0x17, 0x01, -0x74, 0x04, 0xD0, 0x11, 0x40, 0x04, 0x20, 0x1D, 0x01, 0x44, 0x84, 0xB0, 0x01, -0x40, 0x15, 0x01, 0xD5, 0x09, 0x44, 0xB3, 0xD0, 0x1F, 0x42, 0x7F, 0x00, 0xFD, -0x01, 0x04, 0x10, 0x10, 0x19, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x84, 0x00, 0x13, 0xD0, 0x0D, 0x40, 0x30, -0x21, 0xC9, 0x00, 0x30, 0x13, 0x10, 0x4D, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x34, -0x83, 0xC0, 0x0D, 0x00, 0x30, 0x01, 0xCD, 0x60, 0x40, 0x03, 0x92, 0x4C, 0x40, -0x20, 0x00, 0x85, 0x00, 0x14, 0x01, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xC5, 0x00, -0x44, 0x10, 0x91, 0x0D, 0x64, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA8, 0x05, 0x00, 0x1D, 0x00, 0x46, 0x80, 0x50, 0x01, 0x40, 0x04, 0x00, -0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x15, 0x00, 0x74, 0x00, -0xD0, 0x01, 0x50, 0x04, 0x08, 0x1D, 0x00, 0x54, 0x00, 0x98, 0x01, 0x40, 0x21, -0x00, 0x94, 0x00, 0x64, 0x11, 0xD0, 0x0D, 0x60, 0x37, 0x00, 0xDD, 0x00, 0x44, -0x06, 0x10, 0x09, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x88, 0x37, 0x00, 0xCF, 0x00, 0x44, 0x03, 0xD1, 0x0C, 0xD0, 0x34, 0x00, 0xDB, -0x00, 0x74, 0x03, 0x34, 0x0C, 0xD0, 0x30, 0x00, 0xD3, 0x80, 0x7C, 0x03, 0xF1, -0x0D, 0x40, 0x36, 0x08, 0xDB, 0x00, 0x1C, 0x03, 0xB0, 0x0D, 0xC2, 0xA6, 0x00, -0x87, 0x01, 0x7D, 0x01, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xCF, 0x00, 0x2D, 0x04, -0xB0, 0xD4, 0x40, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, -0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xF4, 0x00, 0xF0, 0x03, -0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xED, 0x40, 0xF0, 0x03, 0xC0, 0x3F, 0x08, 0xFF, -0x05, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3E, 0x20, 0xFF, 0x00, 0xFE, 0x00, 0xF0, -0x1B, 0xD0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, -0x04, 0xD3, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x34, 0x10, 0xD7, 0x08, 0x6E, -0xA3, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDB, 0x84, 0x7C, 0x83, 0xF0, 0x0D, 0xC0, -0x37, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xA6, 0x20, 0x97, 0x24, -0x6E, 0x09, 0xF0, 0x0D, 0xC0, 0x37, 0x28, 0xDF, 0x20, 0x7C, 0x02, 0x30, 0x2D, -0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xC4, 0x01, -0x11, 0x01, 0x74, 0x00, 0xD0, 0x01, 0xD0, 0x06, 0x00, 0x11, 0x01, 0x44, 0x04, -0x14, 0x51, 0x40, 0x07, 0x30, 0x11, 0x10, 0x5C, 0x00, 0xD9, 0x00, 0xC1, 0x45, -0x24, 0x0D, 0xAA, 0x64, 0x00, 0x70, 0x41, 0x40, 0x64, 0x00, 0x9B, 0x04, 0x74, -0x01, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x04, 0x5C, 0x6E, 0x10, 0x09, 0xC0, -0x4D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x80, 0xC1, -0x00, 0x34, 0x03, 0xD0, 0x8C, 0x40, 0x34, 0x00, 0xC5, 0x01, 0x44, 0x07, 0x92, -0x1C, 0x00, 0x33, 0x00, 0xC1, 0x02, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x73, 0x20, -0xCD, 0x23, 0x34, 0x27, 0xD0, 0x1D, 0x40, 0xF0, 0x04, 0x81, 0x03, 0x34, 0x01, -0xD0, 0x0C, 0x40, 0x73, 0x00, 0xCD, 0x05, 0x34, 0x0D, 0x10, 0x08, 0x40, 0x1F, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x4C, 0x00, 0x21, 0x01, -0xB4, 0x04, 0xD0, 0x13, 0x40, 0x48, 0x00, 0x21, 0x01, 0xC4, 0x04, 0x98, 0x52, -0x44, 0x4B, 0x00, 0x21, 0x05, 0x94, 0x04, 0xD0, 0x12, 0x68, 0x4B, 0x00, 0x2D, -0x01, 0xB0, 0x04, 0x50, 0x12, 0x40, 0x79, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0, -0x1E, 0x40, 0x7B, 0x00, 0xED, 0xA1, 0x94, 0x27, 0x10, 0x9A, 0x40, 0x19, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC3, 0x00, 0x3C, -0x03, 0xF0, 0x8C, 0x40, 0x30, 0x20, 0xC7, 0x00, 0x05, 0x23, 0xB0, 0x5C, 0xC4, -0x33, 0x00, 0xC1, 0x05, 0x3C, 0x03, 0xD0, 0x0C, 0xC0, 0x33, 0x20, 0xCF, 0x88, -0x3C, 0x03, 0xF2, 0x0D, 0x50, 0xA0, 0x04, 0xC3, 0x00, 0x34, 0x03, 0xF0, 0x8C, -0xC0, 0x33, 0x06, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x88, 0xC4, 0x4B, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00, -0xF0, 0x82, 0xC0, 0x0F, 0x00, 0x2E, 0x08, 0xD4, 0x00, 0x71, 0x03, 0xC0, 0x07, -0x02, 0x17, 0x08, 0xFC, 0x00, 0xF0, 0x01, 0xC0, 0x0D, 0x00, 0x1D, 0x80, 0x64, -0x00, 0xF0, 0x11, 0xC0, 0x20, 0x02, 0xD8, 0x00, 0x7C, 0x03, 0xF0, 0x1F, 0xC0, -0x7F, 0x08, 0xFF, 0x01, 0xDC, 0x03, 0xF0, 0x8B, 0xC0, 0x0B, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x35, 0x10, 0xCE, 0x01, 0x6C, 0x03, 0xD0, 0x0C, 0xC0, 0x34, 0x20, -0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x73, 0x00, 0xD7, 0x00, 0x7C, 0x03, -0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0x70, 0x8D, 0xC0, 0x37, -0x02, 0xDF, 0x00, 0x7C, 0x07, 0x30, 0x1D, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xC0, 0x02, -0x40, 0x0B, 0x00, 0x2D, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x2D, -0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0xA4, 0x00, 0xD0, -0x02, 0x40, 0x3B, 0x00, 0xED, 0x02, 0x9C, 0x1B, 0xF0, 0x4E, 0x48, 0x3B, 0x01, -0xE9, 0x02, 0xB4, 0x03, 0x10, 0x0A, 0xC0, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x02, 0x79, 0x08, 0xED, 0x01, 0xB4, 0x07, 0xC0, 0x1E, 0x40, -0x7B, 0x00, 0xFD, 0x01, 0x84, 0x07, 0xD0, 0x1F, 0x40, 0x78, 0x10, 0xE4, 0x01, -0xB4, 0x07, 0x10, 0x1E, 0x08, 0x7F, 0x00, 0xE5, 0x01, 0xB4, 0x07, 0x40, 0x1E, -0x60, 0x6B, 0x04, 0xE5, 0x05, 0x94, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, -0x05, 0xB4, 0x07, 0x10, 0x1E, 0x44, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x28, 0x03, 0x80, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x44, 0x03, -0x00, 0x0D, 0x00, 0x04, 0x00, 0xD8, 0x01, 0x42, 0x05, 0x00, 0x08, 0x00, 0x34, -0x80, 0x52, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0x90, 0x00, 0x40, -0xE3, 0x00, 0xCD, 0x00, 0x04, 0x06, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC9, 0x00, -0x34, 0x0E, 0x1C, 0x08, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, -0x5F, 0x00, 0x45, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x7C, 0x01, -0x30, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F, -0x00, 0x4F, 0x00, 0xDC, 0x81, 0x78, 0x05, 0xC4, 0x17, 0x00, 0x5F, 0x80, 0xFC, -0x25, 0x30, 0x47, 0x40, 0x5E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x00, 0x8F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x08, 0x3F, -0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC0, 0x0F, 0x20, 0x3D, 0x00, 0xFC, 0x00, 0xF0, -0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0x40, 0x87, 0x01, -0x1F, 0x00, 0x5C, 0x20, 0x70, 0x00, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x20, -0xF0, 0x01, 0xE0, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, -0x67, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF8, 0x29, 0xC0, 0x27, 0x00, 0x93, 0x04, -0x7C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x97, 0x09, 0x4C, 0x02, 0xB0, 0x09, -0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x59, 0xC0, 0x24, 0x01, 0x9F, -0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x16, 0xF0, -0x09, 0xC8, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, -0x06, 0x9D, 0x20, 0x74, 0x06, 0xD8, 0x39, 0x44, 0x23, 0x20, 0x91, 0x01, 0x74, -0x06, 0xD0, 0x09, 0x40, 0x24, 0x08, 0x83, 0x01, 0x04, 0x02, 0x10, 0x09, 0x44, -0x27, 0x00, 0x9D, 0x10, 0x74, 0x06, 0xD0, 0x18, 0x50, 0xE4, 0x00, 0xBD, 0x00, -0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x2C, 0x01, 0xBD, 0x40, 0x74, 0x0E, 0xD2, 0x09, -0x42, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08, -0xBD, 0x00, 0xF4, 0x06, 0xD2, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x40, 0xF4, 0x12, -0x50, 0x8B, 0x40, 0x2C, 0x20, 0xBD, 0x00, 0xE4, 0x02, 0x90, 0x0B, 0x60, 0x2E, -0x00, 0xB5, 0x01, 0xF4, 0x0A, 0xD0, 0x0B, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x64, -0x13, 0xD2, 0x09, 0x40, 0x24, 0x80, 0x9D, 0x00, 0x74, 0x43, 0xD0, 0x09, 0x60, -0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x28, 0x00, 0xAD, -0x02, 0xB4, 0x0A, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB6, 0x0A, 0xD0, -0x2A, 0x50, 0x28, 0x02, 0xBD, 0x00, 0xE5, 0x0A, 0x10, 0x0A, 0x60, 0xAB, 0x00, -0xAD, 0x00, 0xB6, 0x02, 0xD0, 0x2B, 0x62, 0xA1, 0x00, 0x8D, 0x20, 0x04, 0x8A, -0xD2, 0x28, 0x40, 0x20, 0x88, 0x8D, 0x80, 0x34, 0x22, 0xD0, 0x28, 0x40, 0x43, -0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x87, 0x42, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01, -0xC0, 0x84, 0x00, 0x57, 0x00, 0x2C, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1F, -0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC2, 0x15, 0x00, 0x1F, 0x01, 0x4D, 0x04, 0xE0, -0x11, 0xD0, 0x44, 0x00, 0x1D, 0x01, 0x3C, 0x08, 0xF0, 0x00, 0xE2, 0x77, 0xC0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x0D, 0x9F, 0x01, 0x7C, -0x86, 0xF2, 0x09, 0xC0, 0x27, 0x10, 0x9D, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0x44, -0x27, 0x01, 0x93, 0x00, 0x5C, 0x06, 0xE0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x19, 0xC8, 0x6E, 0x00, 0xBF, 0x02, 0xF4, 0x0E, 0xF0, 0x39, -0xC0, 0xA7, 0x08, 0x9F, 0x02, 0xFC, 0x12, 0xF0, 0x1F, 0xC0, 0x67, 0x60, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB3, 0x02, 0xFC, 0x02, -0xD1, 0x0A, 0xC0, 0x27, 0x10, 0xBE, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x27, -0x02, 0xBF, 0x00, 0x74, 0x02, 0xF0, 0x0B, 0xC0, 0xAF, 0x00, 0xB7, 0x00, 0xDC, -0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0x00, 0xB3, 0x01, 0xBC, 0x46, 0x30, 0xD9, 0xC0, -0x6C, 0x01, 0xB3, 0x11, 0xC8, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1B, 0x05, 0x74, 0x14, 0xD0, -0x01, 0x40, 0x07, 0x04, 0x1D, 0x00, 0x74, 0x54, 0xD0, 0x11, 0x40, 0x07, 0x01, -0x1D, 0x00, 0x74, 0x54, 0xD0, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00, -0x90, 0x51, 0x40, 0x47, 0x05, 0x11, 0x20, 0x74, 0x14, 0x50, 0x31, 0x40, 0x85, -0x00, 0x11, 0x02, 0x54, 0x00, 0xD0, 0x50, 0x41, 0x73, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x01, 0x81, 0x00, 0x34, 0x42, 0xD0, 0x08, -0x40, 0x23, 0x00, 0xCD, 0x00, 0x14, 0x02, 0xD0, 0x48, 0x41, 0x23, 0x21, 0x8C, -0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x20, 0x94, 0x00, 0x14, 0x02, 0x90, -0x08, 0x40, 0x27, 0x00, 0x81, 0x02, 0x34, 0x52, 0x50, 0xC8, 0x40, 0x20, 0x02, -0x85, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x99, 0x20, 0x74, 0x02, 0xD0, 0x09, 0x40, -0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x80, -0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09, -0x00, 0xA7, 0x01, 0x91, 0x00, 0x70, 0x42, 0x50, 0x08, 0x40, 0x37, 0x00, 0x95, -0x00, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0x08, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0xFC, -0x02, 0xF0, 0x09, 0xC0, 0x2B, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x90, 0x0B, 0xC0, -0x2F, 0xC0, 0x93, 0x01, 0xFC, 0x2A, 0x71, 0x0B, 0xC8, 0x20, 0x40, 0x97, 0x40, -0x4C, 0x9E, 0xF0, 0x2B, 0x40, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x00, 0x25, 0x04, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE1, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF0, 0x09, 0xC4, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xB0, 0x09, 0xC2, 0x67, -0x00, 0x9F, 0x89, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9B, 0x80, 0x7C, -0x12, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x3A, 0x01, 0xD0, 0x06, 0x00, 0x13, -0x00, 0x6C, 0x00, 0xF2, 0x01, 0xC0, 0x04, 0x80, 0x13, 0x28, 0x7C, 0x00, 0xB2, -0x01, 0xD0, 0x05, 0x40, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC2, 0x87, 0x00, -0x1F, 0x00, 0x0C, 0x08, 0x31, 0x01, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x88, -0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, -0xDC, 0x00, 0x5D, 0x40, 0x74, 0x11, 0x15, 0x57, 0xC0, 0x14, 0x10, 0x55, 0x40, -0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x7B, 0x00, 0x74, 0x01, 0x10, 0x05, -0x40, 0x54, 0x00, 0x6B, 0x02, 0xF4, 0x0D, 0x34, 0x05, 0x40, 0x9B, 0x00, 0x7D, -0x02, 0x6E, 0x01, 0xB0, 0x05, 0x40, 0x9C, 0x00, 0x7B, 0x1B, 0xC4, 0x05, 0x10, -0x05, 0xC8, 0x52, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF6, -0x82, 0xCD, 0x09, 0x34, 0x03, 0x10, 0x38, 0x40, 0x30, 0x00, 0x81, 0x00, 0x34, -0x03, 0xC0, 0x0C, 0x40, 0x30, 0x00, 0x45, 0x05, 0x34, 0x03, 0x90, 0x08, 0x40, -0x32, 0x02, 0xC1, 0x04, 0x34, 0x01, 0x18, 0x0C, 0x40, 0xE3, 0x03, 0x8D, 0x10, -0x24, 0x03, 0x10, 0x0C, 0x44, 0xA2, 0x01, 0x89, 0x03, 0x24, 0x1B, 0x1D, 0x0C, -0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x80, -0xAD, 0x44, 0xF4, 0x17, 0x10, 0x1A, 0x44, 0x7C, 0x00, 0xE5, 0x00, 0xB4, 0x12, -0xD2, 0x5A, 0x40, 0x7C, 0x01, 0xE9, 0x00, 0xF6, 0x17, 0x10, 0x1A, 0x40, 0x2A, -0x00, 0xE1, 0x00, 0xF4, 0x0F, 0x90, 0x0E, 0x40, 0x3B, 0x01, 0x8D, 0x11, 0xF4, -0x0B, 0x90, 0x8E, 0x40, 0x28, 0x04, 0xA9, 0x20, 0xA4, 0x0F, 0x10, 0x5E, 0x40, -0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, -0x21, 0xBC, 0x1E, 0x10, 0x1E, 0xC0, 0x78, 0x02, 0xE3, 0x01, 0xBC, 0x07, 0xD2, -0x5F, 0xC0, 0x78, 0x04, 0xE5, 0x01, 0xBC, 0x97, 0xB0, 0x1A, 0x60, 0x7E, 0x00, -0xE1, 0x01, 0xBC, 0x07, 0x19, 0x3E, 0xC0, 0x7B, 0x11, 0xAF, 0x01, 0xA6, 0x0E, -0x30, 0x1C, 0x88, 0x6A, 0x00, 0xAB, 0x01, 0xEC, 0x05, 0x30, 0x3E, 0xC0, 0x50, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x08, 0x9F, 0x00, -0x3C, 0x02, 0xF0, 0x0D, 0xC8, 0xB1, 0x01, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x89, -0xDA, 0x33, 0x02, 0xDC, 0x00, 0x3C, 0x23, 0xF0, 0x08, 0x80, 0x25, 0x00, 0x9F, -0x00, 0x3C, 0x03, 0x70, 0x09, 0x80, 0x17, 0x10, 0x9D, 0x00, 0x6C, 0x02, 0xC0, -0x0D, 0xC0, 0x21, 0x00, 0x8F, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC8, 0x43, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x11, 0xCC, -0x07, 0xB8, 0x0B, 0xC0, 0x7F, 0x04, 0xFF, 0x01, 0xED, 0x07, 0x30, 0x1F, 0xC0, -0x7F, 0x20, 0xEF, 0x09, 0x4C, 0x27, 0x30, 0x1B, 0xC0, 0x7D, 0x04, 0xFB, 0x01, -0x9C, 0x07, 0xB0, 0x9E, 0xC2, 0x5D, 0x04, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, -0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x08, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x19, 0x06, 0xF1, 0x40, 0xC4, 0x13, -0x39, 0x4A, 0x40, 0x3B, 0x01, 0xED, 0x00, 0xC4, 0x02, 0x10, 0x08, 0x48, 0x3B, -0x01, 0xC7, 0x02, 0x84, 0x77, 0x10, 0x0A, 0x40, 0x3C, 0x00, 0x61, 0x00, 0x84, -0x03, 0x40, 0x1E, 0x40, 0x39, 0x00, 0xAD, 0x84, 0xA4, 0x13, 0xF0, 0x0E, 0x40, -0x28, 0x00, 0xE5, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x00, 0xA1, 0x08, 0x84, 0x02, 0x01, -0x8A, 0x41, 0x3B, 0x10, 0xFD, 0x00, 0x84, 0x43, 0x10, 0x0E, 0x40, 0x3B, 0x20, -0xED, 0x02, 0x80, 0x17, 0x10, 0x0B, 0x41, 0x29, 0x00, 0xF1, 0x00, 0x94, 0x03, -0x10, 0x4F, 0x40, 0x1A, 0x00, 0xAD, 0x80, 0xB4, 0x42, 0xD0, 0x1E, 0x40, 0x20, -0x00, 0xE5, 0x00, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x28, 0x03, 0x00, 0x90, 0x02, 0x44, 0x0E, 0x10, 0x3C, -0x40, 0xB3, 0x02, 0xCD, 0x02, 0x06, 0x0E, 0x00, 0x38, 0x40, 0xF3, 0x01, 0xC9, -0x08, 0x04, 0x4F, 0x11, 0x68, 0x42, 0xA5, 0x02, 0x01, 0x0B, 0x04, 0x4B, 0x50, -0x08, 0x41, 0x13, 0x22, 0x8D, 0x81, 0x66, 0x1A, 0x52, 0x0C, 0x44, 0x20, 0x00, -0xC5, 0x80, 0x74, 0x08, 0xD0, 0x0C, 0x40, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0xA8, 0x65, 0x00, 0xD2, 0x01, 0x4C, 0x4F, 0x34, 0x18, 0xC0, -0x7F, 0x00, 0xDF, 0x03, 0x0C, 0x07, 0x30, 0x3D, 0xC1, 0xBF, 0x04, 0xCD, 0x01, -0x4D, 0x0B, 0x36, 0x2D, 0xE4, 0xB5, 0x02, 0x93, 0x02, 0x54, 0x42, 0x10, 0x19, -0xC0, 0x36, 0x00, 0xDD, 0x05, 0x74, 0x0F, 0xD0, 0x0D, 0xD0, 0x34, 0x00, 0x97, -0x20, 0x7C, 0x02, 0xF2, 0xBD, 0xD5, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0xA7, 0x20, 0x9F, 0x18, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x37, -0x01, 0xDE, 0x08, 0x7C, 0x03, 0xF4, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x02, 0x7C, -0x03, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x97, 0x82, 0x7C, 0x0B, 0x70, 0x8D, 0xE0, -0x35, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9D, 0x02, -0x7C, 0x2A, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x80, 0x0A, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x43, 0x70, 0x0F, 0xC1, 0x3C, 0x00, -0xFF, 0x15, 0xDC, 0x66, 0x30, 0x1B, 0xC0, 0x3F, 0x20, 0xFF, 0x00, 0xCC, 0x03, -0xF0, 0x9F, 0xC0, 0x3F, 0x00, 0x33, 0x10, 0xFC, 0x03, 0xE0, 0x0B, 0xC0, 0x7F, -0x10, 0xE3, 0x49, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0xBF, 0x00, 0xBF, 0x22, 0xFC, -0x40, 0x30, 0x0F, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, -0x20, 0x66, 0x00, 0x9D, 0x00, 0x44, 0x83, 0x10, 0x2D, 0x40, 0x34, 0x08, 0xDD, -0x40, 0x74, 0x02, 0x50, 0x09, 0x44, 0x37, 0x08, 0xDD, 0x03, 0x44, 0x03, 0xD0, -0x19, 0x68, 0x27, 0x80, 0x15, 0x13, 0x74, 0x47, 0xD2, 0x99, 0xC4, 0x51, 0x28, -0xD1, 0x03, 0x6C, 0x27, 0xF0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x7C, 0x2F, -0x11, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, -0x46, 0x04, 0xDD, 0x00, 0x44, 0x12, 0x12, 0x09, 0x41, 0x36, 0x00, 0xDD, 0x00, -0x74, 0x03, 0x12, 0x8D, 0x42, 0x37, 0x00, 0xDD, 0x01, 0x44, 0x03, 0xD0, 0x0D, -0x42, 0x37, 0x20, 0x91, 0x01, 0x74, 0x07, 0xD0, 0x09, 0x44, 0x17, 0x02, 0x95, -0x50, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x36, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x10, -0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, -0x00, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x08, 0x50, 0x32, 0x08, 0xCD, 0x00, 0x74, -0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xDD, 0x02, 0x04, 0x13, 0xD0, 0x08, 0x40, -0x36, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x61, 0x35, 0x40, 0x45, 0x80, -0x24, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x20, 0x34, 0x00, 0x10, 0x0C, -0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, -0x9F, 0x20, 0x4C, 0x02, 0x34, 0x01, 0xC0, 0x3E, 0x00, 0xDF, 0x00, 0x58, 0x82, -0x30, 0x09, 0xC0, 0x3F, 0x08, 0xDF, 0x02, 0x84, 0x43, 0xF0, 0x0D, 0x40, 0x27, -0x00, 0x11, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0x40, 0x17, 0x80, 0x97, 0x80, 0x4C, -0x02, 0x30, 0x0E, 0x80, 0x17, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x34, 0x0F, 0xC8, -0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBF, -0x40, 0xFC, 0x02, 0xB0, 0x07, 0xC0, 0x3D, 0x08, 0xEF, 0x00, 0xFC, 0x02, 0xF0, -0x4B, 0xC8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, -0x2F, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x1F, 0x00, 0x7B, 0x00, 0xF8, 0x02, -0xF0, 0x0F, 0xC2, 0x1F, 0x20, 0x7F, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC0, 0x17, -0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x6F, 0x00, 0x2F, 0x04, -0xCC, 0x06, 0x70, 0x43, 0xC1, 0x0F, 0x01, 0xE3, 0x01, 0xCC, 0x10, 0x74, 0x03, -0xC0, 0x0F, 0x00, 0x33, 0x10, 0xCC, 0x80, 0x30, 0x03, 0xD0, 0x0C, 0x00, 0x33, -0x04, 0xCC, 0x00, 0x34, 0x43, 0xC8, 0x7E, 0x02, 0xB3, 0x00, 0xFC, 0x53, 0xF0, -0x12, 0xC0, 0x6D, 0x02, 0xAF, 0x01, 0xFC, 0x06, 0xF0, 0x4B, 0xC0, 0x0F, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, 0x00, 0x1D, 0xAB, 0x44, -0x07, 0x10, 0x35, 0x48, 0xD7, 0x02, 0xD1, 0xA1, 0x44, 0x0D, 0x10, 0x35, 0x40, -0x57, 0x02, 0x51, 0x43, 0x4C, 0x0D, 0x10, 0xB5, 0x40, 0xD4, 0x02, 0x51, 0x03, -0x44, 0x0D, 0x10, 0x95, 0x40, 0x33, 0x11, 0xD1, 0x03, 0x74, 0x8F, 0xD0, 0x19, -0x40, 0x27, 0x01, 0x9D, 0x01, 0x74, 0x04, 0xD2, 0x11, 0x40, 0x07, 0x60, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA8, 0x23, 0x00, 0x0D, 0x00, 0x44, 0x03, -0x50, 0x08, 0x40, 0x21, 0x40, 0xC1, 0x00, 0x14, 0x0A, 0x18, 0x88, 0x40, 0x23, -0x00, 0x81, 0x00, 0x04, 0x0A, 0x50, 0x08, 0x48, 0x20, 0x00, 0x89, 0x08, 0x06, -0x0A, 0x10, 0x08, 0x40, 0x33, 0x01, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x40, -0x01, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x47, 0x80, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x02, 0x1D, 0xC0, 0x64, 0xC7, 0x10, -0x05, 0x44, 0x37, 0x02, 0xD1, 0x00, 0x56, 0x08, 0x10, 0x05, 0x40, 0xB7, 0x09, -0x91, 0x03, 0x64, 0x03, 0x50, 0x09, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x0E, -0x10, 0x09, 0x42, 0x37, 0x01, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x57, -0x00, 0xDD, 0x01, 0x74, 0x05, 0xD0, 0x19, 0x41, 0x0F, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA8, 0x27, 0x00, 0xDF, 0x5A, 0x0C, 0x0F, 0x70, 0x91, -0xC0, 0xC7, 0x04, 0xD3, 0x01, 0x5C, 0x24, 0x30, 0x11, 0xC2, 0xC7, 0x00, 0x13, -0x02, 0x4C, 0x00, 0x70, 0x21, 0xC1, 0xC4, 0x86, 0x13, 0x1B, 0x4C, 0x08, 0x30, -0x01, 0xC0, 0x36, 0x00, 0x93, 0x00, 0x7C, 0x03, 0xF0, 0x59, 0xC0, 0xE5, 0x00, -0x9F, 0x07, 0x7C, 0x16, 0xF0, 0x39, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0x80, 0x2D, 0x20, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x17, 0xC0, -0x4F, 0x00, 0xFD, 0x02, 0xEC, 0x01, 0xB0, 0x3F, 0xC0, 0x1A, 0x40, 0x6F, 0x00, -0x9C, 0x0D, 0xB0, 0x07, 0xC0, 0x5B, 0x20, 0x7F, 0x00, 0xFD, 0x01, 0xF0, 0x07, -0xC2, 0x7F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x7F, -0x00, 0xFC, 0x01, 0xF2, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x08, 0x25, 0x00, 0xD3, 0x13, 0x4C, 0x23, 0xF0, 0x09, 0xD0, 0xA0, -0x00, 0xDF, 0x11, 0x1C, 0x0A, 0x70, 0x09, 0xE0, 0x27, 0x00, 0x1F, 0x02, 0x4C, -0x2A, 0x30, 0x2C, 0xC0, 0xA7, 0x02, 0x83, 0x02, 0x0D, 0x02, 0xF0, 0x2D, 0x41, -0x74, 0x01, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x29, 0xC0, 0x94, 0x00, 0x9F, 0x0E, -0x4C, 0x0A, 0xF0, 0x29, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0xA0, 0x64, 0x01, 0x81, 0x22, 0x44, 0x03, 0xD0, 0xB5, 0x40, 0xE4, 0x02, -0xCD, 0x02, 0x44, 0x28, 0xD0, 0xAD, 0x41, 0xB7, 0x06, 0x1D, 0x1A, 0x44, 0x07, -0x12, 0xAD, 0x42, 0xB7, 0x00, 0x91, 0x0B, 0x6C, 0x2A, 0xD0, 0x0D, 0x41, 0xB5, -0x08, 0xD1, 0x01, 0xC4, 0x83, 0xD0, 0x0D, 0xC0, 0x14, 0x00, 0xD1, 0x01, 0x44, -0x99, 0xD0, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x20, 0xE2, 0x01, 0x01, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40, 0x00, 0x28, 0xCD, -0x00, 0x20, 0x24, 0x80, 0x10, 0x40, 0x43, 0x00, 0x0D, 0x01, 0x06, 0x90, 0x10, -0x90, 0x40, 0x43, 0x04, 0x01, 0x00, 0x24, 0x24, 0xD0, 0x10, 0x40, 0x34, 0x00, -0x81, 0x80, 0x24, 0x83, 0x90, 0x08, 0x40, 0x20, 0x00, 0x01, 0x02, 0x04, 0x42, -0xD1, 0x00, 0x43, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, -0x6A, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x98, 0x43, 0x58, 0x00, 0xED, 0x01, -0xB4, 0x07, 0xD0, 0x12, 0x40, 0x6B, 0x00, 0x4C, 0x01, 0x04, 0x04, 0x10, 0x1E, -0x40, 0x63, 0x00, 0xC1, 0x11, 0x84, 0x05, 0xD0, 0x14, 0x50, 0x78, 0x00, 0xE1, -0x01, 0xA4, 0x07, 0xD0, 0x0B, 0x40, 0x7A, 0x12, 0xB1, 0x01, 0x85, 0x06, 0xD0, -0x12, 0x48, 0x13, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x22, -0x00, 0x03, 0x08, 0x1C, 0x03, 0xF0, 0xA8, 0xC8, 0x00, 0x84, 0xCF, 0x00, 0x3C, -0x83, 0x70, 0x0C, 0x40, 0x13, 0x00, 0xCE, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, -0x13, 0x10, 0x43, 0x00, 0x24, 0x01, 0xF0, 0xE0, 0xC0, 0x30, 0x40, 0x83, 0x18, -0x2C, 0x03, 0xF0, 0x88, 0xC0, 0x24, 0x40, 0x47, 0x08, 0x0C, 0x03, 0xF0, 0x00, -0xC1, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x39, 0x40, -0xFF, 0x00, 0xFC, 0x03, 0xF1, 0x8B, 0xC0, 0x1F, 0x20, 0xFF, 0x00, 0xCC, 0x03, -0xF8, 0x07, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x8B, 0xC0, 0x3F, -0x00, 0xFF, 0x08, 0xFC, 0x01, 0xF0, 0x83, 0xE0, 0x3F, 0x00, 0xAF, 0x00, 0xDD, -0x43, 0xF0, 0x4F, 0xC0, 0x1D, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x83, 0xC0, -0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x67, 0x00, 0x53, -0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0xF0, -0x01, 0xC0, 0x07, 0x00, 0x93, 0x80, 0x7C, 0x07, 0x32, 0x01, 0xC2, 0x44, 0x00, -0x13, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x03, -0xF0, 0x09, 0xC0, 0x57, 0x00, 0x53, 0x80, 0x7C, 0x01, 0x30, 0x19, 0xC0, 0x40, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xE1, 0x00, -0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A, -0x40, 0x23, 0x40, 0xE1, 0x00, 0x36, 0x03, 0x04, 0x0C, 0x40, 0x28, 0x40, 0xE1, -0x20, 0x04, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x13, 0xD0, -0x0A, 0x40, 0x3B, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xB1, 0x02, 0x40, 0x48, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0x61, 0x01, 0xB4, -0x07, 0xD0, 0x1C, 0x44, 0x78, 0x00, 0xE5, 0x11, 0xB6, 0x07, 0x50, 0x1E, 0x40, -0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0x10, 0x16, 0x40, 0x50, 0x00, 0x41, 0x01, -0x84, 0x07, 0x14, 0x3E, 0x40, 0x7F, 0x00, 0xE1, 0x01, 0x94, 0x07, 0xD0, 0x1A, -0x40, 0xDF, 0x00, 0x61, 0x01, 0xF4, 0x07, 0x10, 0x18, 0x50, 0x10, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC1, 0x13, 0x34, 0x01, -0xD0, 0x9C, 0x40, 0xB0, 0x04, 0x8D, 0x01, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x33, -0x00, 0xC1, 0x02, 0x34, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04, -0x03, 0x10, 0x2C, 0x40, 0x63, 0x02, 0xC5, 0x08, 0x34, 0x03, 0xD0, 0xAC, 0x41, -0xD3, 0x00, 0x41, 0x62, 0x34, 0x85, 0x90, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x57, 0x04, 0x73, 0x07, 0xBC, 0x09, 0xF0, -0x07, 0xD0, 0x9E, 0x04, 0x57, 0x00, 0xFC, 0x01, 0xF0, 0x87, 0xE0, 0x1F, 0x00, -0x73, 0x02, 0xFC, 0x1D, 0x30, 0x17, 0xD1, 0x1C, 0x00, 0x73, 0x00, 0xCD, 0x01, -0x30, 0x27, 0xC0, 0x17, 0x00, 0x53, 0x01, 0x5C, 0x01, 0xF0, 0x17, 0xC0, 0x1F, -0x00, 0x63, 0x07, 0xBC, 0x05, 0x30, 0x77, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x0F, 0x00, 0x7C, 0x40, 0xF0, 0x01, -0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, -0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04, 0xF0, -0x01, 0xC1, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x44, -0x1F, 0x06, 0x7C, 0x24, 0xF0, 0x41, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x08, 0xE0, -0x20, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x10, -0x4C, 0x02, 0xF0, 0x08, 0xC0, 0x24, 0x00, 0x8F, 0x00, 0x0C, 0x02, 0x70, 0x08, -0xC0, 0x64, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, -0x08, 0x4C, 0x22, 0x30, 0x59, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x80, 0x44, 0x02, 0x10, 0x09, 0x10, 0x24, -0x40, 0x91, 0x00, 0x74, 0x02, 0x14, 0x09, 0xD0, 0x24, 0x50, 0x91, 0x40, 0x4D, -0x02, 0xD0, 0x09, 0x50, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x14, 0x09, 0x50, -0x64, 0x42, 0x91, 0x00, 0x74, 0x06, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x01, -0x54, 0x06, 0x54, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, -0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x00, 0x26, 0x00, 0x99, 0x00, 0x44, 0x03, -0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40, 0x20, -0x00, 0x91, 0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00, 0x44, -0x42, 0x11, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x28, 0x20, 0x00, 0x8D, 0x04, 0x05, 0x02, 0x10, 0x48, 0x40, 0x20, 0x01, 0x81, -0x00, 0x34, 0x12, 0x10, 0x48, 0x44, 0x20, 0x01, 0x89, 0x04, 0x04, 0x12, 0xD0, -0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x04, 0x12, 0x10, 0x48, 0x40, 0x60, 0x00, -0x81, 0x04, 0x34, 0x12, 0x50, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x54, 0x02, -0x50, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, -0x06, 0x00, 0x1F, 0x00, 0x44, 0x00, 0x34, 0x01, 0x40, 0x04, 0x00, 0x13, 0x00, -0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x1B, 0x20, 0x4C, 0x00, 0xF0, 0x01, -0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x84, 0x02, 0x13, -0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x5F, 0x80, 0x4C, 0x00, 0x32, -0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2B, -0x00, 0xBF, 0x28, 0xFD, 0x02, 0xF1, 0x8B, 0xC0, 0x2F, 0x0A, 0xBF, 0x20, 0xFC, -0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02, 0xB7, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC0, -0x2F, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0xF2, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08, -0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF1, 0x8B, -0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, -0x9F, 0x84, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x52, -0x30, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x49, 0xC0, 0x24, -0x05, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x2C, 0x02, 0xB3, 0x04, 0xCC, -0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF2, 0x0B, 0xC0, -0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x1D, -0x28, 0x74, 0x80, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0x10, -0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74, 0xA0, 0x12, 0x01, 0x40, 0x04, 0x00, -0x1D, 0x88, 0x74, 0x08, 0xD0, 0x03, 0x40, 0x04, 0x40, 0x11, 0x20, 0x45, 0x00, -0xD0, 0x01, 0x40, 0x16, 0x14, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x73, -0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x29, 0x00, 0xAD, 0x00, -0xB4, 0x02, 0xD0, 0x9A, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x06, 0x10, 0x1A, -0x40, 0x6B, 0x02, 0xAD, 0x09, 0xB4, 0x06, 0x10, 0x9A, 0x48, 0x68, 0x20, 0xAD, -0x01, 0xB0, 0x26, 0xD0, 0x9A, 0x40, 0x20, 0x00, 0x81, 0x08, 0x04, 0x0A, 0xD0, -0x08, 0x40, 0x23, 0x01, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x18, 0x40, 0x4B, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x65, 0x00, 0xBD, 0x00, 0xF4, -0x8A, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, -0x6F, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x6C, 0x00, 0xBD, 0x00, -0xF4, 0x12, 0xD0, 0x0B, 0x50, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02, 0xD0, 0x09, -0x40, 0x26, 0x02, 0x9D, 0x02, 0x74, 0x0A, 0xD0, 0x19, 0x40, 0x63, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26, -0xF0, 0x29, 0xC8, 0xA7, 0x40, 0x91, 0x00, 0x7C, 0x2A, 0x34, 0x39, 0xC0, 0xA7, -0x00, 0x9F, 0x0B, 0x7C, 0x0A, 0x34, 0xA9, 0xD0, 0xA4, 0x00, 0x9F, 0x03, 0x7C, -0x0A, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x39, 0xC1, -0xA7, 0x00, 0x9F, 0x82, 0x7C, 0x0E, 0xF0, 0x29, 0xC0, 0x17, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x08, 0x9F, 0x00, 0x78, 0x06, 0xF0, -0x09, 0x80, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x00, -0x9F, 0x01, 0x3C, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x06, -0xF0, 0x98, 0xC0, 0x27, 0x01, 0x8F, 0x01, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27, -0x00, 0x9F, 0x28, 0x7C, 0x66, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x0D, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xF0, 0x03, -0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0C, 0x00, 0x3F, -0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xB0, -0x03, 0xC0, 0x44, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, -0x1F, 0x12, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x5D, 0x20, 0x40, 0x01, 0x70, 0x05, 0x40, -0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x5D, 0x20, -0x74, 0x01, 0xD2, 0x05, 0x48, 0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x30, 0x05, -0xC0, 0x1E, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x7D, -0x03, 0xF4, 0x4D, 0x50, 0x17, 0x50, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0xA0, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x40, 0x03, -0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40, 0x02, 0x00, 0x0D, 0x00, 0x36, -0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x09, 0x00, 0x30, 0x00, 0x14, 0x00, 0x40, -0x34, 0x08, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00, -0x34, 0x09, 0x10, 0x8C, 0x41, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x88, 0x38, 0x00, 0xCD, 0x01, 0x84, 0x03, 0x50, 0x0E, 0x40, 0x3B, 0x00, -0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x40, 0x3A, 0x00, 0xED, 0x00, 0xB4, 0x03, -0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x07, 0x10, 0x0E, 0x40, 0x2A, -0x00, 0xAD, 0x00, 0xB4, 0x42, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x42, 0xB4, -0x05, 0x50, 0x1E, 0x40, 0x05, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, -0x10, 0x48, 0x00, 0x2F, 0x01, 0x8D, 0x84, 0x70, 0x12, 0xC0, 0x4B, 0x00, 0x2F, -0x01, 0xBC, 0x04, 0x72, 0x10, 0xD0, 0x4A, 0x08, 0x2D, 0x21, 0xB4, 0x04, 0xF0, -0x12, 0xC0, 0x4B, 0x00, 0x2F, 0x01, 0xBC, 0x04, 0x30, 0x12, 0xC0, 0x58, 0x00, -0xAF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x03, 0xEF, 0x01, 0xBC, 0x05, -0x30, 0x1E, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, -0x35, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, -0x0C, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x4D, -0x00, 0x3F, 0x01, 0xCC, 0x20, 0xF0, 0x13, 0xC0, 0x4C, 0x00, 0x3F, 0x01, 0xCC, -0x04, 0xF0, 0x13, 0xC0, 0x4E, 0x00, 0x33, 0x01, 0xCC, 0x84, 0xF0, 0x13, 0xC2, -0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x04, 0xF0, 0x13, 0xC0, 0x7C, 0x00, 0xBF, 0x01, -0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x04, 0x73, 0x01, 0x8C, 0x07, 0x30, 0x17, -0xC0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x08, -0xED, 0x00, 0x84, 0x03, 0xF0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x30, 0x94, 0x03, -0xD0, 0x0E, 0x50, 0x38, 0x42, 0xE1, 0x08, 0x85, 0x23, 0xD0, 0x0E, 0x40, 0x3B, -0x00, 0xED, 0x08, 0xB4, 0x03, 0xF0, 0x0E, 0x40, 0x08, 0x00, 0xAD, 0x00, 0xB4, -0x03, 0xF0, 0x0E, 0xC0, 0x3B, 0x00, 0x21, 0x00, 0xAC, 0x12, 0xB0, 0x5E, 0x40, -0x57, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x2D, -0x18, 0x84, 0x20, 0xD8, 0x00, 0x40, 0x08, 0x00, 0x3D, 0x00, 0x84, 0x00, 0xD0, -0x00, 0x40, 0x80, 0x00, 0x01, 0x00, 0x94, 0x00, 0xD0, 0x22, 0x40, 0x8B, 0x20, -0x2D, 0x08, 0xB4, 0x00, 0xD0, 0x10, 0x40, 0x18, 0x04, 0xAD, 0x00, 0xB4, 0x02, -0xD0, 0x0F, 0x40, 0x38, 0x00, 0x61, 0x10, 0x84, 0x43, 0x18, 0x4E, 0x40, 0x03, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x00, 0xCD, 0x06, -0x06, 0x0B, 0x50, 0x2C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0xD0, 0x0C, -0x44, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x02, 0x34, 0x03, 0x50, 0x0C, 0x50, 0x50, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x50, -0x7C, 0x40, 0xF3, 0x00, 0x81, 0x03, 0x24, 0x16, 0x90, 0x2D, 0x40, 0x13, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x05, 0x00, 0x1F, 0x01, 0x4C, -0x28, 0xD0, 0x11, 0xD0, 0x44, 0x00, 0x1F, 0x00, 0x4C, 0x04, 0xF0, 0x31, 0xC0, -0x44, 0x00, 0x13, 0x01, 0x5C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00, 0x1F, 0x01, -0x7C, 0x04, 0xD0, 0x00, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x3C, 0x02, 0xD0, 0x0D, -0xC1, 0xB8, 0x01, 0x43, 0x03, 0x4C, 0x05, 0x30, 0xBD, 0xC0, 0x57, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x77, 0x00, 0xDF, 0x20, 0x7D, 0x87, -0xF0, 0x1D, 0xC1, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x77, -0x10, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x73, 0x00, 0xDF, 0x81, 0x7C, -0x07, 0xF0, 0x1D, 0xC0, 0x27, 0x10, 0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, -0x35, 0x44, 0x5F, 0x10, 0x7C, 0x0B, 0xF2, 0x3D, 0xC4, 0x07, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0F, 0x00, 0x13, 0x00, 0xFC, 0x80, 0x30, -0x03, 0xC0, 0x0B, 0x00, 0x33, 0x00, 0xBC, 0x40, 0x30, 0x02, 0xC1, 0x0C, 0x08, -0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x32, 0x10, 0xFC, 0x80, -0xF0, 0x03, 0xC0, 0x0C, 0x00, 0xEF, 0x09, 0xCC, 0x02, 0x30, 0x0F, 0xC0, 0x3F, -0x00, 0xB3, 0x00, 0xCC, 0x00, 0x30, 0x5F, 0xC0, 0x10, 0x22, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x85, 0x20, 0x32, 0x00, 0xD1, 0x00, 0x34, 0x03, 0x92, 0x0D, -0x42, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xDD, -0x00, 0x76, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40, 0xD1, 0x00, 0x64, 0x03, 0xD2, -0x0D, 0xC0, 0x24, 0x08, 0x9D, 0x01, 0x44, 0x02, 0x14, 0x0D, 0x40, 0x37, 0x00, -0x95, 0x93, 0x14, 0x0C, 0x10, 0x4D, 0x40, 0x15, 0x02, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xA0, 0x04, 0x00, 0x11, 0x40, 0x74, 0x00, 0x90, 0x01, 0x40, -0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, -0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01, -0x40, 0x76, 0x80, 0xD9, 0x00, 0x44, 0x03, 0x18, 0x0D, 0x40, 0x37, 0x00, 0xD1, -0x21, 0x54, 0x0D, 0x12, 0x0D, 0x48, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x28, 0x34, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x94, 0x0C, 0x40, 0x33, -0x00, 0xC1, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, -0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48, -0x00, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x20, 0x15, 0x00, -0x54, 0x02, 0x11, 0x0D, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40, -0x13, 0x00, 0x7C, 0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00, 0x74, 0x00, -0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xD0, 0x04, -0x10, 0xDF, 0x00, 0x4C, 0x02, 0x30, 0x0D, 0xC0, 0x3B, 0x00, 0x93, 0x00, 0x4C, -0x02, 0x32, 0x45, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xA0, 0x3F, 0x40, 0xFF, 0x80, 0xFC, 0x03, 0x51, 0x0F, 0xC0, 0x3F, 0x00, 0xEF, -0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0D, 0x10, -0xBD, 0x20, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xAF, 0x80, 0xFD, 0x02, -0xF0, 0x29, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, -0x2F, 0x01, 0x73, 0x01, 0xFC, 0x11, 0x34, 0x33, 0xC0, 0x1E, 0x01, 0xB3, 0x14, -0xCC, 0x07, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x80, 0xCC, 0x27, 0xF0, 0x83, -0xC0, 0x78, 0x00, 0x23, 0x01, 0xCC, 0xB3, 0xF0, 0x4B, 0xC0, 0x1A, 0x21, 0x73, -0x01, 0xEC, 0x10, 0xF2, 0x13, 0xC0, 0x3C, 0x05, 0x7F, 0x01, 0xFC, 0x05, 0xF0, -0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xF7, -0x00, 0xD1, 0x81, 0x74, 0x25, 0x12, 0x0D, 0x40, 0xD4, 0x02, 0x91, 0x03, 0x44, -0x87, 0xD0, 0x39, 0x80, 0xFE, 0x02, 0x9D, 0x03, 0x44, 0x13, 0xD0, 0x61, 0x40, -0x34, 0x44, 0x13, 0x81, 0xD4, 0x23, 0xD0, 0xB9, 0x40, 0xD4, 0x02, 0x91, 0x01, -0x44, 0x31, 0xD1, 0x11, 0x40, 0xFC, 0x00, 0x9D, 0x81, 0x34, 0x87, 0xD0, 0x1D, -0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xA3, 0x00, -0xC1, 0x00, 0x74, 0x01, 0x50, 0x4C, 0x40, 0x16, 0x00, 0xC5, 0x00, 0x04, 0x03, -0xD0, 0x20, 0x40, 0x30, 0x00, 0x8D, 0x02, 0x04, 0x13, 0xD0, 0x28, 0x40, 0x30, -0x01, 0x01, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x13, 0x00, 0x81, 0x80, 0x24, -0x42, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x50, 0x0C, 0x40, -0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x00, 0xD1, -0x00, 0x74, 0x01, 0x10, 0x1D, 0x40, 0x34, 0x04, 0x95, 0x00, 0x44, 0x13, 0xD0, -0x39, 0x60, 0x36, 0x00, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x74, 0x00, -0x59, 0x00, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x15, 0x00, 0x91, 0x10, 0x44, 0x63, -0xD0, 0x21, 0x40, 0x36, 0x00, 0x9D, 0x06, 0x74, 0x9B, 0xD8, 0x0D, 0x40, 0x0F, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0x23, 0x40, 0x93, 0x40, -0x3C, 0x3B, 0x71, 0x1D, 0xC0, 0xD2, 0x00, 0x97, 0x00, 0x4C, 0x07, 0xF0, 0x1D, -0xC0, 0x34, 0x00, 0x8F, 0x00, 0x4D, 0x03, 0xF0, 0x91, 0xD0, 0x34, 0x00, 0x11, -0x07, 0x4C, 0x03, 0xF0, 0x0C, 0xC0, 0x13, 0x46, 0x53, 0x00, 0x6C, 0x0C, 0xF0, -0x98, 0xE0, 0x36, 0x00, 0x5F, 0x00, 0x7C, 0x05, 0xE0, 0x0D, 0xC0, 0x0B, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x25, 0x00, 0xBF, 0x45, 0xFC, -0x05, 0xF0, 0x0F, 0xC0, 0x9F, 0x40, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, -0x3F, 0x10, 0xDF, 0x04, 0xFC, 0x03, 0xF0, 0x0C, 0xC0, 0x3F, 0x40, 0xB7, 0x04, -0xFC, 0x03, 0xF0, 0x0B, 0xC4, 0x7E, 0x00, 0xFF, 0x00, 0x7C, 0x84, 0xF0, 0x03, -0x70, 0x35, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x93, 0x01, 0x7C, 0x03, -0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xD3, 0x10, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x34, -0x00, 0x97, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0xDB, 0x10, 0x5C, -0x03, 0xF0, 0x0D, 0xC0, 0x96, 0x84, 0x93, 0x02, 0x7C, 0x08, 0xB4, 0x2D, 0xC0, -0x37, 0x00, 0xD7, 0x02, 0x7C, 0x02, 0xB0, 0x0D, 0xC0, 0x29, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0xE4, 0x01, 0x91, 0x00, 0x76, 0x05, 0xD0, -0x0D, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x3D, 0x01, -0xD1, 0x00, 0x44, 0x83, 0xDA, 0x0D, 0x40, 0x34, 0x00, 0xCB, 0x82, 0xC4, 0x43, -0xD1, 0x0D, 0xC0, 0x37, 0x10, 0x8B, 0x1A, 0x76, 0x00, 0x10, 0x05, 0x40, 0x3F, -0x00, 0x91, 0x00, 0x74, 0x03, 0xB0, 0x1D, 0xC0, 0x4F, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0x01, 0x00, 0x34, 0x05, 0xD0, 0x0D, -0x40, 0x33, 0x02, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x44, 0x30, 0x00, 0xC5, -0x00, 0x24, 0x03, 0xD0, 0x04, 0x40, 0x34, 0x00, 0x01, 0x00, 0x14, 0x07, 0xC0, -0x08, 0x40, 0xF0, 0x20, 0xC1, 0x03, 0x34, 0x00, 0x90, 0x04, 0x48, 0x33, 0x00, -0x80, 0x00, 0x36, 0x02, 0x50, 0x8C, 0x40, 0x4E, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0D, 0x80, 0x78, 0x20, 0xE1, 0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x60, -0x5B, 0x10, 0xA1, 0x81, 0xB4, 0x07, 0x50, 0x9B, 0x42, 0x79, 0x00, 0xA1, 0x01, -0xA4, 0x07, 0xD8, 0x12, 0x40, 0x7C, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xD0, 0x1A, -0x40, 0x5E, 0x04, 0xA9, 0x01, 0xB4, 0x05, 0x90, 0x52, 0x40, 0x7B, 0x00, 0xA1, -0x01, 0xB4, 0x06, 0x90, 0x1E, 0x40, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x10, 0x20, 0x00, 0x81, 0x00, 0x34, 0x01, 0xF2, 0x0C, 0xE0, 0x33, -0x40, 0xC3, 0x00, 0x3C, 0x03, 0xD0, 0x0D, 0xC0, 0x30, 0x00, 0xC6, 0x20, 0x24, -0x03, 0xD0, 0x4C, 0xC0, 0x30, 0x30, 0x83, 0x58, 0x1C, 0x03, 0xF0, 0x08, 0xC0, -0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0xB4, 0x0C, 0xC0, 0x33, 0x40, 0x87, 0x00, -0x3C, 0x02, 0x70, 0x0C, 0xC4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3B, 0x02, -0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0xB3, 0x00, 0xBF, 0x00, 0x5C, 0x03, -0xF0, 0x03, 0xD0, 0x3F, 0x00, 0xFF, 0x20, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x1F, -0x00, 0xBF, 0x00, 0xFC, 0x23, 0x70, 0x4B, 0xCA, 0xBF, 0x82, 0xBF, 0x00, 0xFC, -0x02, 0xF0, 0x0E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC2, 0x77, 0x00, 0x93, -0x80, 0x5C, 0x83, 0x70, 0x09, 0x80, 0xB5, 0x22, 0xD3, 0x00, 0x5C, 0x03, 0xF0, -0x05, 0xC0, 0x77, 0x20, 0x53, 0x00, 0x7C, 0x33, 0xE0, 0x0D, 0xC0, 0x37, 0x00, -0xDF, 0x00, 0x78, 0x03, 0xB0, 0x1D, 0xC0, 0x36, 0x81, 0xDF, 0x00, 0x4C, 0x02, -0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, -0xB9, 0x10, 0xAD, 0x40, 0x9C, 0x0B, 0xD3, 0x0E, 0x40, 0x13, 0x01, 0xE1, 0x00, -0x84, 0x03, 0xD0, 0x2A, 0x40, 0x30, 0x11, 0xE1, 0x22, 0xB4, 0x83, 0xD0, 0x0E, -0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x53, 0x80, 0x0A, 0x40, 0xBB, 0x00, 0xED, -0x00, 0x34, 0x03, 0x10, 0x0E, 0x60, 0x38, 0x08, 0xAD, 0x00, 0x94, 0x02, 0xD0, -0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79, -0x05, 0xAD, 0x03, 0xB4, 0x57, 0xD0, 0x1E, 0x40, 0x7B, 0x03, 0xC1, 0x09, 0x96, -0x47, 0xD0, 0x7C, 0x4C, 0x79, 0x60, 0xE1, 0x05, 0xB6, 0x07, 0xD0, 0x1E, 0x40, -0x7B, 0x00, 0xE1, 0x83, 0xB4, 0x07, 0xC0, 0xDE, 0x08, 0x7B, 0x01, 0xAD, 0x01, -0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x92, 0xED, 0x43, 0x84, 0x06, 0xD0, 0x1E, -0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33, 0x00, -0x8D, 0x40, 0x14, 0x02, 0xD0, 0x3D, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x04, 0x06, -0xD0, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0xD0, 0xEC, 0x60, 0x23, -0x00, 0xC1, 0x07, 0x34, 0x03, 0x91, 0x1C, 0x40, 0xA3, 0x09, 0x8D, 0x00, 0x34, -0x1F, 0x10, 0x3C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40, -0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x11, 0x10, 0x6F, -0x00, 0xBC, 0x21, 0xF0, 0x07, 0xC1, 0x1F, 0x40, 0x53, 0x00, 0x5C, 0x01, 0x72, -0x17, 0xC2, 0x15, 0x00, 0x52, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0, 0x17, 0x00, -0x73, 0x23, 0x7C, 0x01, 0xF2, 0x15, 0xC3, 0x9F, 0x01, 0x7F, 0x05, 0xFC, 0x1D, -0x34, 0x17, 0xC5, 0x16, 0x00, 0x7F, 0x40, 0xCC, 0x81, 0xE0, 0x05, 0xC0, 0x5F, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x20, 0x1F, 0x04, -0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC8, 0x07, 0x42, 0x1F, -0x02, 0x3C, 0x00, 0xB0, 0x01, 0xC2, 0x03, 0x00, 0x1F, 0x00, 0x3C, 0x00, 0x70, -0x01, 0xC0, 0x07, 0x00, 0x1B, 0x20, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27, 0x01, 0x9B, 0x01, 0x4C, -0x22, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xD0, -0x61, 0x00, 0x96, 0x04, 0x7C, 0x02, 0x70, 0x09, 0xC2, 0x24, 0x00, 0x9F, 0x00, -0x5C, 0x02, 0x78, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x02, 0x30, 0x49, -0xC9, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x91, 0x89, 0xC4, 0x06, -0x10, 0x09, 0x40, 0x6C, 0x00, 0xAD, 0x03, 0x44, 0x02, 0xD0, 0x0B, 0x42, 0x64, -0x00, 0xB1, 0x07, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA4, 0x82, 0x8D, 0x02, 0x44, -0x02, 0x10, 0x0B, 0x48, 0x2F, 0x00, 0x91, 0x40, 0x74, 0x02, 0xB0, 0x79, 0x40, -0x27, 0x00, 0x87, 0x00, 0x2C, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x04, 0x91, 0x00, 0x44, 0x02, 0x16, -0x0D, 0x60, 0x24, 0x01, 0x9D, 0x0A, 0x40, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x02, -0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x18, 0x54, 0x02, -0x50, 0x09, 0x41, 0x27, 0x00, 0x91, 0x00, 0x64, 0x02, 0x00, 0x09, 0x40, 0x27, -0x00, 0x98, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x88, -0x40, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00, 0x89, -0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x20, 0x02, 0x8D, 0x40, 0x00, 0x0A, 0x10, -0x08, 0x48, 0x23, 0x40, 0x81, 0x00, 0x34, 0x22, 0x98, 0x08, 0x40, 0x23, 0x20, -0x95, 0xC2, 0x64, 0x0A, 0x10, 0x08, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xB0, 0x46, 0x40, 0x13, 0x00, 0x4C, 0x04, 0x32, 0x21, 0xD0, -0x44, 0x00, 0x1F, 0x01, 0x4D, 0x00, 0xF0, 0x11, 0xC0, 0x05, 0x15, 0x1F, 0x01, -0x7C, 0x08, 0x70, 0x61, 0xD1, 0x80, 0x00, 0x1D, 0x00, 0x5C, 0x50, 0x50, 0x11, -0x40, 0x47, 0x00, 0x53, 0x40, 0x6C, 0x58, 0x30, 0x01, 0xC0, 0x07, 0x05, 0x0F, -0x00, 0x4D, 0x00, 0x34, 0x01, 0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x19, 0xB8, 0xAF, 0x08, 0xBF, 0x00, 0xFD, 0x0A, 0xF0, 0x4B, 0xC0, 0xAF, -0x00, 0xBF, 0x02, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xB3, 0x02, 0x7C, -0x12, 0xB1, 0x4B, 0x80, 0x2F, 0x01, 0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x2B, 0xC0, -0xAF, 0x08, 0xBF, 0x00, 0xF8, 0x12, 0xF2, 0x0A, 0xC4, 0x27, 0x00, 0xB7, 0x01, -0xDC, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0xA0, 0x6F, 0x00, 0xBF, 0x40, 0xC4, 0x56, 0xF0, 0x09, 0xC0, 0x6F, 0x01, -0xBF, 0x41, 0x7C, 0x02, 0x30, 0x79, 0xC0, 0x2C, 0x00, 0xFF, 0x31, 0x4C, 0x22, -0xF0, 0x49, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xB0, 0x5B, 0xC1, 0x6D, -0x14, 0xB3, 0x60, 0x4C, 0x52, 0x32, 0x0B, 0xC0, 0x27, 0x28, 0x9F, 0x02, 0x7C, -0x0A, 0xF0, 0x0B, 0xC6, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, -0x08, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x08, 0xD0, 0x01, 0x43, 0x97, 0x00, 0x1D, -0x02, 0x34, 0x54, 0x52, 0x75, 0x50, 0x84, 0x00, 0x1D, 0x02, 0x54, 0x00, 0x90, -0x41, 0x11, 0x04, 0x41, 0x11, 0x00, 0x74, 0x9C, 0x10, 0x21, 0x40, 0x84, 0x00, -0x51, 0x00, 0x54, 0x11, 0x50, 0x05, 0x00, 0x87, 0x10, 0x1D, 0x01, 0x74, 0x04, -0xD0, 0x01, 0x40, 0x73, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, -0xA3, 0x80, 0xDD, 0x00, 0x14, 0x02, 0xD0, 0x08, 0x40, 0xB3, 0x30, 0x8C, 0x02, -0x34, 0x02, 0x10, 0xC8, 0x40, 0x22, 0x02, 0x8D, 0x00, 0x04, 0x02, 0x50, 0xC8, -0x40, 0x20, 0x25, 0x80, 0x00, 0x34, 0x62, 0x92, 0x08, 0x60, 0x23, 0x00, 0x95, -0x00, 0x14, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x82, 0x8D, 0x00, 0x34, 0x02, 0xD0, -0x08, 0x40, 0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, -0x00, 0x9D, 0x22, 0x54, 0x02, 0xD0, 0x69, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x34, -0x02, 0x50, 0x09, 0x40, 0x26, 0x80, 0x9D, 0x00, 0x54, 0x82, 0x90, 0x08, 0x41, -0x20, 0x00, 0x91, 0x24, 0x76, 0x02, 0x10, 0x09, 0x40, 0x24, 0x02, 0xD5, 0x48, -0x14, 0x02, 0x50, 0x09, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x1A, 0xD0, 0x09, -0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, -0x8F, 0x82, 0x5D, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x02, -0x30, 0xAB, 0xC0, 0x26, 0x10, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x24, -0x00, 0x93, 0x04, 0xFC, 0x02, 0xB0, 0x18, 0xC8, 0x27, 0x40, 0x87, 0x00, 0x5C, -0x0A, 0x60, 0x29, 0xC0, 0x27, 0x00, 0xBF, 0x24, 0xFC, 0x02, 0xF0, 0x09, 0xC0, -0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F, -0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9E, 0x09, 0x7C, 0x0E, 0xF0, -0x08, 0xC0, 0x25, 0x80, 0x8F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0xA7, 0x14, -0x9F, 0x20, 0x3C, 0x02, 0x70, 0x59, 0xCA, 0x27, 0x08, 0x9B, 0x11, 0x7C, 0x02, -0xF8, 0x49, 0xC0, 0x27, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x4B, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x87, 0x00, 0x1B, 0x10, 0x7C, 0x00, 0x30, 0x21, -0xD0, 0x04, 0x02, 0x1F, 0x08, 0x4D, 0x00, 0xF0, 0x01, 0xE0, 0x04, 0x00, 0x17, -0x10, 0x4C, 0x00, 0xF0, 0x41, 0xC0, 0x02, 0x40, 0x13, 0x02, 0x4C, 0x08, 0xF2, -0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x1C, 0x00, 0x5D, 0x00, 0x70, -0x01, 0x18, 0x05, 0x48, 0x17, 0x00, 0x7C, 0x03, 0x74, 0x01, 0x10, 0x05, 0x50, -0x54, 0x00, 0x7C, 0x03, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x9C, 0x01, 0x7D, 0x41, -0x7C, 0x11, 0x70, 0x07, 0xC0, 0xDE, 0x01, 0x70, 0x03, 0x68, 0x01, 0x10, 0x37, -0x05, 0x14, 0x80, 0x5D, 0x00, 0x74, 0x01, 0xC0, 0x45, 0x40, 0x53, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20, 0x8D, 0x00, 0x30, 0x06, -0x10, 0x0C, 0x40, 0x23, 0x10, 0x8C, 0x08, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30, -0x00, 0x8D, 0x13, 0x24, 0x03, 0xC0, 0x0C, 0x40, 0xB0, 0x00, 0xCD, 0x00, 0x24, -0x03, 0x50, 0x38, 0x40, 0x20, 0x29, 0xC0, 0x0A, 0x04, 0x03, 0x90, 0x38, 0x01, -0x31, 0x00, 0xCD, 0x80, 0x36, 0x03, 0xC0, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x40, 0xB4, 0x0F, 0x10, -0x0E, 0x48, 0x3B, 0x00, 0xAD, 0x00, 0xB4, 0x23, 0x10, 0x4C, 0x40, 0x28, 0x00, -0xAD, 0x00, 0xA4, 0x03, 0xD0, 0x4E, 0x60, 0x38, 0x80, 0xFD, 0x03, 0xA4, 0x23, -0x50, 0x28, 0x40, 0x3A, 0x00, 0xF1, 0x00, 0x26, 0x23, 0x10, 0x1B, 0x40, 0x38, -0x00, 0xED, 0x04, 0xB4, 0x13, 0x90, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x3C, 0x07, 0x34, 0x3E, -0xC0, 0x7B, 0x00, 0xAF, 0x81, 0xBC, 0x07, 0x34, 0x7E, 0x40, 0x78, 0x00, 0xAD, -0x01, 0xA4, 0x1F, 0xF9, 0xBF, 0x40, 0x48, 0x00, 0xE7, 0x01, 0xAC, 0x17, 0x70, -0x16, 0xE0, 0x68, 0x00, 0xE3, 0x01, 0x8C, 0x57, 0xB0, 0x1E, 0xE0, 0x79, 0x00, -0xED, 0x03, 0xBE, 0x0F, 0xF0, 0x1E, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xB8, 0x25, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF1, 0x0D, 0x44, -0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0x8F, 0x00, -0x5C, 0x4B, 0xF0, 0x6D, 0xD0, 0x07, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0x70, 0x05, -0xC0, 0x33, 0x08, 0xCF, 0x00, 0x7C, 0x0B, 0x71, 0x0C, 0xC0, 0x37, 0x10, 0xDF, -0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA0, 0x6F, 0x00, 0xF3, 0x09, 0xFC, 0x83, 0x30, 0x9F, 0xC0, 0x7F, -0x02, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0x80, 0x7D, 0x00, 0xBF, 0x01, 0xFC, -0x27, 0x30, 0x1F, 0xC0, 0x7E, 0x22, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC0, -0x6C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xB0, 0x1B, 0xC0, 0x7F, 0x02, 0xEF, 0x09, -0x8C, 0x07, 0x30, 0x1F, 0xC0, 0x03, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x88, 0x39, 0x00, 0xE1, 0x80, 0xB0, 0x53, 0xB4, 0x0E, 0x46, 0x3B, 0x02, -0xE1, 0x80, 0xB4, 0x03, 0x70, 0x4E, 0x48, 0x39, 0x00, 0xAD, 0x04, 0xB4, 0x03, -0x10, 0x0E, 0x41, 0x38, 0x00, 0xED, 0x06, 0xB4, 0x02, 0x90, 0x0E, 0xC4, 0x39, -0x00, 0x2F, 0x00, 0xF4, 0x83, 0x10, 0x4A, 0x00, 0x3B, 0x08, 0xED, 0x20, 0xAC, -0x03, 0xF0, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x29, 0x04, 0xE1, 0x00, 0x30, 0x33, 0x18, 0x0E, 0x60, 0x33, 0xC0, 0xE9, -0x10, 0xB4, 0x27, 0xD0, 0x1F, 0x72, 0x3B, 0x00, 0xAD, 0x80, 0xB4, 0x03, 0x98, -0x0C, 0x40, 0x29, 0x20, 0xEC, 0x10, 0xA4, 0x02, 0xD0, 0x0E, 0x40, 0x2A, 0x00, -0xED, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x48, 0x3B, 0xA0, 0xFD, 0x11, 0xC4, 0x07, -0x10, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, -0x63, 0x00, 0xC1, 0x20, 0x34, 0x8B, 0x90, 0x1C, 0x40, 0xB3, 0x01, 0x49, 0x20, -0x34, 0x07, 0x50, 0x2C, 0x40, 0x31, 0x00, 0x8D, 0x01, 0x34, 0x03, 0x94, 0x1C, -0x64, 0x61, 0x00, 0x0D, 0x13, 0x74, 0x82, 0x90, 0x9C, 0x40, 0xF1, 0x00, 0x05, -0x03, 0x34, 0x03, 0x11, 0x1C, 0x40, 0x33, 0x10, 0xCD, 0x03, 0x04, 0x0B, 0x58, -0x0C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x65, -0x00, 0xC3, 0x04, 0x7C, 0x07, 0x10, 0x1F, 0x40, 0x37, 0x04, 0x8B, 0x01, 0x74, -0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x00, 0xDF, 0x11, 0xFC, 0x03, 0xB0, 0x2F, 0xC0, -0x35, 0x11, 0x5F, 0x03, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0xA6, 0x08, 0x9D, 0x04, -0xFC, 0x17, 0x54, 0x68, 0xC0, 0x37, 0x00, 0xDF, 0xC3, 0x45, 0x13, 0x15, 0x0D, -0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x40, -0xDF, 0x00, 0x7C, 0x13, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x23, -0xF0, 0x4D, 0xD0, 0x27, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x0D, 0x00, 0xB4, -0x08, 0x5F, 0x80, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x06, 0x9F, 0x02, 0x3C, -0x03, 0x50, 0x09, 0xC0, 0x33, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, -0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x27, 0x00, 0xFF, -0x90, 0xCD, 0x03, 0xF1, 0x0F, 0xC1, 0x3E, 0x00, 0xBF, 0x01, 0xCE, 0x03, 0x32, -0x0F, 0xE0, 0x2C, 0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x5F, 0x00, -0x7F, 0x01, 0xFC, 0x23, 0x38, 0x05, 0xE0, 0x2C, 0x01, 0x38, 0x90, 0xFC, 0x03, -0x30, 0x4B, 0xDD, 0x3D, 0x00, 0xF3, 0x10, 0xCC, 0x43, 0x78, 0x9F, 0xC0, 0x13, -0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x56, 0x00, 0xDD, 0x49, -0x44, 0x03, 0x70, 0x0C, 0x40, 0x74, 0x08, 0x9D, 0x00, 0x04, 0x03, 0xB0, 0x0D, -0xC0, 0x66, 0x80, 0x9D, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x15, 0x03, 0x1D, -0x23, 0x5C, 0x02, 0xB0, 0x04, 0x44, 0x25, 0x00, 0x1D, 0x41, 0x74, 0x03, 0x70, -0x09, 0x40, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xD0, 0x1D, 0x40, 0x17, 0x02, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD, 0x00, 0x44, -0x07, 0xD0, 0x0D, 0x60, 0x36, 0x02, 0x9D, 0x04, 0x44, 0x03, 0x10, 0x0C, 0x48, -0x34, 0x02, 0xDD, 0x06, 0x74, 0x03, 0xD0, 0x0D, 0x60, 0x07, 0x00, 0x9D, 0x44, -0x74, 0x03, 0x93, 0x0D, 0x40, 0xA4, 0x00, 0x9D, 0x01, 0x74, 0x03, 0x10, 0x29, -0x40, 0x34, 0x00, 0xC0, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x20, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xDD, 0x20, 0x04, 0x03, -0xD0, 0x0D, 0x40, 0x30, 0x80, 0x8D, 0x00, 0x45, 0x03, 0x99, 0x0C, 0x40, 0x30, -0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0x8D, 0x00, 0x10, -0x02, 0x90, 0x0C, 0x60, 0x11, 0x00, 0x0D, 0x00, 0x34, 0x03, 0x50, 0x08, 0x40, -0x30, 0x40, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x40, 0x43, 0xA1, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x03, 0xF8, -0x0D, 0xC0, 0x36, 0x00, 0xDF, 0x40, 0xC6, 0x03, 0x32, 0x0F, 0x50, 0x24, 0x20, -0x5D, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x07, 0x00, 0x9D, 0x00, 0x78, 0x03, -0x90, 0x0D, 0x40, 0x24, 0x08, 0x1F, 0x00, 0xFC, 0x03, 0x31, 0x05, 0xC0, 0x35, -0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x03, 0xC4, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x20, 0xFF, 0x00, 0xFC, 0x03, 0x7A, 0x0F, -0xC0, 0x3F, 0x00, 0x7C, 0x00, 0xFC, 0x03, 0xF3, 0x0F, 0xC0, 0x2F, 0x00, 0x7F, -0x00, 0xFC, 0x83, 0xF1, 0x0F, 0x80, 0x0D, 0x00, 0x3E, 0x00, 0xDC, 0x82, 0xF0, -0x0F, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x07, 0x40, 0x3F, 0x00, -0xF7, 0x00, 0xFC, 0x03, 0xF8, 0x0B, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x80, 0x5F, 0x00, 0x33, 0x8C, 0xCC, 0x10, 0x30, 0x1F, 0xC0, -0x2F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0x30, 0x1F, 0xE0, 0x7F, 0x00, 0xBB, 0x01, -0xF4, 0x07, 0x70, 0x0B, 0xC0, 0x7C, 0x05, 0xFF, 0x42, 0xFC, 0x32, 0xF0, 0x4F, -0xC8, 0x3F, 0x01, 0xFF, 0x01, 0xFC, 0x0C, 0x30, 0x4F, 0xC0, 0x4E, 0x00, 0xB3, -0x00, 0x7C, 0x73, 0xF0, 0x4F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x08, 0x77, 0x00, 0x11, 0x0E, 0x6C, 0x24, 0x30, 0x1D, 0x40, 0x23, -0x00, 0x51, 0x03, 0x14, 0x02, 0x50, 0x4D, 0x49, 0x33, 0x10, 0xC1, 0x10, 0x74, -0x04, 0x10, 0xB9, 0xE0, 0xFE, 0x00, 0xFD, 0x0A, 0x74, 0x22, 0xD0, 0xBF, 0x40, -0x3F, 0x0B, 0xCD, 0x00, 0x74, 0x00, 0x50, 0x3D, 0x40, 0x44, 0x00, 0x91, 0x0B, -0xF4, 0x03, 0xD1, 0x1F, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0xA0, 0x27, 0x00, 0x41, 0x00, 0x05, 0x00, 0x10, 0x0C, 0x40, 0x23, 0x00, -0x81, 0x02, 0x04, 0x03, 0x10, 0x4C, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x74, 0x03, -0x54, 0x04, 0x50, 0x32, 0x20, 0xC5, 0x84, 0x34, 0x12, 0xD0, 0x0C, 0x40, 0x31, -0x04, 0xCD, 0x00, 0x54, 0x11, 0x10, 0x2C, 0x48, 0x46, 0x80, 0xC1, 0x00, 0x14, -0x13, 0xD0, 0x2C, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA8, 0x25, 0x02, 0x51, 0x00, 0x44, 0x08, 0x10, 0x0D, 0x40, 0x27, 0x02, 0x51, -0x00, 0x54, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x00, 0xD9, 0x03, 0x74, 0x18, 0x14, -0x15, 0x50, 0x36, 0x00, 0xD9, 0x00, 0x70, 0x22, 0xD0, 0x0D, 0x40, 0x37, 0x20, -0xDD, 0x00, 0x74, 0x09, 0x50, 0x0D, 0x40, 0x46, 0x40, 0xD1, 0x11, 0x74, 0x03, -0xD1, 0x0D, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, -0x53, 0x01, 0x13, 0x10, 0x44, 0x0C, 0x30, 0x0D, 0xC0, 0x27, 0x40, 0x13, 0x80, -0x44, 0x06, 0x34, 0x0D, 0x40, 0x37, 0x00, 0xDB, 0x01, 0x3C, 0x09, 0x70, 0x31, -0x40, 0x36, 0x30, 0xDF, 0x00, 0x78, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x7C, 0x0C, 0x30, 0x0D, 0xC0, 0x42, 0x10, 0xD3, 0x01, 0x7C, 0x03, 0xF1, -0x0D, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x7D, -0x50, 0xEF, 0x10, 0xBC, 0x22, 0x70, 0x0F, 0xC0, 0x2B, 0x00, 0x9F, 0x00, 0xB8, -0x26, 0xB0, 0x0F, 0x88, 0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, -0x3F, 0x00, 0xFF, 0x20, 0xF8, 0x06, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x10, -0xFC, 0x24, 0xF0, 0x0E, 0xC0, 0x0D, 0x28, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, -0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x08, -0x1F, 0x00, 0x6C, 0x29, 0x30, 0x0D, 0xC0, 0x27, 0x01, 0xC7, 0x80, 0x4C, 0x03, -0x34, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x02, 0x4E, 0x08, 0x22, 0x05, 0xC8, 0x34, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x6D, -0x09, 0x70, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x0A, 0x7C, 0x03, 0xF1, 0x0D, 0xC4, -0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, -0x00, 0x45, 0x03, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0xD1, 0x00, 0x4D, 0x03, 0x10, -0x0D, 0xC0, 0x76, 0x02, 0xD1, 0x00, 0x45, 0x01, 0xB0, 0x04, 0xC1, 0x3E, 0x00, -0xFD, 0x00, 0x7C, 0x03, 0xC1, 0x1F, 0xC1, 0x3E, 0x00, 0xDD, 0x00, 0x04, 0x01, -0x10, 0x0F, 0xC0, 0x45, 0x00, 0xDD, 0x41, 0xF4, 0x83, 0xD0, 0x5F, 0x40, 0x4F, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x8D, 0x01, -0x04, 0x07, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x05, 0x00, 0x04, 0x03, 0xD0, 0x0C, -0x40, 0xF4, 0x00, 0xC5, 0x00, 0x04, 0x06, 0x18, 0x08, 0x40, 0x70, 0x00, 0xCD, -0x80, 0x34, 0x03, 0xC0, 0x1C, 0x40, 0x30, 0x08, 0xCD, 0xC0, 0x04, 0x01, 0x50, -0x0C, 0x40, 0x53, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x1F, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0x2D, 0x19, 0x04, -0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0x61, 0x01, 0xA4, 0x27, 0x90, 0x1E, 0x40, -0x7A, 0x00, 0xE1, 0x01, 0xC4, 0x04, 0x99, 0x9A, 0x40, 0x7A, 0x00, 0xED, 0x81, -0x94, 0x07, 0xD0, 0x9E, 0x40, 0x7A, 0x00, 0xED, 0x81, 0x84, 0x07, 0x10, 0x1E, -0x40, 0x49, 0x00, 0x6D, 0x01, 0xB4, 0x27, 0xD0, 0x1E, 0x40, 0x13, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x00, 0xDF, 0x00, 0x04, 0x03, -0x30, 0x0C, 0xC0, 0x22, 0x02, 0x85, 0x08, 0x04, 0x23, 0xF0, 0x0D, 0x40, 0x30, -0x04, 0xC7, 0x08, 0x04, 0x42, 0x30, 0x00, 0xC0, 0x30, 0x04, 0xCF, 0x00, 0x34, -0x02, 0xF0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x80, 0x4C, 0x01, 0x70, 0x0C, 0xC0, -0x13, 0x84, 0xCF, 0x00, 0x1C, 0x17, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x00, 0xDD, 0x03, 0xD0, -0x0F, 0xC0, 0x2F, 0x80, 0x7F, 0x00, 0xDE, 0xA3, 0x70, 0x0F, 0xC8, 0x3F, 0x00, -0xF7, 0x00, 0xBC, 0x22, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xFC, 0x22, -0xF0, 0xAE, 0xC2, 0x3F, 0x20, 0xFF, 0x08, 0xDC, 0x21, 0xF0, 0x0F, 0xC4, 0x0F, -0x10, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA8, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x00, 0x31, 0x0D, -0xC0, 0x3F, 0x00, 0x1F, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x7C, 0x04, 0x30, 0x15, 0xC0, 0xB5, 0x04, 0xDF, 0x07, 0x6C, 0x03, 0xF0, -0x5D, 0xC0, 0x36, 0x05, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x53, 0x00, -0xD1, 0x40, 0x78, 0x17, 0x34, 0x2D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40, -0x3B, 0x90, 0xAC, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x20, -0xB4, 0x00, 0x50, 0x0E, 0x40, 0x38, 0x01, 0xCD, 0x12, 0x84, 0x03, 0xD0, 0x0E, -0x40, 0xB8, 0x00, 0xE7, 0x00, 0x9C, 0x03, 0xD0, 0x6E, 0x40, 0x0B, 0x00, 0xE1, -0x00, 0xF4, 0x2B, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x00, 0xE9, 0x00, 0x8D, 0x03, 0x24, 0x05, 0x94, 0x1E, 0x40, 0x7B, -0x10, 0xEC, 0x03, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x01, 0xF6, -0x07, 0x10, 0x14, 0x41, 0x79, 0x02, 0xED, 0x05, 0x84, 0x07, 0x50, 0xDC, 0x40, -0x7A, 0x00, 0xED, 0x01, 0x96, 0x05, 0xD0, 0x1E, 0x40, 0x5B, 0x80, 0xE1, 0x41, -0xB4, 0x17, 0x10, 0x9E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x20, 0x63, 0x00, 0xCD, 0x00, 0x05, 0x13, 0x90, 0x0C, 0x40, 0x33, 0x02, -0xC9, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x00, 0x4C, 0x08, 0x34, 0x0B, -0x50, 0x3C, 0x40, 0x30, 0x00, 0xCC, 0x00, 0x04, 0x07, 0xD1, 0x0C, 0x40, 0x32, -0x20, 0xC5, 0x00, 0x54, 0x0B, 0xD0, 0x0C, 0x44, 0x23, 0x00, 0xC1, 0x07, 0x34, -0x03, 0x10, 0x0C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, -0xA8, 0x1D, 0x00, 0x7F, 0x0A, 0xEC, 0x1D, 0xB0, 0x05, 0x40, 0x57, 0x00, 0x7F, -0x0A, 0x7C, 0x01, 0xB4, 0x05, 0xC0, 0x17, 0x10, 0x7D, 0x02, 0xFC, 0x21, 0x30, -0x27, 0xC0, 0x15, 0x10, 0x5F, 0x00, 0x4C, 0x15, 0xF0, 0x05, 0xC0, 0x16, 0x80, -0x5F, 0xC0, 0xDC, 0x01, 0xF1, 0x05, 0xC0, 0x1F, 0x02, 0x73, 0x02, 0x74, 0x01, -0x30, 0x05, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, -0x07, 0x00, 0x0F, 0x02, 0x3C, 0x00, 0x70, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x20, 0xF0, 0x41, -0xC0, 0x03, 0x80, 0x1F, 0x00, 0x5D, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x80, 0x1F, -0x02, 0x5C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x7C, 0x00, 0xF0, -0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, -0x00, 0x9F, 0x00, 0x4C, 0x22, 0x34, 0x09, 0xC0, 0x23, 0x00, 0x83, 0x00, 0x4C, -0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x00, 0x4C, 0xA2, 0xF0, 0x09, 0xC0, -0x67, 0x00, 0x9B, 0x80, 0x7C, 0x02, 0xD2, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x84, -0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x64, 0x00, 0x8F, 0x01, 0x6C, 0x02, 0xF0, 0x09, -0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, -0x9D, 0x03, 0x44, 0x06, 0x10, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x6C, 0x22, -0xD0, 0x09, 0x40, 0xA7, 0x00, 0x8D, 0x00, 0x6C, 0x06, 0xD0, 0x09, 0x40, 0x27, -0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xC4, 0x27, 0x00, 0x91, 0x03, 0x74, -0x02, 0x50, 0x09, 0xC0, 0x66, 0x02, 0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x40, -0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, -0x04, 0x44, 0x02, 0x19, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x58, -0x09, 0x40, 0x27, 0x05, 0x9D, 0x00, 0x66, 0x02, 0x52, 0x8D, 0x40, 0x27, 0x01, -0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26, 0x00, 0x90, 0x02, 0x74, 0x02, -0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0xC0, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x63, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xA0, 0x00, 0x8D, 0x04, -0x04, 0x12, 0x10, 0x08, 0x40, 0x33, 0x01, 0x85, 0x04, 0x24, 0x12, 0xD0, 0x08, -0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x23, 0x01, 0x81, -0x04, 0x34, 0x12, 0xD0, 0x08, 0x48, 0x21, 0x01, 0x81, 0x00, 0x34, 0x22, 0x50, -0x08, 0x4A, 0x22, 0x00, 0x8D, 0x04, 0x26, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x5F, 0x0A, 0x4C, -0x00, 0x31, 0x01, 0x40, 0x87, 0x02, 0x13, 0x00, 0x0C, 0x28, 0x70, 0xA1, 0xC0, -0x87, 0x02, 0x1F, 0x0A, 0x64, 0x00, 0x70, 0x01, 0xC4, 0x07, 0x00, 0x1B, 0x0A, -0x74, 0x28, 0xF0, 0x41, 0x41, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x08, 0xB0, 0x41, -0xC1, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x98, 0x6F, 0x00, 0xBF, 0x28, 0xF5, 0x22, -0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF, 0x28, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0xBE, 0x40, 0xBD, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0x9F, 0x08, 0xFC, -0x22, 0xF0, 0x09, 0xC2, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x12, 0xF0, 0x09, 0xC0, -0x2F, 0x00, 0xBF, 0x08, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x27, 0x00, 0xBF, 0x14, 0xCC, 0x12, 0xF0, -0x09, 0xC0, 0x2F, 0x00, 0x93, 0x00, 0xFC, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x02, -0x8F, 0x00, 0xBC, 0x02, 0x32, 0x0B, 0xC0, 0x2C, 0x01, 0x9F, 0x14, 0x4C, 0x32, -0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0x4C, 0x02, 0xF2, 0x49, 0xC1, 0x2F, -0x00, 0xBF, 0x00, 0x7C, 0x02, 0x20, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0x08, 0x57, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01, -0x48, 0x07, 0x04, 0x1B, 0x08, 0x74, 0x50, 0x10, 0x41, 0x40, 0x07, 0x81, 0x1D, -0x50, 0x74, 0x00, 0x11, 0x81, 0xC0, 0x06, 0x00, 0x1D, 0x04, 0x45, 0x30, 0xB0, -0x21, 0xC0, 0x06, 0x0C, 0x11, 0x00, 0x44, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, -0x1D, 0x02, 0x74, 0x40, 0x10, 0x01, 0xC0, 0x72, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x14, 0x05, 0x02, 0xD0, 0x08, 0x40, -0x23, 0x02, 0x81, 0x01, 0x14, 0x32, 0x51, 0x48, 0x41, 0x23, 0x01, 0x8D, 0x05, -0x74, 0x03, 0x10, 0x08, 0x40, 0x30, 0x02, 0x89, 0x14, 0x04, 0x12, 0x10, 0x88, -0x40, 0x20, 0x42, 0x81, 0x00, 0x24, 0x12, 0x90, 0x08, 0x40, 0x23, 0x80, 0x8D, -0x09, 0x34, 0x02, 0x14, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA8, 0x25, 0x02, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x09, 0x40, 0x27, -0x02, 0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, -0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x8D, 0x00, 0x44, 0x22, 0x94, 0x09, 0x40, -0x26, 0x00, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x08, -0x74, 0x02, 0x11, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x08, 0x2D, 0x10, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x09, 0x40, 0x27, 0x00, -0x93, 0x01, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0x3C, 0x46, -0x34, 0x09, 0x50, 0x24, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24, -0x00, 0x93, 0x00, 0x6D, 0x6E, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02, 0x78, -0x02, 0x30, 0x09, 0xC0, 0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x00, 0x65, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, -0x83, 0x7E, 0x0E, 0xF0, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x49, 0x7C, 0x26, 0xF0, -0x49, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x3C, 0x06, 0x71, 0x09, 0xC0, 0x23, 0x00, -0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x3C, 0x02, -0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, -0x85, 0x00, 0x0F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x00, -0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1B, 0x00, 0x4F, 0x00, 0xB0, 0x01, -0xC0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x00, 0xC0, 0x07, 0x00, 0x1F, -0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, -0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, -0x00, 0x7D, 0x00, 0x74, 0x81, 0xD0, 0x05, 0xC0, 0x9D, 0x04, 0x5D, 0x00, 0x7E, -0x01, 0xD0, 0x15, 0x40, 0x5F, 0x01, 0x51, 0x00, 0x44, 0x01, 0x14, 0x04, 0xD0, -0x16, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x10, 0x45, 0xC0, 0x14, 0x00, 0x7D, 0x10, -0x44, 0x01, 0xD0, 0x05, 0x44, 0x17, 0x20, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x04, -0x40, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, -0xCD, 0x00, 0x34, 0x02, 0xDA, 0x0C, 0x48, 0x35, 0x20, 0xCD, 0x00, 0x74, 0x03, -0xD0, 0x9C, 0x40, 0x33, 0x80, 0xC9, 0x20, 0x10, 0x02, 0x90, 0x8C, 0x40, 0x22, -0x00, 0xCD, 0x00, 0x36, 0x03, 0x18, 0x08, 0x40, 0x31, 0x00, 0xDD, 0x01, 0x24, -0x83, 0xD0, 0x0C, 0x40, 0x23, 0x82, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, -0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x81, 0xED, -0x00, 0xB4, 0x43, 0xD9, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00, 0x94, 0x43, 0xD0, -0x0E, 0x40, 0x6B, 0x01, 0xF1, 0x05, 0xD4, 0x03, 0x10, 0x0F, 0x50, 0x3A, 0x00, -0xED, 0x08, 0x34, 0x03, 0x18, 0x0E, 0x40, 0x39, 0x08, 0xED, 0x00, 0xA4, 0x03, -0xC0, 0x0E, 0x40, 0x3B, 0x80, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x40, 0x13, -0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0xF8, 0x00, 0x2F, 0x01, -0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x59, 0x00, 0xEF, 0x01, 0xB4, 0x06, 0xF0, 0x1E, -0xE4, 0xFB, 0x00, 0xEB, 0x11, 0x94, 0x07, 0xB2, 0x1E, 0xD0, 0x7A, 0x00, 0xEF, -0x15, 0xBC, 0x5F, 0x70, 0x1C, 0xC0, 0x79, 0x00, 0xFF, 0x01, 0xAC, 0x07, 0xE0, -0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xB4, 0x37, 0xF0, 0x1A, 0xC0, 0x53, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, -0x03, 0xF0, 0x0D, 0xC4, 0x15, 0x10, 0xDF, 0x00, 0x7C, 0x0A, 0xB0, 0x0D, 0xC0, -0x03, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF2, 0x0C, 0xD0, 0x37, 0x00, 0xDF, 0x20, -0x7C, 0x03, 0xF4, 0x0D, 0xC0, 0x34, 0x07, 0x5F, 0x00, 0x5C, 0x03, 0xF0, 0x0D, -0xC8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x07, -0xFA, 0x8F, 0xC0, 0x6F, 0x02, 0xF3, 0x09, 0x8C, 0x0F, 0x30, 0x1F, 0xC0, 0x7F, -0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1E, 0xC0, 0x7C, 0x30, 0xF7, 0x41, 0xCC, -0x07, 0x70, 0x1F, 0xC4, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x72, 0x1F, 0xC8, -0x7B, 0x22, 0xF7, 0xA1, 0xFC, 0x87, 0x32, 0x1B, 0xC2, 0x08, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0x61, 0x40, 0x84, 0x03, 0x78, -0x0E, 0x44, 0x2B, 0x10, 0xE1, 0x20, 0xAC, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, -0xF1, 0x00, 0x84, 0x13, 0x50, 0x4E, 0x44, 0x39, 0x00, 0xF1, 0x00, 0xC4, 0x03, -0x10, 0x0E, 0xC0, 0x3E, 0x02, 0xE1, 0x00, 0x86, 0x03, 0xF0, 0x0E, 0x40, 0x3B, -0x40, 0xE5, 0x00, 0x34, 0x03, 0x10, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x25, 0x00, 0x84, 0x03, 0x50, 0x8E, -0x40, 0x0B, 0x00, 0xC0, 0x20, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1, -0x02, 0xC4, 0x03, 0x12, 0x0E, 0x60, 0x38, 0x00, 0xE5, 0x00, 0x84, 0x03, 0x10, -0x0E, 0x40, 0x39, 0x00, 0xE1, 0x00, 0xD4, 0x03, 0x10, 0x0E, 0x40, 0x3F, 0x40, -0xED, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0x41, 0x03, 0x05, 0x1B, 0x50, 0x0C, 0x40, -0x43, 0x40, 0xC1, 0x02, 0x24, 0x02, 0x10, 0x0C, 0x40, 0x13, 0x00, 0xC1, 0x41, -0x04, 0x03, 0x51, 0x0C, 0x60, 0x31, 0x00, 0xC1, 0x00, 0x05, 0x03, 0x10, 0x0C, -0x40, 0x33, 0x00, 0x41, 0x00, 0x04, 0x0B, 0xD0, 0x0C, 0x40, 0x33, 0x02, 0x8D, -0x42, 0x34, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA8, 0xB5, 0x42, 0xD7, 0x06, 0x0C, 0x03, 0x70, 0x0D, 0xC0, 0x27, -0x04, 0xD3, 0x00, 0x4C, 0x02, 0x34, 0x0D, 0xC0, 0x3F, 0x40, 0xF1, 0x01, 0x0C, -0x07, 0x30, 0xAC, 0x40, 0x30, 0x00, 0xF7, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, -0x3D, 0x00, 0xD3, 0x00, 0xDC, 0x23, 0x70, 0x0D, 0x40, 0xF7, 0x42, 0xDF, 0x02, -0xFC, 0x03, 0x30, 0x09, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x37, 0x00, 0x9F, 0x10, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0xA7, 0x00, -0xDF, 0x01, 0x5C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x5C, 0x63, -0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x36, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, -0x03, 0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -0x08, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xC0, 0x07, 0x00, 0xF7, -0x10, 0xFC, 0x02, 0x30, 0x5F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x30, -0x9B, 0xC0, 0x34, 0x00, 0xE3, 0x00, 0xCC, 0x03, 0x30, 0x1D, 0xC0, 0x3F, 0x00, -0xB3, 0x01, 0xFE, 0x03, 0xF0, 0x0F, 0xCA, 0xBF, 0x00, 0xFE, 0x10, 0xF4, 0x03, -0x30, 0x5A, 0x80, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, -0x36, 0x00, 0x95, 0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0xC7, 0x04, 0xD1, 0x00, -0x74, 0x26, 0x10, 0x1D, 0x40, 0x07, 0x00, 0xD9, 0x00, 0x74, 0x03, 0x10, 0x1D, -0x50, 0x35, 0x00, 0xDB, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91, -0x03, 0x76, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x20, 0xDD, 0x09, 0x74, 0x03, 0x10, -0x09, 0xC0, 0x05, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32, -0x00, 0xD1, 0x01, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x63, 0x00, 0xD5, 0x00, 0x34, -0x03, 0x10, 0x09, 0x40, 0x37, 0x02, 0xDD, 0x00, 0x76, 0x07, 0x10, 0x0D, 0x40, -0x74, 0x20, 0xD1, 0x00, 0x04, 0x03, 0x10, 0x4D, 0x40, 0x33, 0x28, 0xD1, 0x04, -0x74, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x00, 0x24, 0x03, 0x00, 0x09, -0x40, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, -0x05, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xC1, 0x00, 0x34, 0x03, -0x10, 0x08, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x30, -0x00, 0xC9, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x34, -0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x23, 0x10, 0x08, 0x40, -0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0x03, -0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0xD7, 0x00, 0xFC, 0x02, 0x14, -0x09, 0xC0, 0x23, 0x10, 0xFF, 0x00, 0x7C, 0x03, 0x34, 0x0D, 0xC0, 0x34, 0x00, -0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0xC3, 0x20, 0x74, 0x03, -0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0x30, 0x09, 0xC0, 0x01, -0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00, -0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, -0x80, 0x0F, 0x00, 0xFA, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, -0x00, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3F, 0x08, 0xFF, 0x00, 0xB0, 0x03, 0xF0, -0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x0B, 0xC0, 0x15, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x8C, 0xCC, -0x12, 0x32, 0xCF, 0xC0, 0x5E, 0x22, 0xB3, 0x21, 0xFC, 0x06, 0xF0, 0xCF, 0xC4, -0x3D, 0x03, 0x23, 0x01, 0xFC, 0x23, 0xF0, 0x13, 0xC0, 0x3F, 0x00, 0xFF, 0x4C, -0xCC, 0x06, 0xB0, 0x17, 0xD8, 0x5C, 0x00, 0xF7, 0x04, 0xAC, 0x04, 0xB0, 0x4F, -0xC1, 0x7A, 0x08, 0x3F, 0x01, 0xDC, 0x30, 0xB0, 0x1B, 0xC4, 0x0F, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x0E, 0x44, 0x26, -0x10, 0xEF, 0x40, 0x24, 0x01, 0xD1, 0x04, 0x74, 0x05, 0x70, 0x2F, 0x40, 0xBC, -0x02, 0x91, 0x01, 0xF4, 0x1B, 0x90, 0x40, 0x40, 0xFF, 0x02, 0xFD, 0x08, 0x44, -0xC3, 0x10, 0x19, 0x40, 0x34, 0x00, 0xF1, 0x01, 0x44, 0x05, 0x10, 0x3F, 0x40, -0x74, 0x10, 0x1D, 0xA1, 0x34, 0x38, 0xB0, 0x1C, 0x40, 0x07, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x8D, 0x04, 0x04, 0x02, 0x10, -0x4C, 0x40, 0x32, 0x00, 0xC1, 0x10, 0x14, 0x02, 0xD0, 0x6C, 0x48, 0x33, 0x11, -0x45, 0x00, 0x34, 0x0B, 0xD0, 0x00, 0x41, 0x33, 0x10, 0xC5, 0x44, 0x04, 0x13, -0x90, 0x08, 0x40, 0x00, 0x05, 0xC9, 0x08, 0x64, 0x01, 0xD0, 0x0C, 0x40, 0x30, -0x20, 0x05, 0x00, 0x14, 0x00, 0xD0, 0x04, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x44, 0x03, 0x10, 0x0D, -0x40, 0xA4, 0x0A, 0xD1, 0x04, 0x74, 0x01, 0x50, 0x0D, 0x40, 0x34, 0x40, 0x95, -0x02, 0x74, 0x03, 0xD1, 0x19, 0x42, 0x37, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x90, -0x08, 0x40, 0xB4, 0x01, 0xD9, 0x00, 0x64, 0x05, 0xD0, 0x0D, 0x50, 0x36, 0x04, -0x1D, 0x18, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x9F, 0x09, 0x0C, 0x03, 0x34, 0x0D, 0xC0, -0xD6, 0x08, 0x93, 0x01, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xD7, 0x09, -0x7C, 0x03, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB1, 0x25, -0xC9, 0x34, 0x40, 0xDB, 0x00, 0x6C, 0x17, 0xF0, 0x0D, 0xC0, 0xA6, 0x00, 0x1F, -0x02, 0x5C, 0x16, 0xF0, 0x39, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x80, 0x3D, 0x00, 0xEF, 0xC1, 0x7C, 0x02, 0xF2, 0x0E, 0xC0, 0x6F, -0x00, 0xFF, 0x80, 0xFC, 0x8D, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xBB, 0x00, 0xFC, -0x03, 0xB0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x10, 0xDD, 0x83, 0x70, 0x0B, 0xC0, -0x3F, 0x00, 0xF7, 0x00, 0xDC, 0x03, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0x3F, 0x01, -0xFC, 0x0E, 0xB4, 0x2F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x08, 0x35, 0x01, 0x93, 0x40, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x35, 0x08, -0xDF, 0x00, 0x4C, 0x0B, 0xF0, 0x0D, 0xC0, 0x34, 0x88, 0xDF, 0x00, 0x5C, 0x03, -0x70, 0x25, 0xC0, 0x34, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x2D, 0xE2, 0x27, -0x00, 0xDF, 0x04, 0x7C, 0x09, 0xF0, 0x0D, 0xC1, 0x25, 0x00, 0x57, 0x00, 0x5C, -0x02, 0x30, 0x05, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0xA0, 0x34, 0x00, 0xD1, 0x05, 0x74, 0x83, 0x18, 0x1F, 0x40, 0x24, 0x00, 0xDD, -0x10, 0x44, 0x81, 0xD0, 0x0F, 0xC0, 0x3E, 0x88, 0x9F, 0x00, 0xC4, 0x03, 0x10, -0x0D, 0x42, 0x3C, 0x00, 0xFD, 0x00, 0x74, 0x03, 0xB0, 0x09, 0x40, 0x77, 0x00, -0xED, 0x00, 0x36, 0x05, 0x10, 0x6E, 0x40, 0xB4, 0x02, 0x1B, 0x11, 0x4C, 0x03, -0x40, 0x05, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, -0xB2, 0x02, 0x81, 0x00, 0x34, 0x82, 0x10, 0x1C, 0x40, 0x65, 0x02, 0xCD, 0x01, -0x04, 0x81, 0xD0, 0x0D, 0x40, 0x30, 0x08, 0x0D, 0x00, 0x14, 0x03, 0x52, 0x00, -0x42, 0x32, 0x20, 0xCD, 0x43, 0x74, 0x02, 0x10, 0x0C, 0x40, 0x67, 0x02, 0xCD, -0x03, 0x24, 0x03, 0x58, 0x0C, 0x44, 0x31, 0x08, 0x05, 0x01, 0x54, 0x11, 0x10, -0x04, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, -0x00, 0xA1, 0x01, 0xB4, 0x06, 0x10, 0x1C, 0x40, 0x68, 0x00, 0xED, 0x01, 0x84, -0x05, 0xD0, 0x1E, 0x48, 0x7A, 0x00, 0x35, 0x01, 0x84, 0x27, 0x10, 0x96, 0x50, -0x7A, 0x00, 0xED, 0x19, 0xB4, 0x03, 0x10, 0x1A, 0x40, 0x6B, 0x00, 0xED, 0x01, -0xF4, 0x05, 0x19, 0x1C, 0x40, 0x7C, 0x00, 0x39, 0x81, 0xA4, 0x24, 0x10, 0x1E, -0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, -0xC3, 0x04, 0x34, 0x02, 0x10, 0x0C, 0xC0, 0x31, 0x00, 0xDF, 0x00, 0x0D, 0x01, -0xF8, 0x0D, 0xC0, 0x30, 0x02, 0x4D, 0x00, 0x5C, 0x07, 0x70, 0x2C, 0xC0, 0x32, -0x02, 0xCF, 0x00, 0x7C, 0x23, 0x10, 0x08, 0x40, 0x23, 0x00, 0xCF, 0x14, 0x34, -0x43, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC7, 0x00, 0x1E, 0x03, 0x34, 0x04, 0xC2, -0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x39, 0x42, 0xFF, -0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, -0x0F, 0x81, 0x3F, 0x00, 0xFF, 0x00, 0x7C, 0x2B, 0xB0, 0x0F, 0xC0, 0x3D, 0x04, -0xFF, 0x10, 0xF4, 0x13, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xFF, 0x10, 0x7C, 0x21, -0x70, 0x0F, 0xC0, 0x1F, 0x10, 0xEF, 0x00, 0xDC, 0x03, 0xF0, 0x07, 0xC0, 0x0B, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00, -0x4C, 0x03, 0xF0, 0x6D, 0xC0, 0x27, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, -0xC0, 0x37, 0x05, 0x57, 0x00, 0x5C, 0x37, 0x34, 0x08, 0xC0, 0x36, 0x01, 0xDF, -0x12, 0x4D, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2, -0x4C, 0xC1, 0x66, 0x00, 0x9B, 0x01, 0x4C, 0x01, 0xB0, 0x05, 0xC0, 0x57, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xBD, 0x04, 0x85, -0x0A, 0xD0, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x10, 0x8E, 0x40, -0x3B, 0x01, 0x6D, 0x00, 0x9C, 0x13, 0x10, 0x0E, 0x40, 0x38, 0x03, 0xE7, 0x04, -0x84, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x08, 0xED, 0x14, 0xB4, 0x03, 0x70, 0x4E, -0xC2, 0x3A, 0x40, 0x23, 0x00, 0x85, 0x00, 0xB0, 0x0E, 0x40, 0x4B, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x09, 0xA4, 0x17, -0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x90, 0x5E, 0x40, 0x7B, -0x02, 0xED, 0x31, 0x16, 0x07, 0x10, 0x1F, 0x42, 0x7A, 0x00, 0xE5, 0x01, 0x84, -0x07, 0xD0, 0x1E, 0x40, 0x6B, 0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0xDE, 0x40, -0x69, 0x00, 0xE9, 0x81, 0x84, 0x87, 0x90, 0x16, 0x40, 0x0F, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0xD0, -0x0C, 0x40, 0x23, 0x20, 0xDD, 0x40, 0x34, 0x45, 0x10, 0x0C, 0x40, 0x37, 0x08, -0xCD, 0x06, 0x14, 0x03, 0x10, 0xBC, 0x40, 0x30, 0x00, 0xD5, 0x20, 0x04, 0x07, -0xD0, 0x18, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x01, 0x50, 0x0C, 0x40, 0x53, -0x30, 0xC1, 0x08, 0x04, 0x0B, 0x90, 0x04, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x17, 0x88, 0x15, 0x00, 0x5F, 0x00, 0x6C, 0x41, 0xF0, 0x05, -0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC, 0x4D, 0xB0, 0x05, 0xC0, 0x17, 0x00, 0x6F, -0x01, 0x5C, 0x01, 0x30, 0x37, 0xC0, 0x16, 0x00, 0x57, 0x80, 0x4C, 0x91, 0xF0, -0x47, 0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xBC, 0x15, 0x70, 0x04, 0xC0, 0x5D, 0x0C, -0x7B, 0x03, 0xCC, 0x09, 0xA0, 0x07, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x07, 0x00, 0x0F, 0x02, 0x7C, 0x40, 0x70, 0x21, 0x80, 0x86, 0x00, 0x17, -0x12, 0x3C, 0x10, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x27, 0x08, 0x8F, 0x40, 0x4D, 0x16, 0xF0, 0x99, 0xC0, 0xE7, -0x00, 0x93, 0x09, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C, -0x02, 0xF0, 0x29, 0xC0, 0x23, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0, -0x64, 0x06, 0x93, 0x03, 0x5C, 0xA2, 0x71, 0x99, 0xC0, 0x24, 0x00, 0x9F, 0x01, -0x7C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x20, 0xA6, 0x00, 0xBD, 0x40, 0xC4, 0x06, 0x70, 0x09, 0x40, 0x63, 0x00, -0x91, 0x01, 0x44, 0x02, 0x18, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x44, 0x02, -0xD0, 0x28, 0x40, 0x24, 0x08, 0x93, 0x20, 0x04, 0x02, 0x90, 0x08, 0x40, 0x60, -0x00, 0x91, 0x04, 0x44, 0x4E, 0x10, 0x09, 0x50, 0x25, 0x10, 0x9D, 0x06, 0x74, -0x06, 0x50, 0x09, 0x42, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x24, 0x10, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, -0x80, 0x44, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0, -0x29, 0x40, 0x25, 0x00, 0x95, 0x00, 0x54, 0x02, 0x90, 0x09, 0x40, 0x24, 0x00, -0x91, 0x00, 0x54, 0x02, 0x50, 0x29, 0x40, 0x24, 0x30, 0x9D, 0x08, 0x74, 0x52, -0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, -0x30, 0x00, 0x8D, 0x02, 0x04, 0x02, 0x58, 0x68, 0x40, 0xA7, 0x00, 0x81, 0x02, -0x44, 0x0A, 0x10, 0x88, 0x40, 0x23, 0x02, 0x99, 0x00, 0x04, 0x22, 0xD0, 0x89, -0x40, 0x20, 0x00, 0x89, 0x08, 0x44, 0x22, 0x90, 0x29, 0x40, 0xA4, 0x00, 0x81, -0x00, 0x04, 0x02, 0x12, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x54, -0x28, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06, -0x00, 0x1F, 0x01, 0x4C, 0x04, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x0C, -0x00, 0x14, 0x61, 0xC1, 0x87, 0x0D, 0x17, 0x00, 0x5C, 0x58, 0xF1, 0x21, 0xC0, -0x05, 0x05, 0x07, 0x16, 0x5C, 0x88, 0x30, 0x01, 0xD0, 0x04, 0x40, 0x13, 0x54, -0x5C, 0x80, 0x78, 0x41, 0xC1, 0x14, 0x10, 0x1F, 0x00, 0x3C, 0x58, 0x30, 0x01, -0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x38, 0x27, 0x08, -0xBF, 0x03, 0xFC, 0x0A, 0xF0, 0x99, 0xC0, 0x6F, 0x08, 0xBF, 0x01, 0xFC, 0x06, -0xF0, 0x49, 0xC0, 0x27, 0x09, 0xB7, 0x00, 0x7C, 0x12, 0xF0, 0x4B, 0xC2, 0x25, -0x00, 0x97, 0x04, 0xFC, 0x12, 0x70, 0x1B, 0xC0, 0x6F, 0x30, 0x9F, 0x00, 0xFC, -0x02, 0xF8, 0x09, 0xD2, 0x2B, 0x80, 0xAF, 0x00, 0xFC, 0x12, 0xF0, 0x1B, 0xC0, -0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2B, 0x00, 0xBF, -0x13, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0xAC, 0x00, 0xBF, 0x00, 0x7C, 0x0A, 0x30, -0xC9, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x05, -0xBF, 0x0C, 0x49, 0x02, 0xF2, 0x29, 0xC2, 0xAF, 0x00, 0xAF, 0x04, 0xFC, 0x02, -0xF0, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x09, 0xC0, 0x67, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x07, -0x74, 0x88, 0xD0, 0x51, 0x40, 0x44, 0x20, 0x1D, 0x05, 0x74, 0x04, 0x10, 0xC1, -0x48, 0x84, 0x04, 0x11, 0x00, 0x74, 0x20, 0xD0, 0x45, 0x53, 0x04, 0x00, 0x1D, -0x0C, 0x44, 0x40, 0xD0, 0x14, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x74, 0x00, 0x10, -0x81, 0x40, 0x14, 0x20, 0x5D, 0x20, 0x74, 0x20, 0x14, 0x11, 0x40, 0x73, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34, -0x02, 0xD0, 0x88, 0x41, 0x20, 0x00, 0x8D, 0x10, 0x34, 0x02, 0x10, 0x48, 0x40, -0x22, 0x03, 0x89, 0x00, 0x34, 0x02, 0xD1, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x04, -0x26, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xDC, 0x08, -0x40, 0x20, 0x10, 0x8D, 0x00, 0x34, 0x02, 0x94, 0x48, 0x41, 0x43, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x20, 0x74, 0x82, -0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x04, 0x34, 0x02, 0x10, 0x09, 0x40, 0x20, -0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x66, -0x82, 0xD0, 0x89, 0x66, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x51, 0x09, 0x58, -0x24, 0x00, 0x9D, 0x01, 0x74, 0x2A, 0x10, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x01, 0x7C, 0x06, 0xF0, -0x0B, 0xD0, 0x2C, 0x03, 0xBF, 0x00, 0xFC, 0x02, 0x10, 0x09, 0xC0, 0x26, 0x00, -0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x24, 0x00, 0x9D, 0x80, 0x64, 0x22, -0xF0, 0x3B, 0xC0, 0x2F, 0x08, 0x9D, 0x00, 0x34, 0x4A, 0xF0, 0x09, 0x40, 0xA4, -0x00, 0x9F, 0x03, 0x70, 0x06, 0xB0, 0x3B, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x12, 0xF0, 0x09, -0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x08, 0xC0, 0x27, 0x10, 0x9F, -0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x06, 0xF8, -0x19, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xB0, 0x09, 0x05, 0x27, 0x80, -0x9E, 0x10, 0x6C, 0x06, 0xF0, 0x19, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x40, 0x7C, 0x00, 0xB4, 0x81, 0xC0, -0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x13, 0x02, -0x7C, 0x00, 0xF0, 0xA1, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x7C, 0x00, 0xF2, 0x21, -0xC0, 0x04, 0x20, 0x13, 0x10, 0x5C, 0x98, 0xF0, 0x01, 0xD0, 0x84, 0x00, 0x1F, -0x42, 0x2C, 0x00, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0xA0, 0x1C, 0x01, 0x51, 0x01, 0xF4, 0x1D, 0x10, 0x15, 0x40, 0x17, -0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74, -0x01, 0xD0, 0x97, 0xC0, 0x14, 0x00, 0x71, 0x03, 0x44, 0x01, 0x70, 0x05, 0x40, -0x14, 0x00, 0x71, 0x01, 0xC4, 0x05, 0xD0, 0x16, 0x42, 0x1C, 0x00, 0x7D, 0x00, -0xF4, 0x01, 0x14, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0xA0, 0x62, 0x00, 0xC1, 0x00, 0x34, 0x1E, 0x10, 0x0D, 0x48, 0x33, 0x00, -0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0xC0, 0xC1, 0x00, 0x34, 0x03, -0xD0, 0x2C, 0x40, 0x32, 0x40, 0xC1, 0x11, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x32, -0x02, 0x81, 0x00, 0x14, 0x05, 0x90, 0x18, 0x40, 0x60, 0x01, 0xC9, 0x02, 0x24, -0x03, 0x14, 0x0C, 0x60, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x80, 0x68, 0x00, 0xA1, 0x06, 0xB4, 0x06, 0x10, 0x8E, 0x40, 0x3B, 0x01, 0xAD, -0x04, 0xB4, 0x13, 0xD0, 0x8E, 0x40, 0x38, 0x81, 0xE1, 0x00, 0xB4, 0x13, 0xD0, -0x0E, 0x40, 0x78, 0x00, 0xC1, 0x10, 0x84, 0x13, 0x50, 0x5E, 0x40, 0x7A, 0x11, -0xA1, 0x11, 0x86, 0x09, 0xD0, 0x2C, 0x42, 0xA8, 0x00, 0xED, 0x00, 0x34, 0x0B, -0x10, 0x5F, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, -0x68, 0x00, 0xE3, 0x07, 0xBC, 0x06, 0x30, 0x5A, 0xC0, 0xEB, 0x00, 0xEF, 0x03, -0xB4, 0x0F, 0xF0, 0x1C, 0xC0, 0xF1, 0x00, 0xE1, 0x01, 0xBC, 0x17, 0xF0, 0x17, -0xC4, 0x72, 0x00, 0xE3, 0x01, 0x9C, 0x17, 0x70, 0x3E, 0xC8, 0xFE, 0x40, 0xE3, -0x01, 0x9C, 0x05, 0xB0, 0x1A, 0xC0, 0x68, 0x08, 0xED, 0x01, 0xAC, 0x05, 0x30, -0x3E, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, -0x50, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, -0x03, 0xF0, 0x0D, 0xC2, 0xB7, 0x0D, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x05, 0xC0, -0x37, 0x00, 0xDF, 0x00, 0x5C, 0x23, 0x72, 0x0D, 0xD0, 0x25, 0x00, 0xDF, 0x00, -0x7E, 0x01, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0C, -0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00, -0xFF, 0x09, 0xCC, 0x13, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x27, -0x30, 0x5F, 0x80, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x47, 0x30, 0x1B, 0xC0, 0x7C, -0x00, 0xBF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x68, 0x0A, 0xB1, 0x0C, 0xFC, -0x25, 0xF0, 0x1F, 0xC0, 0x78, 0x42, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC4, -0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x80, 0x29, 0x00, 0xBD, -0x18, 0x84, 0x43, 0x11, 0x0A, 0x48, 0x3B, 0x00, 0xA1, 0x10, 0x84, 0x23, 0x10, -0x0E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x03, 0x10, 0x8B, 0x41, 0x38, 0x00, -0x7D, 0x00, 0x94, 0x03, 0xD0, 0x4E, 0x40, 0x38, 0x03, 0xA1, 0x04, 0xB4, 0x09, -0xD0, 0x8E, 0x40, 0x19, 0x02, 0xE1, 0x00, 0xB4, 0x0A, 0xF0, 0x8E, 0x40, 0x54, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x40, -0xA7, 0x22, 0x14, 0x0A, 0x40, 0x2F, 0x06, 0xB1, 0x08, 0xC4, 0x07, 0x12, 0x4E, -0x60, 0x3B, 0x00, 0xED, 0x02, 0xB4, 0x03, 0x90, 0x02, 0x50, 0x38, 0x02, 0xAD, -0x00, 0xA4, 0x03, 0xD0, 0x1F, 0x49, 0x2C, 0x04, 0xE9, 0x88, 0xB4, 0x01, 0xD0, -0x0A, 0x40, 0x38, 0x80, 0x61, 0x10, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x60, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0x8D, 0x00, 0x24, -0x06, 0x10, 0x09, 0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x23, 0x10, 0x0C, 0x60, -0x33, 0x00, 0xCD, 0x08, 0x34, 0x03, 0x91, 0x00, 0x41, 0x30, 0x00, 0x4D, 0x00, -0x06, 0x03, 0xD2, 0x3C, 0x40, 0x60, 0x20, 0xC9, 0x00, 0x34, 0x09, 0xD0, 0x08, -0x40, 0x31, 0x02, 0x01, 0x03, 0x30, 0x07, 0x50, 0x0C, 0x60, 0x18, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x01, 0x6C, 0x02, -0x30, 0x0D, 0x40, 0xB7, 0x42, 0xD3, 0x21, 0x4D, 0x03, 0x14, 0x0F, 0xC2, 0x3F, -0x00, 0xDF, 0x00, 0xF4, 0x03, 0x90, 0x1D, 0xC0, 0x34, 0x00, 0x5F, 0x00, 0xCD, -0x17, 0xF0, 0x3D, 0xD0, 0xF4, 0x40, 0x9A, 0x00, 0x7C, 0x09, 0xF1, 0x0D, 0xC2, -0xF0, 0x00, 0xD1, 0x23, 0x74, 0x07, 0xD0, 0x2D, 0x50, 0x74, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0, -0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC0, 0x37, 0x00, -0xDF, 0x00, 0x3C, 0x03, 0x72, 0x2D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, -0xF0, 0x0D, 0xC0, 0x37, 0x01, 0x97, 0x22, 0x7C, 0x0D, 0xE0, 0x0D, 0xC0, 0xB7, -0x04, 0xDF, 0x20, 0x7C, 0x21, 0xF0, 0xCD, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x08, 0x7F, 0x02, 0xFF, 0x00, 0x7C, 0x22, 0xF0, 0x0B, -0xD0, 0x2C, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF, -0x00, 0xDC, 0x03, 0x30, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x01, 0xEE, 0x03, 0xF0, -0x0F, 0xC1, 0x3F, 0x00, 0xEF, 0x05, 0xCC, 0x41, 0xF0, 0x0B, 0xC0, 0x3D, 0x00, -0xFB, 0x10, 0x8C, 0x10, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x20, 0xD6, 0x00, 0xDD, 0x09, 0x74, 0x0A, 0xD0, 0x0D, 0x40, -0x64, 0x22, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00, -0x74, 0x03, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x7E, 0x03, 0xD0, 0x0D, -0x40, 0x27, 0x00, 0xDD, 0x07, 0x44, 0x05, 0xD0, 0x38, 0xC8, 0x76, 0x01, 0x89, -0x00, 0x54, 0x0C, 0x50, 0x0D, 0x42, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0xA0, 0x24, 0x04, 0x9D, 0x00, 0x74, 0x0B, 0xD2, 0x0D, 0x42, 0x34, -0x40, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74, -0x03, 0x10, 0x05, 0x41, 0x37, 0x80, 0x1D, 0x66, 0x74, 0x03, 0xD0, 0x0D, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x64, 0x07, 0xD2, 0x35, 0x40, 0x75, 0x00, 0xD1, 0x00, -0x44, 0x02, 0x11, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x30, 0x00, 0x8D, 0x20, 0x36, 0x03, 0xD0, 0x08, 0x40, 0x20, 0x00, -0x81, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, -0x18, 0x04, 0x40, 0x33, 0xA0, 0x0D, 0x00, 0x14, 0x03, 0xD2, 0x0C, 0x48, 0x33, -0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x5A, 0x36, 0x00, 0xD1, 0x00, 0x14, -0x00, 0x50, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x20, 0x26, 0x00, 0x9F, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xE8, 0x24, 0x00, 0x93, -0x40, 0xFC, 0x03, 0xF0, 0x0D, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xBC, 0x23, 0x34, -0x01, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x64, 0x03, 0xF0, 0x0F, 0xC0, 0x27, 0x00, -0xDF, 0x00, 0x6C, 0x01, 0xF0, 0x09, 0xC0, 0x35, 0x80, 0x5B, 0x80, 0x4E, 0x00, -0x32, 0x0F, 0xC8, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, -0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAF, 0x20, -0xBC, 0x03, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x03, -0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC2, 0x2F, 0x00, 0x3F, -0x00, 0xDC, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF8, -0x0E, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB0, 0x7F, -0x00, 0x3F, 0x00, 0xEC, 0x07, 0x70, 0x03, 0xC0, 0x7D, 0x02, 0xF3, 0x09, 0xFC, -0x10, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x21, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, -0x3F, 0x00, 0x3F, 0x18, 0xCD, 0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0xFB, 0x00, -0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x4C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0F, -0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x77, 0x00, -0x5D, 0x01, 0x44, 0x07, 0x10, 0xB1, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x74, 0x06, -0xD0, 0x29, 0x41, 0x3D, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0xD0, 0x0E, 0x40, 0x77, -0x00, 0x1D, 0x82, 0x44, 0x07, 0x10, 0x2F, 0x40, 0x67, 0x00, 0x51, 0x01, 0x74, -0x07, 0xD0, 0x15, 0x40, 0x44, 0x00, 0x5B, 0x01, 0x44, 0x05, 0x10, 0x1D, 0x40, -0x04, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x0D, -0x08, 0x04, 0x03, 0x50, 0x14, 0x68, 0x31, 0x01, 0xC1, 0x00, 0x34, 0x20, 0xD0, -0x6C, 0x40, 0xB1, 0x04, 0xCD, 0x01, 0x34, 0x23, 0xD0, 0x4C, 0x41, 0x31, 0x02, -0x0D, 0x05, 0x24, 0x03, 0x10, 0x2C, 0x40, 0x23, 0x00, 0x85, 0x00, 0x34, 0x02, -0x50, 0x08, 0x40, 0x01, 0x00, 0x85, 0x20, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x44, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x80, 0x5D, 0x14, -0x65, 0x03, 0x10, 0x01, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x00, 0xD0, 0x0D, -0x40, 0x35, 0x20, 0xDD, 0x01, 0x74, 0x03, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0x1D, -0x00, 0x64, 0x43, 0x10, 0x0D, 0x44, 0x67, 0x00, 0xD5, 0x06, 0x74, 0x03, 0xD1, -0x0D, 0x51, 0x45, 0x40, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x8D, 0x40, 0x0C, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0x9F, 0x01, 0x6C, -0x07, 0x70, 0x01, 0xC0, 0x75, 0x40, 0xD3, 0x00, 0x7C, 0x11, 0xF0, 0x0D, 0xC0, -0x35, 0x00, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00, -0x6C, 0x03, 0x30, 0x0D, 0xC0, 0xE7, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x3D, -0xC0, 0xC1, 0x84, 0xD7, 0x00, 0x4C, 0x07, 0x30, 0x0D, 0xC0, 0x08, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x6F, 0x00, 0xDC, 0x0B, -0xF0, 0x0F, 0xC0, 0x7F, 0x02, 0xFF, 0x00, 0xFC, 0x0F, 0xF0, 0x0D, 0xE0, 0x3F, -0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC6, 0x3F, 0x80, 0x9F, 0x28, 0xDC, -0x27, 0xF0, 0x0F, 0xC0, 0x2F, 0x40, 0x7B, 0x00, 0xFC, 0x03, 0xF0, 0x96, 0xC0, -0x0E, 0x00, 0xE3, 0x00, 0xBC, 0x09, 0xF0, 0x1E, 0xC0, 0x1F, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x02, 0x4C, 0x03, 0xF0, -0x05, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x70, 0x0D, 0xC8, 0x35, 0x08, -0xD3, 0x80, 0x7C, 0x07, 0xF1, 0x0D, 0xC2, 0x34, 0x00, 0x5F, 0x00, 0x0C, 0x23, -0x30, 0x0D, 0xC0, 0xA3, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xB0, 0x29, 0xC0, 0x04, -0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x5C, 0x00, 0x34, 0x3F, 0xD0, 0x0D, -0xC0, 0x74, 0x01, 0xD1, 0x00, 0x44, 0x01, 0xD0, 0x9C, 0x48, 0x7C, 0x01, 0xD1, -0x00, 0xF4, 0x03, 0xD0, 0x0F, 0x40, 0x3C, 0x01, 0x9D, 0x00, 0x6E, 0x03, 0xB0, -0x4F, 0x40, 0x27, 0x08, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x4D, 0xC0, 0x04, 0x00, -0xDD, 0x00, 0x44, 0x93, 0x10, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x20, 0x32, 0x00, 0x0D, 0x00, 0x34, 0x0F, 0x90, 0x08, 0x40, -0x34, 0x00, 0xC1, 0x00, 0x04, 0x00, 0x50, 0x08, 0x00, 0x31, 0x00, 0xC1, 0x00, -0x34, 0x03, 0xD8, 0x0C, 0x40, 0x70, 0x00, 0x9D, 0x40, 0x04, 0x04, 0x90, 0x2C, -0x41, 0x23, 0x00, 0xC5, 0x00, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x42, 0x02, 0xCD, -0x00, 0x24, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x00, 0x7A, 0x08, 0xAD, 0x21, 0xB4, 0x07, 0xD2, 0x10, 0x40, 0xF8, -0x02, 0xE1, 0x0B, 0x94, 0x26, 0xD0, 0x1A, 0x41, 0xF8, 0x00, 0xE0, 0x01, 0xB4, -0x07, 0xD8, 0x3E, 0x40, 0x78, 0x00, 0x6D, 0x01, 0x84, 0x06, 0x90, 0x1E, 0x40, -0x63, 0x80, 0xE1, 0x01, 0x34, 0x27, 0x10, 0x1C, 0x40, 0x48, 0x00, 0x4D, 0x01, -0x24, 0x07, 0x10, 0x14, 0x42, 0x10, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x00, 0x32, 0x00, 0x0F, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x30, 0x02, -0xC3, 0x00, 0x1C, 0x03, 0x70, 0x8C, 0x40, 0x35, 0x00, 0xC1, 0x00, 0x3C, 0x23, -0xF0, 0x0C, 0xC0, 0x30, 0x00, 0x8F, 0x00, 0x04, 0x11, 0x30, 0x8C, 0xC0, 0xB3, -0x82, 0xC7, 0x00, 0x3C, 0x02, 0x30, 0x0C, 0xC0, 0x02, 0x00, 0x8F, 0x00, 0x2C, -0x02, 0x30, 0x2C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xA8, 0x3D, 0x00, 0xBF, 0x00, 0xFE, 0xA3, 0xF0, 0x83, 0xC0, 0x3F, 0x92, 0xFF, -0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0xBF, 0x04, 0xFF, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC0, 0x3F, 0x04, 0x7F, 0x08, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, -0xFF, 0x00, 0xFC, 0x03, 0x75, 0x8F, 0xD0, 0x0F, 0x00, 0xFF, 0x00, 0x5C, 0x03, -0xF0, 0x0F, 0xE0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, -0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xD3, 0x01, -0x0C, 0x04, 0x30, 0x0D, 0xC0, 0xB5, 0x01, 0xDB, 0x00, 0x7C, 0x7B, 0xF0, 0xED, -0xC1, 0x34, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xB8, 0x8D, 0xC1, 0x27, 0x00, 0xDF, -0x01, 0x4C, 0x05, 0x10, 0x0D, 0xC4, 0x04, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, -0x19, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39, -0x00, 0xED, 0x00, 0xB4, 0x03, 0xD2, 0x0E, 0x40, 0x3B, 0x00, 0xF1, 0x00, 0x85, -0x02, 0x50, 0x0E, 0x40, 0x33, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0C, 0x40, -0x38, 0x01, 0xCD, 0x00, 0xA4, 0x83, 0x10, 0x4E, 0xC0, 0x2B, 0x00, 0xED, 0x00, -0x84, 0x03, 0x10, 0x0E, 0x40, 0x08, 0x00, 0xED, 0x80, 0x84, 0x03, 0x10, 0x0E, -0x40, 0x48, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, -0xED, 0x01, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x81, 0x84, 0x07, -0x00, 0x1E, 0x41, 0x7B, 0x00, 0xE1, 0x03, 0xB4, 0x97, 0xD8, 0x5E, 0x40, 0x7A, -0x00, 0xED, 0x01, 0x05, 0x07, 0x14, 0x5E, 0x44, 0x7B, 0x00, 0xC5, 0x01, 0x04, -0x07, 0x90, 0x1C, 0x40, 0x4A, 0x00, 0xCD, 0x11, 0x04, 0x47, 0x10, 0x1C, 0x40, -0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0xA0, 0xCD, -0x1A, 0x34, 0x86, 0xD0, 0x0C, 0x41, 0x23, 0x02, 0xC1, 0x00, 0x04, 0x27, 0x5B, -0x1D, 0x42, 0x33, 0x40, 0x41, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x32, 0x00, -0xCD, 0x06, 0x04, 0x07, 0x10, 0x0D, 0x40, 0xB1, 0x00, 0xCD, 0x00, 0x05, 0x07, -0x94, 0x0C, 0x50, 0xF2, 0x04, 0xCD, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x78, 0x5A, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x7F, 0x03, -0x7C, 0x01, 0xF0, 0x77, 0x40, 0x57, 0x40, 0x53, 0x00, 0xCC, 0x05, 0x30, 0x05, -0xC0, 0x17, 0x00, 0x73, 0xC1, 0x74, 0x01, 0xF0, 0x05, 0xC8, 0x16, 0x10, 0x7F, -0x02, 0xEC, 0x11, 0xB0, 0x05, 0x40, 0x1F, 0x00, 0x7F, 0x00, 0xCC, 0x15, 0xB0, -0x07, 0xC0, 0xDA, 0x09, 0x7F, 0x03, 0xCC, 0x05, 0x30, 0x27, 0xC0, 0x5E, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x0F, 0x00, 0x74, -0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x17, 0x01, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0xA0, 0x1B, 0x00, -0x3E, 0x04, 0x70, 0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01, -0xC0, 0x85, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x49, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, -0xF0, 0x08, 0xD4, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, -0x40, 0x93, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x00, 0x4C, -0x82, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x08, 0xC0, -0x24, 0x00, 0x93, 0x10, 0x4C, 0x02, 0x34, 0x09, 0xC1, 0x43, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0, -0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x19, 0x48, 0xA4, 0x00, -0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02, -0xB0, 0x09, 0xC0, 0xA6, 0x00, 0x9D, 0x02, 0x5C, 0x0A, 0xD0, 0x29, 0x40, 0x24, -0x00, 0x91, 0x02, 0x4C, 0x0A, 0x10, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x09, -0x48, 0x64, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x89, 0x40, 0x62, 0x84, 0x99, -0x00, 0x44, 0x06, 0x10, 0x19, 0x63, 0x64, 0x80, 0x8D, 0x00, 0x44, 0x02, 0x10, -0x09, 0x42, 0x24, 0x04, 0x91, 0x10, 0x74, 0x42, 0xD0, 0x09, 0x51, 0x24, 0x00, -0x99, 0x30, 0x44, 0xC3, 0x10, 0x09, 0x41, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40, -0x34, 0x40, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x4C, 0x40, 0x20, 0x81, 0x99, 0x00, -0x04, 0x12, 0x10, 0x48, 0x40, 0x20, 0x21, 0x8D, 0x04, 0x06, 0x12, 0x90, 0x4C, -0x48, 0x20, 0x01, 0x8D, 0x04, 0x14, 0x12, 0xD8, 0x48, 0x60, 0x20, 0x00, 0x89, -0xC4, 0x04, 0x12, 0x10, 0x48, 0x60, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xF0, 0x01, 0xC0, 0x80, -0x02, 0x13, 0x0A, 0x74, 0x00, 0x70, 0xA1, 0xC0, 0x86, 0x22, 0x19, 0x00, 0x45, -0x00, 0x30, 0xA1, 0x40, 0x04, 0x00, 0x1F, 0x0A, 0x4D, 0x00, 0x30, 0xA1, 0x40, -0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC8, 0x14, 0x00, 0x13, 0x00, -0x4C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0xA8, 0x27, 0x00, 0xBF, 0x88, 0xFD, 0x02, 0xF0, 0x8B, 0x80, 0x2F, 0x00, -0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x8B, 0xC0, 0x27, 0x42, 0xB7, 0x00, 0x7C, 0x22, -0xF4, 0x89, 0xC0, 0x27, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0x74, 0x89, 0xD0, 0x2F, -0x02, 0xBF, 0x08, 0xDC, 0x22, 0xF1, 0x8B, 0xC0, 0x2F, 0x40, 0xB7, 0x28, 0xDD, -0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA8, 0x27, 0x00, 0x9F, 0x04, 0xFE, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF, -0x00, 0xDC, 0x52, 0xB0, 0xCA, 0xC8, 0x2E, 0x08, 0xBF, 0xA0, 0xDC, 0x82, 0x32, -0x4B, 0xC2, 0x6F, 0x01, 0xDF, 0x0C, 0xFC, 0x02, 0x34, 0x0B, 0xC0, 0x26, 0x00, -0x93, 0x04, 0x5C, 0x52, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0x30, 0x49, 0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, -0x07, 0x00, 0x1D, 0x08, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x14, -0x74, 0x00, 0xD0, 0xC1, 0x40, 0x84, 0x04, 0x1D, 0x00, 0x5C, 0x20, 0x10, 0x41, -0x43, 0x07, 0x00, 0x1D, 0x0C, 0x74, 0x08, 0x10, 0x01, 0x41, 0x04, 0x42, 0x13, -0x00, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x7C, 0x20, 0x10, -0x03, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, -0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x04, 0x34, -0x02, 0x90, 0x48, 0x40, 0x22, 0x03, 0x8D, 0x00, 0x34, 0x02, 0x10, 0xC8, 0x40, -0x23, 0x02, 0x8D, 0x44, 0x34, 0x22, 0x12, 0x88, 0x48, 0x28, 0x80, 0xA1, 0x09, -0xB4, 0x06, 0xD0, 0x1A, 0x40, 0x28, 0x00, 0xAD, 0x89, 0xB4, 0x06, 0x10, 0x9A, -0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, -0x9D, 0x00, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, -0xD0, 0x0D, 0x60, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, -0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA4, 0x00, 0xB9, 0x00, 0xE4, -0x02, 0xD0, 0x4B, 0x40, 0x2C, 0x00, 0xBC, 0x40, 0xF4, 0x02, 0x10, 0x8B, 0x40, -0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, -0x00, 0x74, 0x02, 0xF0, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x6A, 0x90, -0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x22, 0x30, 0x09, 0xD0, 0x60, 0x00, 0x93, 0x0B, 0x7C, 0x0A, -0xF0, 0x39, 0xD0, 0x64, 0x04, 0x9F, 0x02, 0x7C, 0x0A, 0x34, 0x39, 0xC0, 0x17, -0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x20, -0x7C, 0x42, 0xF0, 0x49, 0xC0, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x02, 0xD0, 0x98, -0xC0, 0x27, 0x00, 0x9F, 0x09, 0x1C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x80, 0x9F, -0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x01, 0x87, 0x01, 0x5C, 0x16, 0xF0, -0x19, 0xC0, 0x67, 0x01, 0x9E, 0x05, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x4B, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x4C, -0x80, 0xF2, 0x01, 0xC2, 0x04, 0x04, 0x1F, 0x00, 0x7C, 0x08, 0x30, 0x01, 0xC0, -0x07, 0x04, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00, -0x4C, 0x80, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x00, -0xC0, 0x04, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x20, 0x5D, 0x00, 0xD0, 0x11, -0x70, 0x05, 0x40, 0x9C, 0x00, 0x7D, 0x11, 0x74, 0x01, 0x00, 0x37, 0xC1, 0x5E, -0x00, 0x51, 0x05, 0x40, 0x05, 0xD0, 0x17, 0x40, 0x54, 0x00, 0x5D, 0x00, 0x44, -0x01, 0x30, 0x07, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74, 0x01, 0x50, 0x05, 0x50, -0x14, 0x10, 0x5D, 0x21, 0x54, 0x01, 0xD0, 0x15, 0x40, 0x53, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x04, 0x0D, 0x50, -0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x06, 0x10, 0x34, 0x51, 0x71, 0x00, -0x81, 0x01, 0x34, 0x26, 0xD0, 0x1C, 0x40, 0x60, 0x02, 0xCD, 0x00, 0x04, 0x22, -0x10, 0x85, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x32, -0x00, 0xC9, 0x01, 0x04, 0x03, 0xD0, 0x1C, 0x60, 0x53, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xED, 0x21, 0x84, 0x03, 0x50, 0x1E, -0x40, 0x38, 0xA0, 0xED, 0x00, 0x34, 0x0F, 0x10, 0x06, 0x40, 0x7A, 0x44, 0xA1, -0x01, 0x94, 0x03, 0xD0, 0x1E, 0x41, 0x38, 0x00, 0xCD, 0x09, 0x04, 0x02, 0x10, -0x06, 0x40, 0x32, 0x00, 0xE9, 0x00, 0xB4, 0x07, 0x50, 0x0A, 0x40, 0x2A, 0x00, -0xCD, 0x11, 0x94, 0x02, 0xD0, 0x0E, 0x41, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xCF, 0x01, 0x85, 0x07, 0x70, 0x1C, 0xD0, -0x58, 0x00, 0x2F, 0x01, 0xBC, 0x07, 0x34, 0x16, 0xC0, 0x5D, 0x00, 0xA1, 0x01, -0xBC, 0x07, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xEE, 0x11, 0x8D, 0x06, 0x39, 0x14, -0xC0, 0x5A, 0x00, 0x6F, 0x01, 0x3C, 0x05, 0x70, 0x14, 0xC0, 0x5A, 0x00, 0x6D, -0x01, 0x8C, 0x05, 0xF0, 0x16, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x07, -0x00, 0x1F, 0x00, 0x7C, 0x03, 0x78, 0x01, 0xC8, 0x07, 0x00, 0x8F, 0x00, 0x6C, -0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00, 0xDF, 0x82, 0x7E, 0x02, 0x74, 0x07, 0xC4, -0x15, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xB4, 0x01, 0xC0, 0x05, 0x00, 0x5F, 0x20, -0x6D, 0x00, 0xF0, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0x8C, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x00, -0xF3, 0x01, 0xCC, 0x07, 0x30, 0x17, 0xC2, 0x6F, 0x10, 0xF2, 0x01, 0xFC, 0x07, -0xF0, 0x1B, 0xC0, 0x7C, 0x20, 0xF7, 0x81, 0xFC, 0x06, 0xF0, 0x13, 0xC2, 0x79, -0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC8, 0x7F, 0x00, 0xBB, 0x01, 0xCC, -0x87, 0x30, 0x1B, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x18, 0x39, 0x00, 0xED, 0x08, 0x8C, 0x03, 0x10, 0x0E, 0x40, 0x1F, 0x00, 0xE1, -0x08, 0x84, 0x03, 0x14, 0x02, 0x40, 0x1B, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0, -0x0A, 0x40, 0x38, 0x00, 0xE1, 0x10, 0xB4, 0x13, 0x10, 0x42, 0x40, 0x38, 0x01, -0xE1, 0x00, 0x9C, 0x03, 0x10, 0x4A, 0x40, 0x2B, 0x20, 0xA1, 0x00, 0xAC, 0x02, -0x10, 0x0A, 0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x39, 0x00, 0xED, 0x10, 0xA4, 0x23, 0x50, 0x0E, 0x41, 0x3B, 0x44, 0x61, 0x00, -0x84, 0x03, 0x50, 0x06, 0x40, 0x2B, 0x00, 0xE1, 0x00, 0xB4, 0x23, 0xD0, 0x02, -0x40, 0x38, 0x00, 0xE5, 0x00, 0x34, 0x02, 0x50, 0x02, 0x60, 0x19, 0x10, 0x61, -0x00, 0xB4, 0x01, 0x90, 0x06, 0x44, 0x1F, 0x02, 0x01, 0x00, 0x84, 0x01, 0x10, -0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, -0x20, 0xCD, 0x03, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x51, 0x00, 0x04, -0x4B, 0x50, 0x00, 0x40, 0x03, 0x00, 0xC1, 0x43, 0x36, 0x03, 0xD0, 0x00, 0x40, -0x30, 0x00, 0xC1, 0x03, 0x34, 0x0B, 0x10, 0x00, 0x40, 0x90, 0x40, 0x41, 0x42, -0x14, 0x01, 0x90, 0x20, 0x40, 0x83, 0x2E, 0x01, 0x02, 0x24, 0x08, 0x10, 0x00, -0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, -0xDF, 0x03, 0x6D, 0x03, 0x70, 0x3D, 0xC0, 0x67, 0x00, 0xD3, 0x00, 0x4D, 0x0B, -0x70, 0x0D, 0xC2, 0x37, 0x40, 0x93, 0x01, 0x3C, 0x03, 0xF0, 0x0D, 0xD0, 0x30, -0x00, 0xF7, 0x23, 0x7C, 0x0A, 0x70, 0x05, 0xC0, 0xA1, 0x00, 0x93, 0x03, 0x7C, -0x06, 0xB0, 0x3D, 0xC0, 0xF7, 0x00, 0xD3, 0xA3, 0x4D, 0x8F, 0x34, 0x1D, 0xD0, -0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, -0x04, 0x5C, 0x0F, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x3C, 0x03, 0xB0, -0x09, 0xC0, 0x37, 0x20, 0x9F, 0x08, 0x7C, 0x83, 0xF0, 0x05, 0xC0, 0x37, 0x00, -0xCF, 0x04, 0x7C, 0x02, 0x70, 0x20, 0xC0, 0x27, 0x04, 0x8F, 0x11, 0x1C, 0x46, -0x74, 0x19, 0xC1, 0x27, 0x00, 0xD7, 0x01, 0x5C, 0x06, 0xF0, 0x1D, 0xC0, 0x07, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xDF, 0x00, -0xFC, 0x03, 0xF0, 0x0E, 0xC1, 0x0C, 0x08, 0xBF, 0x03, 0x4C, 0x03, 0x30, 0x0E, -0xD0, 0x14, 0x00, 0xBF, 0x19, 0xCC, 0x17, 0x30, 0x89, 0xC0, 0x34, 0x00, 0xF7, -0x00, 0xCC, 0x42, 0xF0, 0x05, 0xC0, 0x8E, 0x00, 0x37, 0x08, 0x68, 0x20, 0x30, -0x07, 0xC0, 0x1F, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0, 0x07, 0xC0, 0x13, 0x22, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, -0x0F, 0xD0, 0x0D, 0xC0, 0x46, 0x00, 0x1D, 0x01, 0x44, 0x27, 0x10, 0x31, 0x40, -0x04, 0x00, 0x8D, 0x01, 0x44, 0x07, 0x10, 0x01, 0x40, 0x34, 0x00, 0xDB, 0x00, -0x44, 0x02, 0xD0, 0x19, 0x40, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, -0x40, 0x07, 0x00, 0x5D, 0x00, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x02, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x0F, -0xD0, 0x0D, 0x40, 0x24, 0x01, 0x9D, 0x10, 0x54, 0x03, 0x14, 0x1D, 0x40, 0x24, -0x20, 0x9D, 0x00, 0x46, 0x03, 0x10, 0x0C, 0x41, 0x36, 0x02, 0xD0, 0x00, 0x44, -0x02, 0xD8, 0x11, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x0D, 0x40, -0x37, 0x00, 0x98, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0, -0x0C, 0x50, 0x12, 0x00, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x08, 0x40, 0x10, 0x00, -0x9D, 0x00, 0x04, 0x03, 0x10, 0x04, 0x48, 0x30, 0x00, 0xC9, 0x00, 0x04, 0x03, -0xD0, 0x00, 0x40, 0x25, 0x00, 0x81, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x23, -0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x24, 0x00, 0x8F, 0x00, 0x5D, 0x03, 0x14, 0x05, 0xC0, 0x24, 0x20, 0x9E, -0x00, 0x4D, 0x03, 0x34, 0x09, 0xD0, 0x34, 0x00, 0xF7, 0x00, 0x4D, 0x02, 0xF0, -0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x05, 0xC8, 0x17, 0x10, -0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0xA8, 0x3F, 0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, -0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x00, -0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, -0xC0, 0x0E, 0x00, 0x3F, 0x20, 0xEC, 0x00, 0xB0, 0x03, 0xC0, 0x0B, 0x00, 0x3F, -0x40, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xB0, 0x1B, 0xC0, 0x2F, -0x21, 0xF3, 0x24, 0xEC, 0x25, 0xF0, 0x1F, 0xD0, 0x3C, 0x00, 0xFB, 0x88, 0xCC, -0x84, 0xB0, 0x4F, 0xC0, 0x7F, 0x22, 0x2F, 0x01, 0xF4, 0x05, 0x30, 0x0B, 0xC1, -0xEF, 0x00, 0x2F, 0x01, 0xEC, 0x04, 0x30, 0x12, 0xC0, 0x5E, 0x08, 0x2F, 0x01, -0xCE, 0x0D, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x27, 0x10, 0x9D, 0x01, 0x44, 0x0F, 0x10, 0x15, 0x40, 0x67, 0x00, -0xD1, 0x14, 0x44, 0x02, 0xD0, 0x4D, 0x40, 0xBC, 0x04, 0xF1, 0x0E, 0x44, 0x07, -0x10, 0xBF, 0x40, 0x37, 0x00, 0x17, 0x94, 0x64, 0x05, 0x10, 0x39, 0x40, 0x37, -0x11, 0x5D, 0x21, 0x44, 0x05, 0x51, 0x19, 0x40, 0x75, 0x30, 0x1D, 0x21, 0x46, -0x02, 0x10, 0x11, 0xC0, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, -0xA0, 0x23, 0x00, 0x0D, 0x80, 0x05, 0x0B, 0xD8, 0x08, 0x40, 0x23, 0x02, 0xC1, -0x0C, 0x24, 0x02, 0x50, 0x08, 0x41, 0xB0, 0x81, 0xC9, 0x04, 0x54, 0x07, 0x90, -0x0C, 0x40, 0x33, 0x11, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x0C, 0x44, 0x31, 0x01, -0x49, 0x00, 0x24, 0x00, 0x12, 0x0D, 0x44, 0x31, 0x00, 0x1D, 0x40, 0x64, 0x13, -0x90, 0x08, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, -0x65, 0x00, 0x9D, 0x11, 0x44, 0x03, 0x18, 0x65, 0x40, 0x27, 0x00, 0xD1, 0x00, -0x42, 0x02, 0xD0, 0x08, 0x40, 0x34, 0x08, 0xC1, 0x00, 0x55, 0x03, 0x10, 0x0D, -0x40, 0x37, 0x00, 0x9D, 0x11, 0x64, 0x00, 0x1C, 0x0D, 0x40, 0x37, 0x10, 0x5D, -0x11, 0x44, 0x45, 0x50, 0x89, 0x00, 0x75, 0x00, 0x1D, 0x10, 0x64, 0x43, 0x96, -0x11, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x47, -0x04, 0x9F, 0x21, 0x44, 0x03, 0xF2, 0x05, 0xC0, 0x33, 0x40, 0xD3, 0x00, 0x6C, -0x03, 0xF1, 0x0D, 0xC0, 0x34, 0x00, 0xDB, 0x00, 0x54, 0x04, 0xB0, 0x0D, 0xC0, -0x37, 0x00, 0x1F, 0x01, 0x7C, 0x14, 0x30, 0x09, 0xC0, 0x35, 0x00, 0x5B, 0x01, -0x2C, 0x0D, 0x30, 0x31, 0x82, 0x77, 0x01, 0x1D, 0x22, 0x64, 0x0F, 0xB1, 0x31, -0xC1, 0x81, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, -0xAF, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x02, 0xEF, 0x80, 0xFC, 0x82, -0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0xA0, 0xF0, 0x0F, 0xC2, 0x3F, -0x10, 0x37, 0x00, 0xEC, 0xA4, 0x70, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC, -0x01, 0xF0, 0x13, 0xC0, 0x2F, 0x00, 0x3F, 0x08, 0xDD, 0x27, 0x70, 0x03, 0xC0, -0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x02, 0x13, -0x10, 0x7E, 0x23, 0xB0, 0x05, 0xC0, 0x37, 0x03, 0xDF, 0x80, 0x7C, 0x03, 0xF1, -0x09, 0xC0, 0x35, 0x80, 0xDF, 0x08, 0x4C, 0x80, 0x70, 0x0D, 0xC1, 0x37, 0x00, -0x93, 0x02, 0x5C, 0x08, 0xF8, 0x0D, 0xC2, 0x37, 0x00, 0x5F, 0x0E, 0x78, 0x1B, -0x70, 0x25, 0xC4, 0xA5, 0x00, 0x53, 0x00, 0x6C, 0x4B, 0x31, 0x09, 0xC4, 0x0B, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xE4, 0x02, 0x91, 0x00, -0xF4, 0x07, 0x10, 0x05, 0x41, 0x77, 0x00, 0xFD, 0x00, 0x44, 0x02, 0xD0, 0x19, -0xC8, 0x3E, 0x20, 0xFF, 0x00, 0x00, 0x2C, 0x10, 0x1F, 0x40, 0x37, 0x00, 0x91, -0x00, 0x04, 0x00, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0x4C, 0x01, 0x44, 0x05, 0xB0, -0x04, 0x40, 0x24, 0x00, 0x4B, 0x04, 0x24, 0x83, 0x14, 0x71, 0x40, 0x6F, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x40, 0x00, 0x01, 0x00, 0x34, -0x83, 0x14, 0x3C, 0x41, 0xA3, 0x10, 0xCD, 0x00, 0x14, 0x01, 0xD0, 0x9C, 0x40, -0x35, 0x08, 0xCD, 0x01, 0x04, 0x08, 0x50, 0xBC, 0x60, 0x32, 0x00, 0x05, 0x00, -0x14, 0x01, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x49, 0x03, 0x14, 0x8C, 0xD1, 0xB4, -0x41, 0x31, 0x00, 0x00, 0x00, 0x04, 0x23, 0x10, 0x48, 0x40, 0x0F, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x61, 0x01, 0xB4, 0x07, -0x10, 0x16, 0x40, 0x6B, 0x00, 0xED, 0x01, 0x96, 0x06, 0xD0, 0x1E, 0x40, 0x7A, -0x00, 0xC5, 0x41, 0x84, 0x47, 0x10, 0x1E, 0x68, 0x7B, 0x00, 0xF1, 0x00, 0x84, -0x05, 0x50, 0x9A, 0x40, 0x7B, 0x02, 0x7D, 0x01, 0xC4, 0x14, 0x90, 0x1A, 0x48, -0x79, 0x20, 0x39, 0x09, 0x85, 0x27, 0x15, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x34, 0x02, 0x43, 0x04, 0x34, 0x03, 0x10, -0x0C, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x1C, 0x02, 0xF0, 0x0C, 0xC0, 0x31, 0x00, -0xCD, 0x00, 0x0C, 0x03, 0x70, 0xCC, 0xC0, 0x37, 0x42, 0x05, 0x00, 0x1C, 0x11, -0xD0, 0x08, 0xC0, 0x33, 0x00, 0x4B, 0x00, 0x1C, 0x40, 0xF0, 0x8C, 0xC0, 0x31, -0x02, 0xC3, 0x00, 0x6C, 0x23, 0x30, 0x88, 0xE0, 0x4B, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x7F, 0x00, 0xBC, 0x03, 0x70, 0x07, -0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x0C, 0xC0, 0xBF, 0x20, 0xDF, -0x00, 0x3C, 0x03, 0xC0, 0x8F, 0xC8, 0x37, 0x08, 0xFF, 0x8C, 0x7C, 0x01, 0xF0, -0x09, 0xC0, 0x3F, 0x00, 0xFF, 0x48, 0x1C, 0x11, 0xF0, 0x89, 0xC0, 0x3A, 0x00, -0xBF, 0x00, 0xFC, 0x23, 0xF2, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0x17, 0x00, 0xDF, 0x01, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, -0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC4, 0x74, 0x03, 0xD1, 0x0E, -0x7C, 0x80, 0x70, 0x6D, 0xE0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0x70, 0x1D, -0xC0, 0x36, 0x00, 0x5B, 0x00, 0x7C, 0x04, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x97, -0x00, 0x4C, 0x03, 0x34, 0x01, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x80, 0x19, 0x00, 0xED, 0x00, 0x84, 0x0B, 0xC0, 0x06, 0x40, 0xAB, -0x20, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0xE1, 0x10, 0xB4, -0x03, 0xD0, 0xEE, 0xC0, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x00, 0xD0, 0x4E, 0x40, -0x38, 0x00, 0x61, 0x00, 0xA4, 0x00, 0x10, 0x0E, 0x60, 0x3B, 0x00, 0x2D, 0x00, -0x8D, 0x03, 0xB0, 0x06, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x85, 0x17, 0x50, 0x1E, 0x41, 0x7B, 0x01, -0xED, 0x09, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x78, 0x41, 0xE1, 0x05, 0x94, 0x47, -0x50, 0x1E, 0x02, 0x7B, 0x10, 0xED, 0x01, 0xB4, 0x04, 0xD2, 0xDC, 0x00, 0x7A, -0x24, 0x6D, 0x01, 0xD6, 0x0D, 0xD8, 0x1E, 0x40, 0x7B, 0x04, 0xE5, 0x01, 0xF4, -0x07, 0x10, 0x1A, 0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x28, 0x33, 0x00, 0xCD, 0x1A, 0x04, 0x03, 0xD0, 0x14, 0x40, 0x73, 0x02, 0xCD, -0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x13, 0xD0, -0x0C, 0x48, 0x30, 0x00, 0xDD, 0x01, 0x34, 0x06, 0xD0, 0x8C, 0x40, 0x30, 0x00, -0x45, 0x08, 0x34, 0x0D, 0xD0, 0x8C, 0x40, 0x73, 0x00, 0xCD, 0x01, 0x04, 0x03, -0x17, 0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, -0x1D, 0x06, 0x7D, 0x03, 0x6C, 0x01, 0xF0, 0x17, 0xC0, 0x17, 0x00, 0x5F, 0x00, -0xF4, 0x2D, 0x70, 0x04, 0xC4, 0x14, 0x10, 0x53, 0x80, 0xFC, 0x0D, 0x71, 0x05, -0xC0, 0x17, 0x00, 0x7F, 0x07, 0xFC, 0x19, 0xF0, 0x15, 0xC0, 0x56, 0x00, 0x6F, -0x02, 0xFC, 0x05, 0xF0, 0x27, 0xC8, 0x1F, 0x20, 0x67, 0x07, 0xFC, 0x01, 0x10, -0x97, 0xC2, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, -0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC1, 0x87, 0x00, 0x1F, 0x80, 0x7C, -0x20, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0, -0x05, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x19, 0x50, -0x6C, 0x18, 0x10, 0x21, 0xC1, 0xC7, 0x08, 0x1B, 0x30, 0x7E, 0x0C, 0xF0, 0x81, -0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, -0x9F, 0x44, 0x7E, 0x0A, 0xF0, 0x09, 0xD0, 0x64, 0x10, 0x9F, 0x00, 0x7C, 0x06, -0x30, 0x09, 0xD0, 0x24, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, -0x00, 0x93, 0xC0, 0x4C, 0x42, 0xF0, 0x29, 0xC0, 0x26, 0x00, 0x93, 0x80, 0x5C, -0x0A, 0xF0, 0x19, 0xC0, 0x65, 0x00, 0x9F, 0x00, 0x5C, 0x26, 0x30, 0x29, 0xC0, -0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x9D, -0x47, 0x74, 0x06, 0xD0, 0x48, 0x40, 0xEC, 0x10, 0x9D, 0x00, 0x34, 0x26, 0x10, -0x09, 0xC0, 0x26, 0x10, 0x9D, 0x02, 0x74, 0x1A, 0xD0, 0x09, 0x44, 0x27, 0x00, -0x91, 0x40, 0x4C, 0x02, 0x78, 0x1B, 0x40, 0x23, 0x00, 0x91, 0x10, 0x44, 0x0E, -0xD0, 0x08, 0x42, 0x20, 0x10, 0x9B, 0x40, 0x0C, 0x1E, 0x54, 0x09, 0xC0, 0x07, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, -0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, -0x40, 0x24, 0x00, 0x99, 0x10, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x23, 0x00, 0x91, -0x00, 0x64, 0x02, 0xD1, 0x29, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x02, 0x50, -0x4D, 0x40, 0x25, 0x02, 0x94, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x63, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x05, 0x8D, 0x14, 0x34, -0x02, 0xD0, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x08, 0x74, 0x0A, 0x10, 0x28, 0x40, -0x22, 0x02, 0x8D, 0x08, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x02, 0x81, 0x08, -0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x02, 0x91, 0x40, 0x04, 0x02, 0xD2, 0x09, -0x40, 0x24, 0x00, 0x99, 0x00, 0x46, 0x22, 0x51, 0x48, 0x44, 0x43, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F, 0x04, 0x74, 0xD0, -0xF0, 0x01, 0xC0, 0x54, 0x10, 0x1F, 0x16, 0x7E, 0x00, 0x34, 0x01, 0x40, 0x84, -0x05, 0x19, 0x96, 0x7C, 0x00, 0xF0, 0x41, 0xC1, 0x87, 0x00, 0x13, 0x02, 0x6D, -0x80, 0xD0, 0x11, 0x40, 0x83, 0x40, 0x13, 0x00, 0x54, 0x01, 0x70, 0x05, 0xC0, -0x15, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x30, 0x05, 0xC0, 0x77, 0xE0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x25, 0xAF, 0x20, 0x7C, 0x02, 0xF0, -0x0B, 0xC8, 0xAF, 0x00, 0x9D, 0x04, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x27, 0x09, -0x9F, 0x04, 0xFC, 0x02, 0xF2, 0x09, 0xC2, 0x27, 0x41, 0xBF, 0x04, 0xFC, 0x02, -0x50, 0x2B, 0xC0, 0x2F, 0x01, 0xBF, 0x00, 0xB4, 0x02, 0xF2, 0x0B, 0xC0, 0x2F, -0x00, 0xA7, 0x00, 0xBC, 0x12, 0xF4, 0x8B, 0xC0, 0x75, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B, -0xD0, 0x6C, 0x04, 0x91, 0x24, 0xFC, 0x0A, 0xF0, 0x2B, 0xD0, 0x24, 0x00, 0xBF, -0x00, 0x9E, 0x02, 0xF0, 0x4B, 0xC0, 0x26, 0x00, 0x9F, 0x08, 0x7C, 0x82, 0x34, -0x5B, 0xD1, 0x24, 0x02, 0xBF, 0x00, 0xEC, 0x02, 0xF2, 0x0B, 0xC0, 0x2E, 0x80, -0xA7, 0x00, 0xCE, 0x83, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x00, 0x07, 0x11, 0x1D, 0x08, 0x74, 0x08, 0xD0, 0x01, 0x40, -0x84, 0x00, 0x11, 0x14, 0x74, 0x04, 0xD0, 0x51, 0x40, 0x84, 0x04, 0x0D, 0x10, -0x76, 0x00, 0xD1, 0x01, 0x00, 0x04, 0x01, 0x1D, 0x04, 0x74, 0x00, 0x19, 0x21, -0x40, 0x04, 0x00, 0x19, 0x00, 0x5C, 0x00, 0xD2, 0x01, 0x40, 0x04, 0x10, 0x1D, -0x00, 0x05, 0x00, 0xB4, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x00, 0x34, 0x22, 0xD0, 0x09, 0x40, 0x20, -0x00, 0x81, 0x0C, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x20, 0x83, 0x8D, 0x08, 0x14, -0x02, 0xD3, 0x88, 0x00, 0x22, 0x05, 0x8D, 0x04, 0x74, 0x02, 0x10, 0x08, 0x40, -0x20, 0x10, 0x8D, 0x00, 0x36, 0x82, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x95, 0x00, -0x54, 0x02, 0x14, 0x0C, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x2A, 0x25, 0x86, 0x9D, 0x20, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x24, 0x00, -0x91, 0x20, 0x74, 0x02, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x74, 0x42, -0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x44, 0x24, -0x01, 0x9D, 0x02, 0x55, 0x0B, 0xD1, 0x89, 0x40, 0xE4, 0x00, 0x9D, 0x03, 0x54, -0x2A, 0x90, 0x2D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x02, 0x25, 0x10, 0x9F, 0x12, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93, -0x00, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x2A, 0xF0, -0x09, 0xC2, 0x26, 0x00, 0x9F, 0x00, 0x3E, 0x3A, 0x10, 0x99, 0xC8, 0x24, 0x20, -0x8F, 0x4B, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0xA6, 0x80, 0x87, 0x01, 0x54, 0x02, -0x31, 0x09, 0xE0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, -0x25, 0x0C, 0x9F, 0x84, 0x7C, 0x02, 0xF8, 0x09, 0xE0, 0x23, 0x41, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x06, 0xF8, 0x19, 0xC4, 0x67, 0x00, 0x9B, -0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE8, 0x27, 0x88, 0x9F, 0x00, 0x6C, 0x06, 0xD1, -0x48, 0xD8, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, -0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF8, 0x41, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x7C, -0x00, 0x70, 0x41, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0xC8, 0x71, 0x01, 0x41, -0x06, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC1, 0x07, 0x20, 0x1F, 0x30, -0x5C, 0x10, 0x70, 0xC1, 0xC8, 0x87, 0x20, 0x1F, 0x10, 0x4C, 0x10, 0x32, 0x41, -0xC4, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xDC, 0x04, -0x7D, 0x07, 0x74, 0x15, 0x78, 0x76, 0xC0, 0x1C, 0x00, 0x51, 0x00, 0x74, 0x01, -0x10, 0x16, 0x45, 0x14, 0x00, 0x71, 0x86, 0xC4, 0x09, 0x12, 0x16, 0x40, 0x17, -0x00, 0x5D, 0x00, 0x74, 0x01, 0x70, 0x36, 0x40, 0x17, 0x10, 0x7D, 0x00, 0xF0, -0x0D, 0x12, 0x36, 0x48, 0xDF, 0x02, 0x7D, 0x04, 0x80, 0x15, 0x50, 0x07, 0x50, -0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF2, 0x00, 0x8D, -0x06, 0x34, 0x07, 0x50, 0x18, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x36, 0x23, 0x50, -0x08, 0x40, 0x32, 0x40, 0xC9, 0x00, 0x04, 0x2F, 0x50, 0xBC, 0x40, 0x33, 0x00, -0xCD, 0x00, 0x14, 0x03, 0x50, 0x28, 0x40, 0x33, 0x80, 0x4D, 0x0A, 0x34, 0x2F, -0x50, 0x1C, 0x40, 0xD3, 0x00, 0xC9, 0x00, 0x04, 0x0B, 0x11, 0x0C, 0x40, 0x40, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x80, 0xAD, 0x00, -0xB4, 0x03, 0x50, 0x02, 0x40, 0x28, 0x00, 0xE1, 0x00, 0xB4, 0x17, 0x18, 0x0E, -0x40, 0x70, 0x02, 0xE9, 0x01, 0xC4, 0x07, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0xED, -0x08, 0xB4, 0x03, 0x50, 0x22, 0x40, 0x3B, 0xB0, 0x6D, 0x00, 0xB6, 0x07, 0x11, -0x06, 0x40, 0x1B, 0x8C, 0xFD, 0x00, 0x85, 0x03, 0x10, 0x0C, 0x40, 0x10, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC, -0x07, 0x70, 0x12, 0xC0, 0x68, 0x00, 0xE3, 0x01, 0xFC, 0x0F, 0x70, 0x1A, 0xD0, -0x7A, 0x01, 0xE9, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xE8, 0x7B, 0x03, 0xEF, 0x01, -0xBC, 0x07, 0x70, 0x12, 0xC0, 0x7B, 0x25, 0x6F, 0x01, 0x9E, 0x06, 0x70, 0x1A, -0xC0, 0x6B, 0x00, 0xEF, 0x01, 0x8C, 0x06, 0x34, 0x1E, 0xC0, 0x50, 0x60, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x00, 0x7C, 0x03, -0x70, 0x00, 0xC0, 0x21, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0xF2, 0x0C, 0xC0, 0x37, -0x20, 0xD7, 0x80, 0x7C, 0x01, 0xF2, 0x0D, 0xC0, 0x37, 0x02, 0xDF, 0x10, 0x78, -0x03, 0x70, 0x01, 0xC2, 0x37, 0x1A, 0x1F, 0x80, 0x3C, 0x02, 0xF0, 0x05, 0xC0, -0x27, 0x20, 0xDF, 0x00, 0x7C, 0x02, 0xF6, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xA3, 0x01, 0xCC, 0x13, 0xF8, -0x03, 0xC0, 0x6D, 0x00, 0xFF, 0x11, 0xBC, 0x07, 0x20, 0xDB, 0xC0, 0x7C, 0x00, -0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xD0, 0x7C, 0x00, 0xDF, 0x09, 0xFC, 0x07, -0xF0, 0x13, 0xC0, 0x7F, 0x20, 0x2F, 0x09, 0xEE, 0x17, 0xF0, 0x1F, 0xC0, 0x5F, -0x00, 0xFF, 0x01, 0x8C, 0x05, 0x30, 0xDB, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0xA1, 0x00, 0x84, 0x03, 0x78, 0x42, -0x40, 0x28, 0x02, 0xED, 0x00, 0xB4, 0x13, 0x10, 0x8A, 0x50, 0x38, 0x11, 0x2D, -0x04, 0x8C, 0x1A, 0xD0, 0x8A, 0x40, 0x38, 0x00, 0xED, 0x05, 0xB4, 0x03, 0x90, -0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00, 0x9E, 0x03, 0xD0, 0x0E, 0x40, 0x9B, 0x22, -0xAD, 0x04, 0xAC, 0x01, 0x10, 0xCE, 0x48, 0x55, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0xA1, 0x00, 0x85, 0x23, 0x50, 0x82, 0x43, -0x29, 0x00, 0xED, 0x00, 0xF4, 0x02, 0x10, 0x4B, 0x48, 0x38, 0x80, 0x6D, 0x80, -0x84, 0x03, 0xD2, 0x06, 0x00, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x02, -0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x12, 0xD0, 0x0A, 0x40, 0x9B, 0x00, 0xF5, -0x10, 0xD4, 0x20, 0x10, 0xC2, 0x44, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x28, 0xC3, 0x00, 0x01, 0x01, 0x00, 0x02, 0x50, 0x30, 0x40, 0x20, -0x00, 0xCD, 0x00, 0x34, 0x22, 0x10, 0x08, 0x40, 0x30, 0x00, 0x1D, 0x00, 0x04, -0x4C, 0xD0, 0x00, 0x40, 0x30, 0x00, 0xCD, 0x04, 0x34, 0x43, 0xD0, 0x00, 0x40, -0x77, 0x00, 0x0D, 0x12, 0x14, 0xC6, 0xD9, 0x8C, 0x40, 0x13, 0x00, 0x8D, 0x23, -0x05, 0x03, 0x14, 0x24, 0x40, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0xE5, 0x41, 0x93, 0x0A, 0x4C, 0x03, 0x70, 0x35, 0xC0, 0x35, 0x00, -0xFF, 0x00, 0x74, 0x02, 0x34, 0x08, 0xC0, 0x3C, 0x00, 0x9F, 0x00, 0x4C, 0x4E, -0xF0, 0x09, 0xC0, 0x3C, 0x00, 0xFF, 0x13, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x3F, -0x01, 0x5F, 0x01, 0x4C, 0x07, 0xF1, 0xBD, 0xC0, 0xB7, 0x00, 0xD7, 0x03, 0x14, -0x4F, 0x30, 0x94, 0xC0, 0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x08, 0x27, 0x00, 0x9F, 0x88, 0x7C, 0x03, 0x70, 0x21, 0xC0, 0xB7, 0x00, 0xDF, -0x00, 0x7C, 0x42, 0xF0, 0x29, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x5D, 0x02, 0xF0, -0x00, 0xC4, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x03, 0xB0, 0x25, 0xE4, 0x37, 0x00, -0x5F, 0x01, 0x4D, 0x23, 0xF0, 0x05, 0xC0, 0xF7, 0x00, 0xDF, 0x02, 0x7C, 0x1B, -0xF0, 0x3D, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, -0x27, 0x04, 0xFF, 0x02, 0xFC, 0x03, 0xF0, 0x17, 0xC1, 0x6B, 0x00, 0xF7, 0x00, -0xFC, 0x07, 0xD0, 0x1B, 0xC0, 0x3C, 0x08, 0x1F, 0x00, 0xCC, 0x02, 0xF0, 0x09, -0xC0, 0x3D, 0x80, 0xFF, 0x80, 0xCC, 0x03, 0xF8, 0x13, 0xC0, 0x3D, 0x00, 0xF3, -0x00, 0xFC, 0x26, 0xF0, 0x03, 0xCC, 0x2F, 0x00, 0xF7, 0x10, 0xCC, 0x02, 0x30, -0x11, 0xC8, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66, -0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x17, 0x00, 0xD1, 0x80, 0x74, -0x07, 0xD0, 0x39, 0x50, 0x34, 0x00, 0x1D, 0x09, 0x44, 0x0C, 0xD0, 0x11, 0x40, -0x34, 0x80, 0xDD, 0x00, 0x44, 0x03, 0xD8, 0x00, 0xC1, 0x34, 0x40, 0x11, 0x03, -0x72, 0x0E, 0x70, 0x05, 0x41, 0x23, 0x00, 0xCB, 0x22, 0x44, 0x64, 0x14, 0x39, -0xC0, 0x06, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x0C, -0x9D, 0x00, 0x74, 0x03, 0xD0, 0x45, 0x41, 0xB7, 0x01, 0xD5, 0x00, 0x74, 0x12, -0xD0, 0x81, 0x40, 0x36, 0x00, 0xDD, 0x02, 0x44, 0x04, 0xD2, 0x19, 0x41, 0x34, -0x00, 0xCD, 0x00, 0x44, 0x03, 0xD0, 0x45, 0x40, 0x36, 0x20, 0x51, 0x11, 0x64, -0x03, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x51, 0x02, 0x44, 0x01, 0x10, 0x41, 0x40, -0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x8D, -0x00, 0x34, 0x03, 0xD0, 0x04, 0x40, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, -0x00, 0x40, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x00, 0xD2, 0x00, 0x40, 0x30, 0x00, -0xCD, 0x10, 0x04, 0x03, 0xD0, 0x04, 0x60, 0x30, 0x00, 0x41, 0x20, 0x34, 0x01, -0x50, 0x08, 0x40, 0x37, 0x80, 0x09, 0x00, 0x45, 0x00, 0x10, 0x0C, 0x44, 0x42, -0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF2, 0x01, -0xD0, 0x36, 0x00, 0x5F, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xD0, 0x3C, 0x20, 0xFD, -0x00, 0x4D, 0x03, 0xD0, 0x05, 0xC0, 0x3F, 0x10, 0x53, 0x20, 0x74, 0x83, 0xF0, -0x01, 0xC8, 0x37, 0x80, 0x57, 0x00, 0x4C, 0x00, 0x31, 0x01, 0xC0, 0x04, 0x44, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0x7F, 0x00, 0xFC, -0x02, 0xF0, 0x06, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x02, 0xC0, -0x3D, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x03, 0x82, 0x3F, 0x10, 0xFF, 0x80, -0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x03, -0xC0, 0x3F, 0x00, 0x2D, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0x80, 0x14, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xF3, 0x09, 0x8C, 0x07, -0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7F, -0x02, 0xFF, 0x09, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x02, 0xEF, 0x01, 0xCC, -0x07, 0xF0, 0x1E, 0x40, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0, -0x3C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0x40, 0x11, 0x00, 0x45, 0x04, 0xD0, -0x11, 0x52, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x01, -0x1D, 0x04, 0x74, 0x10, 0xD0, 0x40, 0xC0, 0x06, 0x01, 0x1D, 0x81, 0x44, 0x04, -0xD0, 0x11, 0x40, 0x74, 0x08, 0x51, 0x21, 0x44, 0x07, 0x10, 0x15, 0x42, 0x74, -0x00, 0xD1, 0x00, 0x44, 0x07, 0x10, 0x19, 0x48, 0x07, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x04, 0x14, 0x03, 0xD0, 0x0D, -0x60, 0x30, 0x05, 0xCD, 0x14, 0x34, 0x03, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xC5, -0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, -0x0C, 0x40, 0x32, 0x00, 0x81, 0x00, 0x04, 0x02, 0x50, 0x0C, 0x40, 0x32, 0x00, -0xC5, 0x00, 0x44, 0x02, 0x14, 0x0C, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA8, 0x05, 0x00, 0x01, 0x40, 0x54, 0x00, 0xD0, 0x01, 0x60, -0x04, 0x30, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20, -0x74, 0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x80, 0xC0, 0x01, -0x40, 0x36, 0x00, 0xD1, 0x00, 0x44, 0x43, 0xD0, 0xAD, 0x40, 0x36, 0x04, 0xC5, -0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA0, 0x33, 0x00, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, -0x00, 0xDF, 0x80, 0x7C, 0x83, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, -0x03, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0x40, -0x86, 0x04, 0xD3, 0x09, 0x4C, 0x25, 0xF0, 0x3D, 0xC0, 0x26, 0x00, 0xD7, 0x09, -0x0D, 0x03, 0x30, 0x09, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x07, 0x88, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, -0x3F, 0x00, 0xF4, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, -0xA0, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x19, -0x00, 0xCF, 0x21, 0xBC, 0x01, 0x30, 0x16, 0xC2, 0x39, 0x02, 0xFB, 0x00, 0xFC, -0x13, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x08, 0x35, 0x00, 0xDF, 0x05, 0x7C, 0x03, 0x32, 0x0D, 0xC2, 0x37, 0x00, 0xDF, -0x00, 0x4C, 0x07, 0xF0, 0x0D, 0xC0, 0x77, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0, -0x0D, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0xB5, 0x00, -0x93, 0x00, 0x4C, 0x0A, 0x70, 0x0D, 0xC2, 0xA4, 0x00, 0xD7, 0x00, 0x4C, 0x02, -0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x04, 0x10, 0x1D, 0x01, 0x74, 0x00, 0x14, 0xB0, 0x40, 0x07, 0x00, 0x1D, 0x00, -0x44, 0x04, 0xC1, 0xA1, 0x42, 0x07, 0x00, 0x1D, 0x01, 0x74, 0x84, 0xD0, 0xE1, -0x40, 0x44, 0x00, 0x0D, 0x00, 0x44, 0x00, 0xB0, 0x00, 0x40, 0x34, 0x00, 0xD1, -0x80, 0x44, 0x13, 0x10, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x0A, 0x44, 0x46, 0xD0, -0x1D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30, -0x00, 0xCD, 0x02, 0x34, 0x03, 0x10, 0x3C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04, -0x1B, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x10, 0x34, 0x03, 0xD0, 0x0D, 0x40, -0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x44, 0x30, 0x00, 0xC1, 0x00, -0x04, 0x83, 0x14, 0x08, 0x40, 0x12, 0x00, 0xC4, 0x00, 0x04, 0x03, 0xD0, 0x1C, -0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, -0x2D, 0x09, 0xF4, 0x24, 0x10, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x00, 0x84, 0x24, -0xD0, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x0C, 0xD0, 0x12, 0x60, 0xC8, -0x00, 0x2D, 0x01, 0xC4, 0x04, 0xD2, 0x32, 0x40, 0x70, 0x00, 0x61, 0x01, 0x05, -0x07, 0x10, 0x1C, 0x40, 0x7A, 0x00, 0xED, 0x01, 0x84, 0x07, 0xD1, 0x1A, 0x60, -0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xCF, -0x00, 0x3C, 0x03, 0x30, 0x0C, 0xC3, 0x33, 0x02, 0xCF, 0x08, 0x0C, 0x03, 0xF0, -0x0C, 0xC2, 0x32, 0x00, 0xCD, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00, -0xCF, 0x00, 0x0C, 0x03, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC3, 0x04, 0x0C, 0x03, -0x70, 0x0C, 0xC0, 0x32, 0x00, 0xD7, 0x00, 0x0D, 0x03, 0xF2, 0x8C, 0x51, 0x48, -0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0F, 0x08, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03, -0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, -0x40, 0xBC, 0x00, 0xB0, 0x13, 0xC4, 0x3F, 0x02, 0xFF, 0x00, 0xFE, 0x03, 0xF2, -0x0F, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC2, 0x0B, 0xE0, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x00, 0xDF, 0x01, 0x0D, -0x07, 0x34, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x07, 0x3C, 0x0D, 0xC0, -0x77, 0x00, 0xD7, 0x01, 0x4D, 0x87, 0x34, 0x1D, 0xC0, 0x75, 0x40, 0xD3, 0x00, -0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xB8, 0x09, -0xC0, 0x54, 0x00, 0xDB, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x41, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x90, 0x08, 0x00, 0x2D, 0x00, 0x84, 0x00, -0x18, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xD4, 0x00, 0x10, 0x02, 0x40, 0x0F, -0x00, 0x31, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x0C, 0x00, 0x21, 0x00, 0x9C, -0x80, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xE1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x42, -0x38, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4B, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xC4, 0x87, 0x12, -0x1E, 0x60, 0x7B, 0x80, 0xE9, 0x01, 0x84, 0x07, 0x10, 0x1E, 0x42, 0x7B, 0x20, -0xE5, 0x01, 0xA0, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0x94, 0x07, -0xD0, 0x1F, 0x40, 0x72, 0x08, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x40, 0x70, -0x00, 0xE1, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x16, 0x20, 0x03, 0x00, 0x0D, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x03, 0x00, 0x0D, 0x00, 0x14, 0x00, 0x18, 0x00, 0x40, 0x03, 0x00, 0x01, -0x00, 0x24, 0x00, 0x10, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00, 0x14, 0x00, 0xD0, -0x00, 0x40, 0x33, 0x40, 0xC1, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x50, 0x30, 0x52, -0x91, 0x48, 0x04, 0x02, 0xD0, 0x1C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x05, 0xC0, -0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x04, 0xC0, 0x17, 0x10, 0x57, 0x00, -0x64, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05, -0xC0, 0x1E, 0x00, 0x73, 0x02, 0xCC, 0x09, 0x30, 0x07, 0xC0, 0x5C, 0x00, 0x53, -0x01, 0x4C, 0x01, 0xF2, 0x05, 0xC1, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, -0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDC, -0x00, 0xF0, 0x23, 0xC0, 0x0D, 0x20, 0x37, 0x02, 0xDC, 0x00, 0xF0, 0x03, 0xE2, -0x41, 0x00, 0x0F, 0x10, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x02, -0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x25, 0x00, 0x9F, 0x05, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x24, 0x01, 0x9F, 0x01, 0x5C, 0x02, -0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27, -0x20, 0x93, 0x20, 0x0C, 0x02, 0x34, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x05, 0x4C, -0x06, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x26, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x90, 0x49, 0x48, 0x27, 0x00, 0x9D, -0x00, 0x74, 0x0A, 0xD9, 0x39, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x0A, 0xD0, -0xD9, 0x40, 0xA7, 0x80, 0x9F, 0x12, 0x34, 0x02, 0xB0, 0x09, 0x40, 0xA7, 0x20, -0x91, 0x82, 0x44, 0x0A, 0x30, 0x29, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x44, 0x06, -0xD0, 0x08, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, -0x24, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB5, 0x00, -0xF4, 0x02, 0xD0, 0x0B, 0x60, 0x2C, 0x00, 0xBD, 0x08, 0xF6, 0x06, 0xD0, 0x0B, -0x40, 0x6F, 0x10, 0xBD, 0x00, 0xF4, 0x02, 0x50, 0x1B, 0x42, 0x27, 0x04, 0x91, -0x10, 0x64, 0x42, 0x00, 0x09, 0x41, 0x24, 0x84, 0x9D, 0x00, 0x64, 0x22, 0xD0, -0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x28, -0x00, 0xAD, 0x01, 0xB4, 0x02, 0x91, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, -0x06, 0xD0, 0x0B, 0x42, 0x29, 0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x0A, 0x60, -0x6B, 0x00, 0xA5, 0x00, 0xF4, 0x02, 0xD2, 0x0A, 0x60, 0x23, 0x41, 0x81, 0x04, -0x24, 0x92, 0x90, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x40, 0x24, 0x02, 0xD0, 0x09, -0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x00, -0x0F, 0x0A, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x12, 0x17, 0x0A, 0x7C, 0x28, -0xD0, 0xA5, 0xD0, 0x84, 0x02, 0x1D, 0x0A, 0x5C, 0x28, 0xF0, 0xA0, 0xC0, 0x87, -0x02, 0x1D, 0x00, 0x7C, 0x00, 0x60, 0x03, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x65, -0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x5F, 0x0A, 0x6C, 0x00, 0xF0, 0x01, 0xC0, -0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F, -0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x2F, 0x02, 0xBF, 0x08, 0xDC, 0x22, -0x70, 0x8B, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xDD, 0x02, 0xF0, 0x0B, 0xC0, 0x77, -0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x27, 0x00, 0xB3, 0x00, -0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x0A, -0xC0, 0x2D, 0x02, 0xB7, 0x00, 0xFE, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x00, 0x9F, -0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0x9F, 0x00, 0x6D, 0x12, 0x30, -0x49, 0xC1, 0x24, 0x01, 0xB3, 0x00, 0xCC, 0x03, 0xF0, 0x0B, 0xC0, 0x73, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, 0x00, 0x11, 0x04, 0x45, -0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x45, 0x50, 0x70, 0x41, 0x40, -0x04, 0x01, 0x11, 0x10, 0x74, 0x40, 0xD1, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x00, -0x74, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x08, 0x44, 0x00, 0x10, 0x01, -0x40, 0x0C, 0x12, 0x01, 0x10, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x63, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x40, 0x81, 0x14, 0x04, 0x02, -0xD0, 0x08, 0x40, 0x20, 0x00, 0x9D, 0x00, 0x04, 0x12, 0xD0, 0x48, 0x41, 0x21, -0x21, 0x85, 0x04, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0xAD, 0x00, 0xB4, -0x03, 0xD0, 0x0B, 0x40, 0x6A, 0x02, 0xAD, 0x01, 0x84, 0x26, 0x10, 0x1A, 0x40, -0x68, 0x00, 0x99, 0x04, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x4B, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x02, 0xD0, -0x09, 0x40, 0x24, 0x80, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, -0x91, 0x80, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x82, -0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x0B, 0x40, 0x2C, -0x10, 0x99, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x93, 0x00, 0x48, 0x02, 0xF0, 0x08, -0xC0, 0x24, 0x00, 0x9F, 0x20, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x95, -0x00, 0x74, 0x02, 0xE0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x40, 0x7E, 0x02, 0xF0, -0x09, 0xC0, 0xA6, 0x02, 0x9F, 0x03, 0x4C, 0x2A, 0x34, 0xB9, 0xC0, 0xA4, 0x00, -0x8B, 0xA0, 0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x17, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x08, 0x24, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xD0, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x25, 0x00, 0x9F, 0x03, 0x5C, 0x06, 0xF0, 0x19, 0xD0, 0x27, 0x40, 0x97, -0x20, 0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x13, 0x10, 0x7C, 0x00, 0xF2, 0x81, 0xD1, 0x06, 0x00, 0x1F, 0x00, 0x7C, -0x60, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, -0x07, 0x00, 0x03, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x1F, 0x00, -0x4D, 0x04, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x10, 0x00, 0x7D, 0x00, 0x76, 0x45, 0xD0, 0x07, 0xC0, 0x15, 0x20, -0x65, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xD0, 0x16, 0x00, 0x77, 0x00, 0xF4, 0x09, -0xD2, 0x07, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x14, 0x04, 0xC0, 0x15, -0x00, 0x51, 0x01, 0x74, 0x01, 0xD0, 0x15, 0x40, 0x57, 0x10, 0x7D, 0x41, 0xC4, -0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA0, 0x32, 0x00, 0xDD, 0x40, 0x34, 0x07, 0xD0, 0x04, 0x40, 0x31, 0x80, 0x49, -0x00, 0x34, 0x4B, 0xD0, 0x3D, 0x40, 0x36, 0x30, 0xCD, 0x00, 0x34, 0x07, 0xD8, -0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00, -0xC1, 0x21, 0x34, 0x03, 0xD0, 0x1C, 0x40, 0x73, 0x00, 0xCD, 0x00, 0x04, 0x07, -0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, -0x38, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x79, 0x02, 0x6D, 0x10, -0xB6, 0x03, 0xD0, 0x0E, 0x58, 0x2A, 0x00, 0x6D, 0x00, 0xB4, 0x01, 0xD9, 0x02, -0x40, 0x1B, 0x00, 0xAD, 0x00, 0xB4, 0x07, 0x10, 0x06, 0x40, 0x71, 0x40, 0xE1, -0x10, 0xB4, 0x02, 0xD0, 0x0E, 0x41, 0x3B, 0x04, 0xED, 0x02, 0x84, 0x43, 0xD0, -0x0A, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, -0x00, 0xAF, 0x01, 0xB4, 0x07, 0xD0, 0x16, 0xC0, 0x7D, 0x00, 0x6B, 0x01, 0xBC, -0x06, 0xF0, 0x16, 0xD0, 0x7A, 0x00, 0xAF, 0x01, 0xB4, 0x06, 0xF0, 0x1E, 0xC0, -0x6B, 0x00, 0x6F, 0x01, 0xB8, 0x07, 0x30, 0x1A, 0xC0, 0x59, 0x00, 0x63, 0x01, -0xBC, 0x05, 0xF0, 0x16, 0xC0, 0x5B, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1E, -0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, -0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x75, 0x20, 0x57, 0x00, 0x7C, 0x00, -0xF0, 0x05, 0xD0, 0x27, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC2, 0x15, 0x00, 0x5F, 0x00, 0x7C, -0x00, 0xF8, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x00, 0xFF, -0x01, 0xBC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x00, 0xB3, 0x89, 0xCC, 0x05, 0xA0, -0x1B, 0xC0, 0x7F, 0x20, 0xF3, 0x01, 0xDC, 0x07, 0x30, 0x1F, 0xC0, 0x7C, 0x00, -0xF3, 0x01, 0xCC, 0x06, 0xF2, 0x1F, 0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xCC, 0x07, -0xF0, 0x1B, 0xC0, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x05, 0x30, 0x1F, 0xC0, 0x1B, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x6D, 0x00, -0x9C, 0x03, 0x18, 0x0A, 0x40, 0x38, 0x00, 0xA1, 0x00, 0xC4, 0x03, 0x11, 0x0A, -0x40, 0x2B, 0x00, 0x71, 0x00, 0xC4, 0x02, 0x10, 0x02, 0x40, 0x1C, 0x00, 0xA1, -0x00, 0x84, 0x0A, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0, -0x0A, 0x40, 0x28, 0x12, 0xE1, 0x00, 0xB4, 0x00, 0xB0, 0x0E, 0x40, 0x57, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0xB4, -0x03, 0x50, 0x87, 0x40, 0x3C, 0x00, 0xB1, 0x00, 0x84, 0x20, 0x10, 0x02, 0x40, -0xBF, 0x00, 0xA9, 0x00, 0x84, 0x01, 0x10, 0x0F, 0x40, 0x2A, 0x00, 0x79, 0x02, -0x84, 0x02, 0xD0, 0x0A, 0x40, 0x1B, 0x00, 0x0D, 0x00, 0x84, 0x01, 0xD0, 0x80, -0x40, 0x00, 0x00, 0xA1, 0x00, 0xF4, 0x40, 0x10, 0x0E, 0x40, 0x03, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0xF1, 0x00, 0x1D, 0x02, 0x34, 0x43, -0x10, 0x00, 0x41, 0xB0, 0x04, 0x81, 0x04, 0x04, 0x34, 0x91, 0x38, 0x40, 0x23, -0x00, 0x09, 0x0D, 0x04, 0x34, 0x10, 0x00, 0x41, 0x42, 0x43, 0x09, 0x20, 0x04, -0x06, 0xD0, 0x10, 0x40, 0x13, 0x00, 0x0D, 0x12, 0x04, 0x00, 0xD0, 0x00, 0x40, -0x80, 0x00, 0x01, 0x20, 0x34, 0x84, 0x90, 0x0C, 0x40, 0x0B, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xB5, 0x00, 0xDF, 0x05, 0x7C, 0x07, 0x50, -0x24, 0xC0, 0x38, 0x00, 0x93, 0x02, 0x44, 0x0B, 0xB0, 0x05, 0xC0, 0x73, 0x00, -0xD9, 0x02, 0x44, 0x0B, 0x10, 0x2C, 0xC0, 0xB6, 0x00, 0xCB, 0x00, 0x0C, 0x69, -0xF1, 0x2D, 0x41, 0x67, 0x00, 0xDF, 0x03, 0x4D, 0x07, 0xF0, 0xBD, 0xD0, 0x74, -0x40, 0xD3, 0x00, 0x3C, 0x05, 0x30, 0x0D, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x06, 0x9F, 0x10, 0x5C, 0x23, 0x70, 0x1D, -0xC0, 0x77, 0x00, 0x9F, 0x03, 0x7C, 0x02, 0x71, 0x85, 0xC0, 0x37, 0x22, 0x97, -0x02, 0x7C, 0x01, 0xF0, 0x3D, 0xC0, 0x25, 0x00, 0x97, 0x08, 0x7C, 0x01, 0xF0, -0x05, 0xC1, 0x63, 0x00, 0xDF, 0x81, 0x7C, 0x06, 0xF0, 0x1D, 0xC2, 0x77, 0x14, -0xDF, 0x03, 0x7C, 0x01, 0xF0, 0x8D, 0xC2, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0x7F, 0x00, 0xCC, 0x0F, 0xF0, 0x07, 0xC0, -0x3E, 0x00, 0xB3, 0x00, 0xFC, 0x17, 0x32, 0x03, 0xC5, 0x2C, 0x00, 0x73, 0x00, -0xCE, 0x02, 0x30, 0x13, 0xC0, 0x1C, 0x01, 0x72, 0x00, 0xCC, 0x01, 0x30, 0x0B, -0xC0, 0x0F, 0x02, 0x73, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0xFF, -0x00, 0xCC, 0x01, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x81, 0x20, 0x36, 0x00, 0x1D, 0x00, 0x44, 0x03, 0xD0, 0x05, 0x40, 0x34, -0x20, 0x91, 0x09, 0x74, 0x04, 0x10, 0x10, 0x41, 0x24, 0x00, 0x11, 0x02, 0x44, -0x00, 0x10, 0x11, 0x40, 0xC4, 0x01, 0x11, 0x00, 0x44, 0x09, 0x10, 0x01, 0xC0, -0x05, 0x00, 0x51, 0x20, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x10, 0xDD, 0x00, -0x44, 0x05, 0x10, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0xA0, 0x36, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD8, 0x85, 0x40, 0x36, 0x00, -0x91, 0x02, 0x14, 0x01, 0x18, 0x15, 0x40, 0x34, 0x81, 0xC9, 0x06, 0x04, 0x03, -0x10, 0x6D, 0x40, 0x32, 0x80, 0xD5, 0x00, 0x44, 0x00, 0x10, 0x0D, 0x40, 0x27, -0x00, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x86, 0x44, -0x04, 0x10, 0x1D, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0x30, 0x00, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x36, 0x00, 0x81, -0x00, 0x34, 0x02, 0x14, 0x0D, 0x50, 0x34, 0x00, 0x80, 0x00, 0x05, 0x02, 0x14, -0x0D, 0x60, 0x22, 0x40, 0x95, 0xA0, 0x04, 0x00, 0x10, 0x04, 0x40, 0x23, 0x40, -0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x04, -0x14, 0x0C, 0x40, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x36, 0x00, 0x5F, 0x00, 0x4C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0x93, 0x00, -0x7C, 0x01, 0x30, 0x01, 0xC0, 0x24, 0x10, 0x5B, 0x80, 0x46, 0x81, 0x30, 0x01, -0xC0, 0x16, 0x00, 0x57, 0x00, 0x4C, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x00, 0x13, -0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x4D, 0x00, 0x30, -0x0D, 0xC0, 0x03, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, -0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x39, 0x00, 0xAF, 0x80, 0xFC, -0x00, 0xF0, 0x0B, 0xC0, 0x2B, 0x80, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x02, 0xC0, -0x0D, 0x00, 0x2B, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x0F, -0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00, -0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x5D, 0x00, 0x6F, 0x01, 0xCC, 0x06, -0xF1, 0x0F, 0xC0, 0x7C, 0x00, 0x33, 0x03, 0xEC, 0x24, 0xB2, 0xCF, 0xC8, 0x3C, -0x21, 0xFB, 0x84, 0xDC, 0x87, 0xB0, 0x0F, 0x40, 0x5C, 0x02, 0x3F, 0x08, 0xAC, -0x85, 0xB0, 0x0F, 0xC2, 0x5F, 0x00, 0x37, 0x80, 0xCD, 0x06, 0x90, 0x0B, 0x80, -0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0xDD, -0x01, 0x74, 0x00, 0xD0, 0x3D, 0x42, 0x60, 0x00, 0x1D, 0x01, 0x44, 0x06, 0xD2, -0x1D, 0x40, 0x7C, 0x00, 0x11, 0x20, 0x44, 0x10, 0x10, 0xAF, 0x40, 0x7C, 0x02, -0xF1, 0x02, 0x44, 0x07, 0x14, 0x6D, 0x40, 0x04, 0x01, 0x9D, 0x04, 0x54, 0x85, -0x10, 0x9F, 0x00, 0x47, 0x40, 0x93, 0x8B, 0x44, 0x52, 0x10, 0x09, 0x40, 0x0D, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0xCD, 0x00, -0x34, 0x00, 0xD0, 0x2C, 0x40, 0x31, 0x00, 0x4D, 0x00, 0x04, 0x02, 0xD0, 0x0C, -0x60, 0x30, 0x20, 0x10, 0x04, 0x64, 0x10, 0x90, 0x4C, 0x48, 0x30, 0x10, 0xC9, -0x08, 0x34, 0x03, 0x02, 0x2C, 0x45, 0x12, 0x01, 0x0D, 0x00, 0x24, 0x01, 0xD0, -0x0C, 0x42, 0x33, 0x10, 0x09, 0x20, 0x04, 0x03, 0x10, 0x00, 0x40, 0x4D, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x64, 0x00, 0xDD, 0x00, 0x74, -0x04, 0xC0, 0x0D, 0x60, 0x24, 0x00, 0x1D, 0x04, 0x45, 0x02, 0xD0, 0x0D, 0x40, -0x34, 0x08, 0x11, 0x00, 0x64, 0x44, 0x10, 0x0D, 0x48, 0x34, 0x80, 0xD1, 0x00, -0x64, 0x03, 0x50, 0x0D, 0x40, 0x06, 0x04, 0x8D, 0x11, 0x74, 0x85, 0x54, 0x0D, -0x42, 0x07, 0x00, 0x55, 0x08, 0x44, 0x02, 0x10, 0x11, 0x41, 0x0D, 0x20, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x66, 0x00, 0xDF, 0x00, 0x78, 0x4E, -0xE0, 0x0D, 0xC0, 0x25, 0x10, 0x4F, 0x07, 0x4C, 0x22, 0xF0, 0x9D, 0x40, 0x34, -0x40, 0x13, 0x0D, 0x2C, 0x0C, 0xB2, 0x0D, 0xD0, 0x34, 0x10, 0xDB, 0x00, 0x74, -0x03, 0x30, 0x0D, 0x50, 0x06, 0x28, 0x9E, 0x01, 0x6C, 0x14, 0xF0, 0x0D, 0xC0, -0x13, 0x00, 0x1B, 0x03, 0x4C, 0x06, 0x30, 0x19, 0xC0, 0x21, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, -0x0E, 0xC0, 0x2F, 0x00, 0x7F, 0x00, 0xFC, 0x06, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, -0xFF, 0x00, 0xDC, 0x02, 0x70, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xDC, 0x03, -0xB0, 0x0F, 0xC2, 0x0D, 0x10, 0xBD, 0x00, 0xDC, 0x01, 0xB4, 0x0F, 0xC0, 0x8F, -0x50, 0x6B, 0x00, 0xFC, 0x26, 0xF4, 0x0A, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x08, 0x85, 0x02, 0xDF, 0x00, 0x7C, 0x40, 0x30, 0x0D, -0xC0, 0x37, 0x00, 0x57, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0xDF, -0x00, 0x7C, 0x0A, 0xF0, 0x0D, 0xC4, 0x34, 0x0A, 0xDF, 0x00, 0x5C, 0x23, 0x70, -0x0D, 0xC1, 0x15, 0x00, 0x13, 0x02, 0x4C, 0x00, 0x50, 0x0D, 0xC9, 0x36, 0x08, -0x17, 0x12, 0x4D, 0x03, 0xF0, 0x09, 0x82, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x60, 0x70, 0x18, 0x10, 0x0F, 0x40, -0x27, 0x00, 0x51, 0x05, 0x44, 0x4E, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00, -0x74, 0x02, 0xD0, 0xAF, 0x40, 0x38, 0x02, 0xFD, 0x00, 0x34, 0x2B, 0xB0, 0x2E, -0x40, 0x04, 0x40, 0x11, 0x08, 0x2C, 0x03, 0x10, 0x2F, 0x48, 0x04, 0x02, 0x51, -0x00, 0x44, 0x13, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x20, 0xC0, 0x04, 0xCD, 0x00, 0x34, 0x0E, 0x50, 0x0C, 0x40, 0x13, -0x00, 0x05, 0x06, 0x05, 0x0E, 0xD0, 0x08, 0x40, 0xF3, 0x04, 0x0D, 0x00, 0x34, -0x00, 0xD0, 0x0C, 0x60, 0x70, 0x00, 0xCD, 0x07, 0x34, 0x03, 0x10, 0x0C, 0x48, -0x11, 0x80, 0x04, 0x00, 0x04, 0x00, 0x40, 0x3C, 0x40, 0x90, 0x00, 0x49, 0x02, -0x44, 0x13, 0xD1, 0x50, 0x44, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x01, 0x50, 0x1E, 0x40, 0x6B, 0x00, -0x31, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, -0xD0, 0x1C, 0x40, 0x78, 0x00, 0xED, 0x31, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x48, -0x80, 0xE5, 0x01, 0xE4, 0x04, 0x10, 0x9C, 0x40, 0x4C, 0x01, 0xC9, 0x01, 0x84, -0x16, 0xD8, 0x9A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x1A, 0x90, 0x02, 0xCF, 0x00, 0x7C, 0x23, 0x70, 0x0C, 0xC0, 0x33, 0x00, 0x07, -0x04, 0x0C, 0x02, 0xF0, 0x4C, 0xC0, 0x33, 0x01, 0xCD, 0x00, 0x3C, 0x02, 0xF0, -0x8C, 0x40, 0x30, 0x02, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0xDD, 0xC0, 0x15, 0x2A, -0x57, 0x24, 0x0C, 0x61, 0x70, 0x8C, 0xC9, 0x22, 0x90, 0x89, 0x12, 0x0C, 0x03, -0xF0, 0x00, 0xC1, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, -0x3D, 0x08, 0xFF, 0x00, 0xFC, 0x13, 0xB0, 0x0F, 0xC1, 0x2F, 0x00, 0x3F, 0x00, -0xFC, 0x22, 0xF0, 0x0F, 0xC0, 0x77, 0x00, 0xDF, 0x08, 0xFC, 0x23, 0xF0, 0x2D, -0x52, 0x3F, 0x20, 0xDF, 0x00, 0x3C, 0x03, 0xF4, 0x0D, 0xC0, 0x07, 0x20, 0xDB, -0x00, 0x7C, 0x81, 0xF0, 0x8F, 0xC2, 0x0B, 0x81, 0xF7, 0x00, 0xF0, 0x12, 0xF0, -0x03, 0xC2, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x6C, 0x01, 0xF0, 0x0D, 0xC0, -0xB7, 0x00, 0xDF, 0x08, 0x3C, 0x03, 0x31, 0x1D, 0xC8, 0x07, 0x10, 0x9F, 0x00, -0x4F, 0x00, 0xF0, 0x4D, 0xC8, 0x10, 0x08, 0x9B, 0x00, 0x4D, 0x83, 0x30, 0x01, -0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, -0xED, 0x00, 0xB4, 0x03, 0xD3, 0x4E, 0x40, 0x2B, 0x00, 0x2D, 0x00, 0x9C, 0x02, -0xD0, 0x0A, 0x60, 0xBB, 0x10, 0xFC, 0x00, 0x84, 0x03, 0xD0, 0x4E, 0x40, 0xBB, -0x04, 0xED, 0x0C, 0xB4, 0x03, 0x40, 0x2E, 0x40, 0x0B, 0x00, 0xED, 0x20, 0x84, -0x00, 0xD0, 0xAE, 0x40, 0x08, 0x00, 0xE7, 0x00, 0xC4, 0x83, 0x12, 0x0F, 0x40, -0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x59, 0x18, 0xE5, -0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40, 0x7B, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x50, -0x1E, 0x40, 0x7B, 0x01, 0xED, 0x11, 0x84, 0x07, 0xD0, 0xDE, 0x40, 0x7B, 0x01, -0xED, 0x81, 0xB4, 0x07, 0x00, 0x4E, 0x40, 0x5B, 0x20, 0xED, 0x01, 0x94, 0x04, -0xD1, 0x5C, 0x50, 0x69, 0x00, 0x85, 0x01, 0x94, 0x0F, 0x10, 0x16, 0x40, 0x12, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x80, 0xCD, 0x40, -0x34, 0x27, 0xD0, 0x0C, 0x40, 0x23, 0x11, 0x8D, 0x03, 0x14, 0x07, 0xD0, 0x0C, -0x40, 0x33, 0x00, 0xCD, 0x01, 0x04, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x00, 0x34, 0x83, 0x00, 0x0C, 0x44, 0xA3, 0x02, 0xDD, 0x02, 0x04, 0x05, 0xD0, -0x0C, 0x44, 0x01, 0x00, 0xC5, 0x07, 0x14, 0x87, 0x10, 0x6C, 0x40, 0x5A, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x1D, 0x04, 0x5F, 0x00, 0xFC, -0x09, 0xF0, 0x05, 0xC0, 0xDF, 0x01, 0x7F, 0x44, 0x74, 0x45, 0xF8, 0x05, 0xC0, -0x17, 0x00, 0x7F, 0x02, 0xCD, 0x95, 0xF0, 0x05, 0x40, 0x17, 0x00, 0x5F, 0x80, -0x3C, 0x01, 0x31, 0x05, 0xC0, 0x5F, 0x00, 0x7F, 0x02, 0x8C, 0xBD, 0xF1, 0x05, -0xC0, 0x1D, 0x00, 0x67, 0x07, 0x5C, 0x01, 0x36, 0x27, 0xC4, 0x5E, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x04, 0x1F, 0x00, 0x7C, 0x80, -0xF0, 0x01, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x70, 0x00, 0xF9, 0x01, 0xC4, 0x07, -0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x42, 0x7C, -0x08, 0xF4, 0x01, 0xC0, 0x07, 0x01, 0x1D, 0x82, 0x7C, 0x00, 0xF0, 0x01, 0xA0, -0x86, 0x00, 0x16, 0x00, 0x68, 0x08, 0xF2, 0x01, 0xD0, 0x49, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x01, 0x97, 0x00, 0x7C, 0x4E, 0xF8, -0x09, 0xC0, 0x27, 0x00, 0x93, 0x82, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x89, -0x93, 0x80, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x00, 0x7C, 0x16, -0x30, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x39, 0x4C, 0x02, 0x34, 0x29, 0xD8, 0x24, -0x40, 0x91, 0x09, 0x4C, 0x0E, 0x34, 0x08, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x01, 0x9D, 0x00, 0x74, 0x0E, 0xD0, 0x09, -0x60, 0x23, 0x20, 0x91, 0x03, 0x76, 0x06, 0xD0, 0x09, 0x40, 0xEB, 0x81, 0x8B, -0x00, 0x6C, 0x02, 0x50, 0x19, 0xD0, 0x64, 0x12, 0x9D, 0x02, 0x74, 0x02, 0xB0, -0x09, 0xC0, 0x26, 0x00, 0x9D, 0x43, 0x45, 0x2E, 0x10, 0x38, 0x48, 0xA0, 0x11, -0x91, 0x01, 0x44, 0x02, 0x12, 0x29, 0x40, 0x05, 0x80, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x24, 0x18, 0x9D, 0x00, 0x54, 0x0A, 0xD0, 0x09, 0x40, -0x27, 0x00, 0x91, 0x10, 0x74, 0x0E, 0xD1, 0x09, 0x48, 0x25, 0x80, 0x91, 0x00, -0x14, 0x02, 0x10, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x54, 0x0A, 0x90, 0x09, -0x44, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x95, -0x02, 0x25, 0x02, 0x10, 0x49, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x22, 0x20, 0x05, 0x8D, 0x00, 0x34, 0x52, 0xD0, 0x08, 0x40, 0xA7, -0x08, 0x81, 0x00, 0x36, 0x02, 0xDA, 0x08, 0x40, 0x23, 0x00, 0x91, 0x08, 0x04, -0x22, 0x10, 0x8C, 0x60, 0x22, 0x80, 0x8D, 0x24, 0x34, 0x02, 0x94, 0x58, 0x40, -0x22, 0x00, 0x8D, 0x0C, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x24, 0x00, 0x85, 0x00, -0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB8, 0x06, 0x11, 0x1F, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x41, 0x07, 0x40, -0x13, 0x00, 0x76, 0x00, 0xF0, 0x01, 0xC0, 0x47, 0x40, 0x11, 0x02, 0x54, 0x08, -0x34, 0x61, 0xC1, 0x14, 0x15, 0x1F, 0x8A, 0x7C, 0x00, 0xB4, 0xA1, 0xC4, 0x84, -0x02, 0x0F, 0x02, 0x4C, 0x00, 0x30, 0x41, 0xC1, 0x04, 0x00, 0x15, 0x14, 0x6C, -0x09, 0x30, 0xA5, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB8, 0x2F, 0x05, 0x9F, 0x00, 0xFC, 0x52, 0xF0, 0x09, 0xC0, 0x6F, 0x20, 0xBF, -0x00, 0xFC, 0x02, 0xF0, 0x2B, 0xC0, 0xA7, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0, -0x49, 0x42, 0x25, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF4, 0x89, 0xC0, 0x2D, 0x00, -0xBF, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x3F, 0x00, 0xBB, 0x00, 0xDC, 0x12, -0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8, -0x2F, 0x01, 0x9F, 0x00, 0xFC, 0x32, 0xB0, 0x09, 0xC0, 0xA7, 0x20, 0xBF, 0x00, -0xCD, 0x02, 0xF0, 0x49, 0xC5, 0x6F, 0x00, 0x9B, 0x80, 0x6E, 0x02, 0x79, 0x8B, -0xC0, 0x2F, 0x01, 0xBB, 0x14, 0xAC, 0x82, 0x30, 0x0B, 0xCC, 0x21, 0x00, 0xBF, -0x28, 0xCC, 0x82, 0x31, 0x4B, 0xC1, 0x2E, 0x68, 0xA3, 0x00, 0xBC, 0x02, 0xF0, -0x0F, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, -0x05, 0x1D, 0x00, 0x70, 0x31, 0x14, 0x21, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x44, -0x00, 0xD0, 0x01, 0x00, 0x07, 0x00, 0x5A, 0x30, 0x44, 0xC0, 0xD8, 0x81, 0x40, -0x07, 0x00, 0x11, 0x04, 0x51, 0x00, 0x10, 0x01, 0xC0, 0x05, 0x04, 0x5D, 0x08, -0x4C, 0x00, 0x11, 0x01, 0x40, 0x07, 0x30, 0x11, 0x00, 0x64, 0x80, 0xD0, 0x01, -0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03, -0x8D, 0x00, 0x34, 0x12, 0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x80, 0x04, 0x82, -0xD2, 0x08, 0x0A, 0xA3, 0x00, 0x89, 0x04, 0x04, 0x02, 0x50, 0x08, 0x40, 0x23, -0x02, 0x89, 0x14, 0x14, 0x02, 0x14, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x05, -0x02, 0x18, 0x08, 0x48, 0x27, 0x20, 0x85, 0x00, 0x36, 0x02, 0xD0, 0x08, 0x40, -0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0xA5, 0x00, 0x9D, -0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44, 0x02, 0xD0, -0x09, 0x48, 0x26, 0x20, 0x89, 0x00, 0x44, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00, -0x91, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x68, 0x25, 0x10, 0x9D, 0x04, 0x46, 0x02, -0x99, 0x0D, 0x40, 0x27, 0x00, 0xD5, 0x00, 0x64, 0x22, 0xD0, 0x09, 0x41, 0x63, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x65, 0x00, 0x9D, 0x00, -0x7C, 0x06, 0x30, 0x09, 0xC0, 0x2F, 0x06, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9B, 0x02, 0x65, 0x42, 0x72, 0x09, 0xC2, 0x27, 0x00, 0x9B, -0x00, 0x54, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x33, 0x9F, 0x21, 0x4C, 0x46, 0x30, -0x09, 0xC0, 0x22, 0x00, 0x95, 0xA7, 0x7E, 0x82, 0xE0, 0x39, 0xC0, 0x17, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25, 0x25, 0x9F, 0x80, 0x3C, -0x06, 0x70, 0x09, 0xE2, 0x27, 0x00, 0x9F, 0x10, 0x7C, 0x26, 0xF0, 0x59, 0xC0, -0x27, 0x0C, 0x97, 0x02, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50, -0x5C, 0x02, 0x32, 0x09, 0xE8, 0x27, 0x10, 0x8F, 0x01, 0x5C, 0x0A, 0x74, 0x09, -0xC1, 0xA6, 0x00, 0x9B, 0x05, 0x7E, 0x02, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x40, -0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x80, 0xB0, 0x01, 0xC0, 0x03, -0x00, 0x17, 0x02, 0x7C, 0x08, 0xF0, 0x01, 0xC2, 0x00, 0x01, 0x1F, 0x00, 0x4C, -0x00, 0xB0, 0x81, 0xC1, 0x07, 0x40, 0x17, 0x22, 0x5C, 0x10, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x13, 0x02, 0x4C, 0x40, 0x30, 0x01, 0x82, 0x53, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x9C, 0x00, 0x5D, 0x40, 0xF4, 0x05, 0xD8, -0x05, 0xC0, 0x15, 0x20, 0x6C, 0x00, 0xF4, 0x49, 0x10, 0x05, 0x40, 0x9F, 0x80, -0x5B, 0x00, 0x76, 0x01, 0xD0, 0x87, 0x40, 0x9C, 0x00, 0x7D, 0x02, 0x84, 0x01, -0xF4, 0x27, 0xC0, 0x15, 0x00, 0x71, 0x00, 0x84, 0x89, 0x10, 0x77, 0x40, 0xDF, -0x00, 0x70, 0x07, 0xC4, 0x01, 0x16, 0x97, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA8, 0xF2, 0x00, 0xCD, 0x00, 0x34, 0x23, 0xD0, 0x0C, -0x48, 0x31, 0x00, 0x88, 0x02, 0x36, 0x1F, 0x90, 0x0C, 0x40, 0x13, 0x10, 0xC5, -0x00, 0x34, 0x03, 0x90, 0x3C, 0x60, 0xB0, 0x00, 0xD5, 0x0B, 0x00, 0x03, 0x91, -0x3C, 0x44, 0x31, 0x00, 0xC1, 0x01, 0x34, 0x0A, 0x50, 0x14, 0x40, 0xF2, 0x01, -0xC1, 0x07, 0x24, 0x0B, 0x12, 0x8C, 0x44, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, -0x39, 0x01, 0x6D, 0x10, 0xB4, 0x04, 0x18, 0x0E, 0x40, 0x1B, 0x00, 0xE1, 0x44, -0xB4, 0x03, 0xD0, 0x36, 0x40, 0x38, 0x00, 0xED, 0x00, 0x85, 0x03, 0xD4, 0x06, -0x60, 0x7D, 0x02, 0xE1, 0x02, 0xE6, 0x02, 0x10, 0x06, 0x40, 0xBB, 0x20, 0xE1, -0x61, 0xE5, 0x8F, 0x50, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x05, 0xD0, 0x1E, 0xC0, 0xF9, -0x00, 0x2B, 0x01, 0xBC, 0x04, 0xB1, 0x1E, 0xC0, 0x73, 0x00, 0xE5, 0x35, 0xB4, -0x2F, 0xB0, 0x1F, 0xD0, 0x78, 0x00, 0xCF, 0x41, 0x8C, 0x05, 0xB4, 0x16, 0xC0, -0x79, 0x03, 0xF3, 0x01, 0xBD, 0x04, 0x70, 0x16, 0xC0, 0x7B, 0x40, 0x23, 0x01, -0xAC, 0x07, 0x31, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0xFC, 0x01, 0xF0, 0x0D, 0xC0, 0x35, 0x00, -0x1E, 0x00, 0x3C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xDF, 0x4A, 0x7C, 0x1B, -0xF0, 0x05, 0xC8, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF6, 0x05, 0xC6, 0xB5, -0x01, 0x5E, 0x00, 0x1C, 0x00, 0x50, 0x05, 0xC0, 0x33, 0x00, 0x1F, 0x00, 0x5C, -0x03, 0xB0, 0x09, 0xC8, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x20, 0x5D, 0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF8, 0x8F, 0xC0, 0x7B, 0x00, 0x3B, -0x01, 0xFC, 0x04, 0x70, 0x1F, 0xC0, 0x5F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0xB0, -0x1B, 0xC0, 0x76, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30, 0x93, 0xC4, 0x7F, 0x00, -0xB3, 0x01, 0xCC, 0x16, 0xF8, 0x97, 0xC0, 0x7B, 0x00, 0xFB, 0x41, 0xF8, 0x04, -0x34, 0x9B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, -0x19, 0x22, 0xE1, 0x40, 0xB4, 0x81, 0x78, 0x0E, 0x42, 0x3B, 0x00, 0x61, 0x00, -0xB4, 0x00, 0xD0, 0x0E, 0x44, 0x1B, 0x21, 0xE6, 0x08, 0xF4, 0x23, 0x14, 0x0A, -0x40, 0x78, 0x00, 0xBD, 0x00, 0x84, 0x23, 0xF0, 0x00, 0x40, 0x3B, 0x01, 0xA1, -0x24, 0xAC, 0x12, 0xB0, 0x06, 0xC0, 0x3B, 0x06, 0xE1, 0x08, 0xB4, 0x20, 0xB0, -0x03, 0x48, 0x55, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, -0x04, 0xE1, 0x00, 0xB4, 0x03, 0x58, 0x8E, 0x40, 0x7F, 0x04, 0x21, 0x00, 0xB4, -0x00, 0x50, 0x0E, 0x40, 0x19, 0x08, 0xEC, 0x42, 0xB4, 0x03, 0x10, 0x02, 0x40, -0x38, 0x00, 0x6D, 0x00, 0xA4, 0x01, 0x10, 0x02, 0x60, 0x39, 0x24, 0xE1, 0x80, -0xB4, 0x72, 0x1C, 0x06, 0x46, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x40, 0x50, 0x0A, -0x42, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x25, 0x00, -0xC1, 0x20, 0x34, 0x08, 0x58, 0x0C, 0x40, 0xF3, 0x00, 0x49, 0x11, 0x34, 0x20, -0xD8, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x90, 0x01, 0x40, 0x02, -0x80, 0x0D, 0x00, 0x24, 0x01, 0x90, 0x00, 0x40, 0xF3, 0x00, 0x41, 0x01, 0x34, -0x06, 0x90, 0x04, 0x40, 0xF1, 0x00, 0xC1, 0x00, 0x36, 0x04, 0x18, 0x39, 0x40, -0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0xA5, 0x40, 0xD3, -0x00, 0x7C, 0x6E, 0x70, 0x0D, 0x40, 0xF7, 0x40, 0x0B, 0x07, 0x7C, 0x00, 0x70, -0x0D, 0xC2, 0x15, 0x00, 0xFF, 0x01, 0xF4, 0x4F, 0x30, 0x0D, 0xC0, 0x24, 0x00, -0x1F, 0x00, 0x24, 0x02, 0x30, 0x01, 0xC0, 0xF9, 0x00, 0x53, 0xA3, 0x3C, 0x02, -0x30, 0x04, 0x40, 0x77, 0x08, 0xDF, 0x25, 0x7C, 0x07, 0x50, 0x61, 0xC0, 0x54, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x11, 0xDF, 0x00, -0x7C, 0x0A, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x7C, 0x00, 0xF0, 0x0D, -0xC0, 0x17, 0x00, 0xD7, 0x08, 0x7C, 0x43, 0x70, 0x05, 0xD8, 0x25, 0x10, 0x9F, -0x00, 0x5C, 0x02, 0xF0, 0x21, 0xC0, 0x37, 0x04, 0xDF, 0x08, 0x68, 0x0A, 0xF9, -0x25, 0x80, 0x37, 0x01, 0x0E, 0x10, 0x7C, 0x0B, 0xF2, 0x21, 0xC0, 0xB7, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x07, 0x00, 0xF3, 0x00, 0xFC, -0x00, 0xF0, 0x0E, 0xC0, 0x3E, 0x04, 0x33, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, -0x7F, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0x70, 0x2B, 0xC0, 0x2B, 0x00, 0x3B, 0x20, -0xFC, 0x00, 0xB0, 0x03, 0xC0, 0x3F, 0x00, 0x23, 0x11, 0xCC, 0x42, 0x76, 0x87, -0xC0, 0x3C, 0x00, 0x3F, 0x02, 0xC4, 0x07, 0xF0, 0x03, 0xC1, 0x04, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66, 0x08, 0xD1, 0x40, 0x76, 0x04, -0xD0, 0x0D, 0x48, 0x35, 0x00, 0x11, 0x00, 0x44, 0x14, 0xD0, 0x0D, 0xC0, 0x27, -0x80, 0xDD, 0x80, 0x7C, 0x03, 0xD0, 0x11, 0x40, 0xC4, 0x44, 0x91, 0x21, 0x7C, -0x07, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x11, 0x0B, 0x44, 0x07, 0x10, 0x0D, 0x48, -0xF0, 0x00, 0x11, 0x03, 0x44, 0x00, 0xD2, 0x31, 0x40, 0x04, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0xA2, 0x46, 0x04, 0xD1, 0x00, 0x74, 0x0E, 0xD0, -0x0D, 0x40, 0x30, 0x00, 0x11, 0x30, 0x64, 0x04, 0xD0, 0x0D, 0x48, 0x17, 0x01, -0xDD, 0x00, 0x74, 0x03, 0xD2, 0x0D, 0x40, 0x44, 0x00, 0x91, 0x83, 0x76, 0x46, -0x90, 0x11, 0x40, 0x37, 0x00, 0x11, 0x02, 0x46, 0x0E, 0x50, 0x05, 0x40, 0x64, -0x44, 0xD1, 0x20, 0x54, 0x18, 0xD2, 0x39, 0x40, 0x04, 0x08, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C, -0x40, 0x31, 0x00, 0x51, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x11, 0x00, 0xCD, -0x00, 0x34, 0x03, 0xD0, 0x0C, 0x70, 0x00, 0x01, 0x81, 0x00, 0x34, 0x02, 0x99, -0x00, 0x40, 0x37, 0x00, 0x81, 0x20, 0x04, 0x02, 0x10, 0x04, 0x40, 0x24, 0x00, -0x01, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x52, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x0D, 0x40, -0x3C, 0x80, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x0D, 0x60, 0x17, 0x00, 0xFD, 0x00, -0xEC, 0x03, 0xF8, 0x00, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x81, -0xC0, 0x3B, 0x40, 0x03, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24, 0x10, 0xD3, -0x00, 0x1C, 0x00, 0xF0, 0x09, 0xC4, 0x04, 0x64, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC2, 0x3D, -0x40, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, -0x03, 0xF0, 0x03, 0x00, 0x0F, 0x2A, 0x3F, 0x00, 0xDC, 0x03, 0x70, 0x03, 0xC0, -0x3F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0x40, 0x0F, 0x40, 0x37, 0x00, -0xEC, 0x00, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA8, 0x7F, 0x00, 0x3E, 0x00, 0xFC, 0x04, 0x30, 0x1F, 0xC0, 0x2C, 0x00, -0xBF, 0x24, 0xCC, 0x03, 0xF0, 0x43, 0xC1, 0x3D, 0x21, 0x3F, 0xA0, 0xDC, 0x13, -0x30, 0x9E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0x98, 0x17, 0xF0, 0x1F, 0xC0, 0x4C, -0x00, 0xFF, 0x03, 0xFC, 0x07, 0xF0, 0x4F, 0xC0, 0x7E, 0x02, 0xFF, 0x00, 0xCC, -0x03, 0x30, 0x83, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x10, 0x36, 0x05, 0x1D, 0x02, 0x44, 0x00, 0x10, 0x0D, 0x50, 0x24, 0x08, 0x9D, -0x08, 0xC4, 0x2B, 0x10, 0x39, 0x44, 0x7C, 0x02, 0x9D, 0x01, 0xC4, 0x23, 0x11, -0x1D, 0x40, 0xFF, 0x01, 0x5D, 0x01, 0xC4, 0x0F, 0xD0, 0x0D, 0x40, 0x44, 0x00, -0xDD, 0x00, 0x5C, 0x07, 0xD0, 0xBF, 0x40, 0x34, 0x01, 0xF7, 0x03, 0xC4, 0x2F, -0x10, 0x09, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, -0x33, 0x00, 0x0D, 0x03, 0x54, 0x00, 0x90, 0x0C, 0x40, 0x21, 0x00, 0x8D, 0x00, -0x04, 0x83, 0x10, 0x01, 0x60, 0x30, 0x08, 0x05, 0x00, 0x24, 0x03, 0x10, 0x4C, -0x40, 0x32, 0x06, 0x89, 0x00, 0x05, 0x23, 0xD2, 0x0C, 0x48, 0x00, 0x20, 0xCD, -0x04, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x30, 0x01, 0xCD, 0x02, 0x05, 0x03, 0x14, -0x40, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, -0x00, 0x1D, 0x01, 0x44, 0x46, 0x94, 0x0D, 0x40, 0xE5, 0x00, 0x9D, 0x20, 0x44, -0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x64, 0x03, 0x11, 0x0D, 0x40, -0x37, 0x20, 0xDC, 0x10, 0x44, 0x03, 0xD0, 0x8C, 0x40, 0x44, 0x00, 0xDC, 0x00, -0x54, 0x03, 0xD0, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x10, 0x49, -0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, -0x1F, 0x01, 0x7C, 0x0C, 0xB0, 0x0D, 0xC0, 0x65, 0x00, 0x9F, 0x80, 0x0C, 0x03, -0xB4, 0x35, 0xC0, 0x35, 0x00, 0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC2, 0x36, -0x20, 0xDB, 0x80, 0x5C, 0x03, 0xE0, 0x1D, 0x80, 0x44, 0x04, 0x9F, 0x08, 0x7C, -0x07, 0xF0, 0x0D, 0xC0, 0x36, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30, 0x1D, 0xC0, -0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x2F, -0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2E, 0x00, 0x9F, 0x00, 0xFD, 0x03, 0xB0, -0x0F, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xDC, 0x03, 0xF0, 0x2F, 0xC6, 0x3F, 0x00, -0x69, 0x08, 0xFC, 0x03, 0xF0, 0x1F, 0xD0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x27, -0xF1, 0x0E, 0xC4, 0x3F, 0x01, 0xDF, 0x00, 0xBC, 0x03, 0xF0, 0x17, 0xC8, 0x1F, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x04, 0x1F, 0x21, -0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xD3, 0x00, 0x4C, 0xC3, 0x30, 0x25, -0xC0, 0x34, 0x00, 0x17, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x9F, -0x21, 0x6C, 0x43, 0x30, 0x0D, 0xD1, 0x44, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC2, 0x36, 0x00, 0xCF, 0x04, 0x4C, 0x13, 0xF0, 0x0D, 0xC0, 0x8B, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x1D, 0x00, 0x34, -0x12, 0xD0, 0xBD, 0x41, 0x27, 0x04, 0xD1, 0x00, 0xD4, 0x13, 0x10, 0x0C, 0x45, -0x3C, 0x00, 0x1D, 0x00, 0xE4, 0x03, 0xD2, 0x0D, 0x40, 0x3C, 0x00, 0xDD, 0x00, -0xC4, 0x07, 0x10, 0x0D, 0x40, 0x04, 0x00, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x1F, -0x40, 0x34, 0x00, 0xFD, 0x82, 0xC4, 0x0B, 0xD0, 0x05, 0x40, 0x6F, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30, 0x00, 0x0D, 0x20, 0x34, 0x00, -0xD0, 0x1D, 0x40, 0x33, 0x00, 0x94, 0x60, 0x24, 0x03, 0x10, 0x04, 0x40, 0x32, -0x00, 0x0D, 0x00, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24, -0x23, 0x50, 0x2C, 0x40, 0x03, 0x84, 0xC5, 0x12, 0x34, 0x03, 0xD0, 0x9C, 0x40, -0x30, 0x00, 0xC9, 0x49, 0x24, 0x27, 0xD0, 0x05, 0x40, 0x1F, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x78, 0x00, 0x2D, 0x21, 0xB4, 0x07, 0xD0, -0x9E, 0x40, 0x6B, 0x02, 0xA4, 0x01, 0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x00, -0xED, 0x81, 0xA4, 0x07, 0xD0, 0x1F, 0x60, 0x7A, 0x00, 0xC9, 0x03, 0x84, 0x07, -0x50, 0x1E, 0x40, 0x4B, 0x50, 0xE5, 0x89, 0xB4, 0x17, 0xD1, 0x1C, 0x40, 0x78, -0x00, 0xED, 0x81, 0xA4, 0x07, 0xD0, 0x9E, 0x40, 0x37, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x8C, -0xC0, 0x37, 0x08, 0x87, 0x00, 0x6C, 0x13, 0x30, 0x04, 0xC0, 0x32, 0x00, 0x4F, -0x02, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x32, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70, -0x0D, 0xC0, 0x03, 0x00, 0xC7, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00, -0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xE8, -0x3F, 0x40, 0xBB, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x3D, 0x02, 0xFF, 0x00, -0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x23, 0xB2, 0x0F, -0xC0, 0x08, 0x02, 0xFB, 0x28, 0xFC, 0x93, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF, -0x00, 0xDD, 0x03, 0xF2, 0x8F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xB0, 0x37, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF1, 0x1D, 0xC0, 0x34, -0x00, 0x93, 0x00, 0x4C, 0x03, 0x70, 0x05, 0xC4, 0x77, 0x01, 0x9B, 0x00, 0x7C, -0x4B, 0xE0, 0x1D, 0xC2, 0x35, 0x05, 0xCD, 0x01, 0x4C, 0x1B, 0xF0, 0x0D, 0xC0, -0x07, 0x00, 0xDF, 0x01, 0x1C, 0x07, 0x70, 0xCD, 0xC0, 0x37, 0x20, 0xDF, 0x0A, -0x3C, 0x4F, 0x30, 0x09, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x80, 0x39, 0x00, 0x2D, 0x00, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x1C, 0x00, -0xA1, 0x00, 0xAC, 0x53, 0x10, 0x0E, 0x40, 0xBB, 0x04, 0xE1, 0x00, 0xB4, 0x03, -0xD0, 0x0E, 0x40, 0x3C, 0x01, 0xE1, 0x00, 0x84, 0x53, 0xD0, 0x0E, 0x40, 0x0B, -0x00, 0xFD, 0x00, 0x8C, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x00, 0xE7, 0x10, 0xB4, -0x13, 0xB0, 0x00, 0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x00, 0x79, 0x00, 0x6D, 0x01, 0x94, 0x06, 0xD0, 0x1E, 0x40, 0x78, 0x0C, 0xC1, -0x01, 0x04, 0x27, 0x50, 0x1E, 0x40, 0x73, 0x01, 0xE1, 0x01, 0xB4, 0x27, 0x50, -0x3E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x85, 0x27, 0xD0, 0x1E, 0x43, 0x4B, 0x00, -0xED, 0x01, 0x84, 0x07, 0x10, 0x5E, 0x40, 0x6B, 0x00, 0xE5, 0x25, 0xB6, 0x37, -0x10, 0x1A, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, -0x33, 0x00, 0xCD, 0x01, 0x34, 0x4B, 0x50, 0x0C, 0x60, 0x70, 0x01, 0xC1, 0x01, -0x24, 0x03, 0x10, 0x0C, 0x41, 0x33, 0x80, 0xC1, 0x10, 0x34, 0x03, 0xD0, 0x18, -0x40, 0x32, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x09, 0x40, 0xF3, 0x00, 0xCD, -0x01, 0x04, 0x06, 0x14, 0x0C, 0x40, 0x37, 0x10, 0xC5, 0x80, 0x36, 0x03, 0x90, -0x41, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, -0x00, 0x7F, 0x05, 0xFC, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x00, 0x53, 0x41, 0x4C, -0x01, 0x70, 0x27, 0xC0, 0x17, 0x40, 0x73, 0xC2, 0x7C, 0x01, 0xF0, 0x05, 0xC0, -0x17, 0x10, 0x7F, 0x00, 0x4C, 0x01, 0xF0, 0x15, 0xC0, 0x5F, 0x01, 0x5F, 0x01, -0x5D, 0x15, 0x70, 0x04, 0xC2, 0x57, 0x01, 0x47, 0x00, 0x7C, 0x01, 0x30, 0x17, -0xC1, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85, 0x00, -0x1F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x3C, 0x00, -0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x05, -0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x08, 0x5C, -0x00, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8, -0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, -0x05, 0x4C, 0x02, 0x36, 0x09, 0xC0, 0xA3, 0x40, 0x83, 0x05, 0x4C, 0x06, 0xB0, -0x08, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, -0x9B, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x9F, 0x00, 0x7C, 0x26, -0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9C, 0x00, 0x48, 0x02, 0xF0, 0x09, 0xC8, 0x40, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x00, 0x9D, 0x00, -0x44, 0x02, 0x10, 0x19, 0x40, 0x27, 0x40, 0x91, 0x01, 0x7C, 0x2A, 0x10, 0x09, -0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xE0, 0x27, 0x00, 0x91, -0x10, 0x74, 0x1E, 0xD1, 0x99, 0x40, 0xA4, 0x00, 0x9D, 0x42, 0x5C, 0x02, 0xD0, -0x09, 0xC0, 0x26, 0x00, 0x95, 0x80, 0x54, 0x1A, 0xD0, 0x09, 0xC0, 0x06, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x8D, 0x00, 0x04, -0x02, 0x18, 0x49, 0x40, 0x27, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x1D, 0x40, -0x26, 0x00, 0x95, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x23, 0x00, 0x99, 0x01, -0x74, 0x12, 0xD0, 0x29, 0x40, 0x25, 0x00, 0x9D, 0x04, 0x74, 0x02, 0x50, 0x89, -0x40, 0x24, 0x00, 0x95, 0x18, 0x54, 0x22, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02, -0x10, 0x0C, 0x40, 0x23, 0x01, 0x81, 0x04, 0x14, 0x13, 0x10, 0x48, 0x40, 0x20, -0x01, 0x8D, 0x04, 0x36, 0x16, 0xD1, 0x08, 0x42, 0x21, 0x01, 0x81, 0x04, 0x34, -0x12, 0xD8, 0x08, 0x40, 0x61, 0x80, 0x8D, 0x01, 0x14, 0x02, 0xD0, 0x48, 0x40, -0x22, 0x30, 0x85, 0x44, 0x16, 0x12, 0xD0, 0x48, 0x40, 0x42, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x96, 0x02, 0x1F, 0x0A, 0x4D, 0x28, 0x30, -0xA0, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x44, 0x28, 0xB0, 0x01, 0xC0, 0x06, 0x00, -0x17, 0x10, 0x7C, 0x00, 0xF0, 0xA0, 0x40, 0x87, 0x02, 0x1B, 0x00, 0x74, 0x00, -0xF0, 0xA1, 0xC8, 0x05, 0x00, 0x1F, 0x0A, 0x74, 0x00, 0xF0, 0x01, 0xC0, 0x84, -0x00, 0x17, 0x00, 0x5C, 0x00, 0xF2, 0x21, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0x88, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x02, 0xF0, 0x09, -0xC0, 0x2F, 0x02, 0xBF, 0x48, 0x7C, 0x22, 0xF0, 0x8B, 0xC4, 0x27, 0x02, 0xBF, -0x00, 0x7C, 0x62, 0xF0, 0x0B, 0xC0, 0x27, 0x02, 0xBF, 0x08, 0x7C, 0x22, 0xF0, -0x0B, 0xD8, 0x2E, 0x00, 0xBF, 0x40, 0xDC, 0x02, 0xF0, 0x89, 0xC2, 0x2F, 0x04, -0x93, 0x08, 0x7C, 0x22, 0xF2, 0x8B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1C, 0xA0, 0x2D, 0x00, 0xBF, 0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0, -0x2C, 0x02, 0xB3, 0x00, 0xFC, 0x52, 0x34, 0x4F, 0x80, 0x27, 0x00, 0x9F, 0x00, -0xF8, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x25, 0xBF, 0x04, 0xD4, 0x02, 0x70, 0x0A, -0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xA3, -0x80, 0xBC, 0x02, 0xF0, 0x29, 0xC0, 0x61, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0x00, 0x07, 0x01, 0x0D, 0x2C, 0x44, 0x41, 0x10, 0x01, 0x41, 0x14, -0x02, 0x01, 0x14, 0x74, 0x10, 0x13, 0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74, -0x20, 0xD0, 0x41, 0x41, 0x06, 0x01, 0x1D, 0x08, 0x44, 0x08, 0x10, 0x01, 0x41, -0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xC0, 0x81, 0x44, 0x47, 0x05, 0x1B, 0x00, -0x74, 0x20, 0xD0, 0x11, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x20, 0x21, 0x05, 0x8D, 0x04, 0x05, 0x12, 0x10, 0x08, 0x40, 0x20, 0x40, -0x81, 0x04, 0x34, 0x52, 0x10, 0x08, 0x48, 0x22, 0x02, 0x88, 0x08, 0x34, 0x02, -0xD0, 0x48, 0x40, 0x21, 0x05, 0x8D, 0x01, 0x14, 0x22, 0xD0, 0x08, 0x40, 0x61, -0x00, 0x8D, 0x04, 0x24, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x81, 0x08, 0x34, -0x02, 0xD0, 0x48, 0x40, 0x4B, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x28, 0x25, 0x00, 0x9D, 0x00, 0x04, 0x02, 0x10, 0x09, 0x60, 0x24, 0x01, 0xD1, -0x00, 0x34, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x0A, 0x74, 0x02, 0xD0, -0x19, 0x40, 0x24, 0x00, 0x9D, 0x08, 0x44, 0x02, 0x90, 0x08, 0x50, 0x25, 0x01, -0x9D, 0x01, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x98, 0x00, 0x74, 0x02, -0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, -0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0x30, 0x09, 0xD0, 0xE4, 0x08, 0x93, 0x01, -0x7C, 0x02, 0x34, 0x69, 0xC8, 0x26, 0x00, 0x9B, 0x03, 0x7C, 0x02, 0xF0, 0x09, -0xCC, 0x27, 0x00, 0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x25, 0x00, 0x9E, -0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x90, 0x00, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, -0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C, -0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x82, 0xF0, 0x09, 0xC8, -0x27, 0x00, 0x8F, 0x00, 0x7C, 0x42, 0x70, 0x49, 0xC0, 0x26, 0x08, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x08, -0xC0, 0x59, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01, -0x1F, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x84, 0x40, 0x13, 0x10, 0x4C, 0x00, -0x30, 0x21, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xE0, 0x07, -0x00, 0x1F, 0x00, 0x3C, 0x00, 0xB0, 0x11, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, -0x00, 0xF0, 0x11, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, -0x51, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C, 0x00, 0x5D, -0x80, 0x44, 0x05, 0x30, 0x07, 0x40, 0x54, 0x40, 0x71, 0x05, 0xC6, 0x29, 0x10, -0x05, 0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x09, 0xD0, 0x05, 0xC0, 0x17, 0x00, -0x7D, 0x0A, 0xF4, 0x01, 0x70, 0x17, 0x40, 0x9C, 0x00, 0x7D, 0x10, 0x5C, 0x01, -0xD0, 0x17, 0x40, 0x17, 0x00, 0x71, 0x07, 0xC4, 0x19, 0x50, 0x05, 0x48, 0x50, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x02, 0xDD, 0x00, -0x04, 0x03, 0x50, 0x15, 0x49, 0x76, 0x20, 0xC1, 0x02, 0x24, 0x0F, 0x10, 0x0C, -0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x37, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD, -0x0B, 0x34, 0x07, 0x50, 0x9C, 0x42, 0xA0, 0x04, 0xCD, 0x05, 0x34, 0x03, 0xD0, -0x1C, 0x40, 0x37, 0x00, 0x05, 0x04, 0x04, 0x10, 0x10, 0x0C, 0x40, 0x51, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x00, 0xED, 0x00, 0x84, -0x0A, 0x10, 0x2A, 0x40, 0x32, 0x24, 0xE1, 0x01, 0xA4, 0x0A, 0x10, 0x2E, 0x48, -0x3B, 0x00, 0xED, 0x00, 0xB4, 0x83, 0xD0, 0x4E, 0x40, 0x39, 0x00, 0xAD, 0x00, -0xB4, 0x09, 0x40, 0x0F, 0x40, 0x18, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, -0x49, 0x3B, 0x00, 0x25, 0x00, 0x84, 0x04, 0x50, 0x0E, 0x48, 0x10, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x69, 0x00, 0xEF, 0x01, 0xCC, 0x07, -0x70, 0x1F, 0xD0, 0x7A, 0x00, 0xA3, 0x01, 0xE4, 0x07, 0x34, 0x1A, 0xC0, 0x7B, -0x00, 0xED, 0x01, 0xBC, 0x05, 0xF0, 0x7E, 0x41, 0x7B, 0x05, 0xAF, 0x01, 0xB8, -0x05, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, -0x7F, 0x00, 0xA5, 0x00, 0x8C, 0x06, 0x30, 0x1F, 0xC0, 0x51, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x0D, 0x00, 0x9F, 0x02, 0x7D, 0x1A, 0x74, -0x6B, 0xC0, 0x35, 0x00, 0x9F, 0x00, 0x5D, 0x1A, 0xF0, 0x09, 0xC0, 0x37, 0x00, -0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x3C, 0x81, -0x70, 0x0D, 0xD0, 0x17, 0x08, 0xDF, 0x00, 0x5C, 0x82, 0xF0, 0x0D, 0xC0, 0x37, -0x00, 0xDA, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x20, 0x4D, 0x00, 0xF7, 0x03, 0xCC, 0x1B, 0x70, 0x3F, -0xC0, 0x7C, 0x00, 0x73, 0x01, 0xCD, 0x0F, 0x30, 0x1B, 0xC0, 0x7F, 0x00, 0xF3, -0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xB3, 0x01, 0xCC, 0x85, 0xF0, -0x1F, 0xC0, 0x4C, 0x20, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00, -0x23, 0x01, 0xCC, 0x05, 0xF0, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x00, 0x0D, 0x00, 0xF1, 0x08, 0x84, 0xC3, 0x18, 0x0B, 0x40, -0x28, 0x00, 0x71, 0x00, 0xC4, 0x22, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00, -0xB4, 0x23, 0x10, 0x0E, 0xC0, 0x39, 0x02, 0xE1, 0x02, 0x84, 0x00, 0x70, 0x07, -0x40, 0x18, 0x20, 0xED, 0x80, 0xB4, 0x03, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x25, -0x0A, 0xAC, 0x28, 0xD0, 0x0E, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x09, 0x00, 0xED, 0x00, 0xC4, 0x23, 0x50, 0x0A, 0x50, 0x28, -0x00, 0x25, 0x08, 0x84, 0x03, 0x10, 0x0A, 0x40, 0x33, 0x00, 0xE1, 0x00, 0x34, -0x02, 0x10, 0x0E, 0x40, 0x33, 0x00, 0x41, 0x00, 0xA4, 0x01, 0xD0, 0x0E, 0x40, -0x88, 0x04, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x02, 0x40, 0x3F, 0x00, 0xA1, 0x00, -0x94, 0x03, 0xD0, 0x0E, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x28, 0x01, 0x00, 0x89, 0x00, 0x44, 0x0B, 0x10, 0x08, 0x40, 0xE4, 0x01, -0x05, 0x00, 0x44, 0x02, 0x10, 0x28, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x34, 0x02, -0x10, 0x0C, 0x68, 0x31, 0x00, 0x41, 0x52, 0x24, 0x00, 0x50, 0x0C, 0x40, 0x50, -0x00, 0xDD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x73, 0x02, 0x85, 0x00, 0x34, -0x03, 0xD0, 0x0C, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA0, 0x25, 0x00, 0xDF, 0x00, 0x4D, 0x0B, 0x50, 0x05, 0xC0, 0x74, 0x40, 0x17, -0x00, 0x44, 0x03, 0x34, 0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x06, 0x7C, 0x02, 0x30, -0x0F, 0xC0, 0x3F, 0x00, 0xD3, 0x02, 0x6C, 0x01, 0xF0, 0x1D, 0xC0, 0x44, 0x00, -0xDF, 0x40, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00, 0x5C, 0x00, -0xF0, 0x2F, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, -0x87, 0x00, 0xD7, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1A, 0x02, -0x7C, 0x02, 0xF1, 0x09, 0xC1, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x1D, -0xC0, 0x37, 0x20, 0x1F, 0x03, 0x5C, 0x01, 0x70, 0x8D, 0xC0, 0x07, 0x28, 0xDF, -0x02, 0x7C, 0x06, 0xF0, 0x05, 0xCA, 0x37, 0x00, 0x9F, 0x02, 0x2C, 0x0A, 0xF0, -0x0D, 0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0F, -0x00, 0xFF, 0x00, 0xCC, 0x43, 0x30, 0x0F, 0xC0, 0x74, 0x01, 0x23, 0x01, 0xC4, -0x03, 0x30, 0x0B, 0xC0, 0x3C, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0x30, 0x0F, 0xC0, -0x3B, 0x00, 0xB3, 0x00, 0x8E, 0x00, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x7B, 0x00, -0xCC, 0x03, 0x30, 0x07, 0xC0, 0x3F, 0x10, 0x7F, 0x00, 0xCC, 0x0C, 0x30, 0x0F, -0xC1, 0x03, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0xC6, 0x24, -0x8D, 0x00, 0x44, 0x02, 0x90, 0x19, 0xC0, 0x36, 0x40, 0x11, 0x03, 0x54, 0x0E, -0x50, 0x09, 0x50, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x4C, 0x10, 0x0D, 0x40, 0x37, -0x00, 0x01, 0x00, 0x54, 0x0C, 0x51, 0x09, 0x40, 0xC0, 0x00, 0xDB, 0x03, 0x04, -0x07, 0x10, 0x15, 0xC0, 0x35, 0x00, 0xCD, 0x08, 0x54, 0x06, 0x10, 0x0D, 0x40, -0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x80, 0xDD, -0x00, 0x44, 0x03, 0x90, 0x18, 0x40, 0x25, 0x00, 0x51, 0x88, 0x54, 0x07, 0x10, -0x89, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00, -0x91, 0x00, 0x46, 0x45, 0x90, 0x1C, 0x40, 0x44, 0x44, 0xD9, 0x03, 0x44, 0x12, -0x10, 0x11, 0x60, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x10, 0x0D, 0x40, 0x07, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xDD, 0x00, -0x04, 0x03, 0x90, 0x08, 0x40, 0x22, 0x00, 0x41, 0x00, 0x14, 0x02, 0x14, 0x08, -0x48, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x10, 0x0C, 0x40, 0x33, 0x20, 0x41, -0x00, 0x16, 0x00, 0xD0, 0x04, 0x40, 0x00, 0x40, 0xC9, 0x80, 0x45, 0x02, 0x14, -0x10, 0x60, 0x31, 0x00, 0x4D, 0x00, 0x14, 0x01, 0x10, 0x0C, 0x40, 0x43, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xFF, 0x00, 0xCD, -0x03, 0x34, 0x0B, 0xC0, 0x25, 0x00, 0x13, 0x00, 0xDC, 0x02, 0x30, 0x09, 0xC0, -0x34, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0x11, 0x0F, 0xC0, 0x3F, 0x00, 0x53, 0x00, -0x44, 0x00, 0xB0, 0x0D, 0xC8, 0x05, 0x40, 0x9B, 0x00, 0x4C, 0x03, 0x30, 0x01, -0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x03, 0x40, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xBC, 0x03, -0x70, 0x0B, 0xC0, 0x2F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, -0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC, -0x00, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x03, 0xCA, -0x39, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x53, 0xF0, -0x03, 0xC0, 0x0F, 0x00, 0xAF, 0x01, 0xFC, 0x87, 0xF0, 0x1F, 0xD0, 0x0C, 0x00, -0xFF, 0x01, 0xCC, 0x03, 0xF0, 0x4F, 0xC0, 0x0D, 0x02, 0xB3, 0x01, 0xEC, 0x07, -0xF0, 0x03, 0xC0, 0x0F, 0x08, 0xEF, 0x01, 0xBC, 0x05, 0xB4, 0x1A, 0xC0, 0x7B, -0x00, 0x33, 0x04, 0xBC, 0x02, 0x20, 0x0B, 0xC8, 0x0C, 0x08, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0x1D, 0x00, 0xF4, 0x0B, 0xD0, 0x11, -0x40, 0x47, 0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0x0D, 0x40, 0x20, 0x01, 0xCC, -0x10, 0xC4, 0x2B, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0xD1, 0x01, 0x44, 0x03, 0xD0, -0x11, 0x42, 0x07, 0x00, 0xDD, 0x01, 0x74, 0x07, 0x12, 0x19, 0x40, 0x57, 0x20, -0x15, 0x83, 0x74, 0x06, 0x51, 0x01, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, -0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x04, 0xCD, 0x04, -0x05, 0x03, 0xD2, 0x8C, 0x42, 0x23, 0x08, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x08, -0x40, 0x63, 0x00, 0xCD, 0x00, 0x34, 0x81, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81, -0x08, 0x34, 0x02, 0x19, 0x08, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x21, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x47, -0x00, 0xDD, 0x01, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xE4, 0x00, 0xCD, 0x20, 0x44, -0x03, 0xD1, 0x0D, 0x40, 0x63, 0x00, 0xD1, 0x03, 0x54, 0x03, 0x90, 0x19, 0x40, -0x67, 0x10, 0xDD, 0x04, 0x74, 0x06, 0x11, 0x1D, 0x40, 0x37, 0x00, 0x55, 0x90, -0x74, 0x06, 0x58, 0x19, 0x42, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA0, 0xE7, 0x00, 0x9F, 0x11, 0x5C, 0x03, 0xF1, 0x19, 0xC0, 0x67, 0x04, -0xDF, 0x05, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xC4, 0x00, 0xDF, 0x01, 0x4C, 0x03, -0xF0, 0x0D, 0xC0, 0x45, 0x40, 0xC3, 0x01, 0x7C, 0x03, 0xF0, 0x39, 0xC1, 0x67, -0x00, 0xDF, 0x00, 0x3C, 0x0D, 0xB8, 0x39, 0xC0, 0x37, 0x00, 0x53, 0x02, 0x7C, -0x04, 0x30, 0x11, 0xC0, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0x88, 0x2D, 0x00, 0xBF, 0x80, 0x7C, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF, -0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x02, 0xFC, 0x03, 0xF2, -0x0F, 0xE0, 0x27, 0x80, 0xFF, 0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x0F, 0x00, -0xFF, 0x01, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x7F, 0x01, 0x3F, 0x04, 0xBC, 0x02, -0xF0, 0x01, 0xC1, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, -0x05, 0x02, 0x9F, 0x02, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0xA7, 0x00, 0xDF, 0x0A, -0x6C, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xD3, 0x04, 0x4C, 0x13, 0xF2, 0x8D, -0xC2, 0xA7, 0x00, 0xD7, 0x03, 0x4C, 0x47, 0xF0, 0x29, 0xC0, 0x24, 0x04, 0xDB, -0x04, 0x4C, 0x19, 0x70, 0x2D, 0xC5, 0x34, 0x00, 0x57, 0x02, 0x7C, 0x60, 0x74, -0x01, 0xC0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, -0x00, 0x9D, 0x18, 0xF4, 0x2B, 0x10, 0x01, 0x40, 0x27, 0x00, 0xDD, 0x00, 0x44, -0x03, 0xD0, 0x8D, 0x40, 0x27, 0x00, 0xD1, 0x02, 0xC4, 0x4B, 0xD0, 0x2F, 0x40, -0x27, 0x00, 0xD1, 0x80, 0x50, 0x0B, 0xF0, 0x49, 0x00, 0x85, 0x00, 0xDD, 0x41, -0x6C, 0x4F, 0x10, 0x0D, 0x40, 0x30, 0x02, 0x5B, 0x00, 0x70, 0x0A, 0x10, 0x21, -0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x04, -0x0D, 0x00, 0x34, 0x03, 0x10, 0x00, 0x40, 0x23, 0x00, 0xCD, 0x01, 0x24, 0x03, -0x50, 0x3D, 0x40, 0x03, 0x00, 0xC5, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x02, -0x00, 0xC9, 0x00, 0x04, 0x8B, 0xD0, 0x10, 0x40, 0x00, 0x20, 0xCD, 0x02, 0x04, -0x0B, 0x50, 0x28, 0x40, 0x32, 0x00, 0x0D, 0x07, 0x34, 0x04, 0xD4, 0x19, 0x40, -0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x6D, -0x01, 0xB4, 0x27, 0x14, 0x16, 0x40, 0x7B, 0x00, 0xFD, 0x01, 0x84, 0x87, 0xD0, -0x1E, 0x40, 0x7B, 0x10, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x48, 0x6B, 0x50, -0xF9, 0x01, 0x94, 0x87, 0x58, 0x16, 0x50, 0x48, 0x02, 0xFD, 0x11, 0xE4, 0x17, -0x10, 0x0F, 0x40, 0x7E, 0x8C, 0xA9, 0x01, 0xB4, 0x24, 0x90, 0x12, 0x48, 0x3E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A, 0x90, 0x00, 0xCF, 0x00, -0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70, 0x0C, -0xC1, 0x03, 0x40, 0xC5, 0x00, 0x0C, 0x23, 0xF0, 0x0C, 0x40, 0x12, 0x02, 0xD7, -0x00, 0x0C, 0x03, 0xD0, 0x80, 0xC0, 0x30, 0x02, 0xCF, 0x00, 0x04, 0x03, 0x70, -0x8C, 0xC0, 0x32, 0x00, 0xCF, 0x10, 0x3C, 0x22, 0xF4, 0x88, 0xC9, 0x48, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x1D, 0x00, 0xFF, 0x00, 0xFC, -0x03, 0xF0, 0x8F, 0xC0, 0x3F, 0x10, 0xFF, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x17, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC8, 0x1F, 0x08, 0xF7, 0x00, -0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x4F, -0xE0, 0x3D, 0x00, 0xFE, 0x08, 0xFC, 0x23, 0x74, 0x0F, 0xC0, 0x0B, 0x60, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x08, 0x5F, 0x01, 0x4C, 0x03, -0x70, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x17, -0x00, 0xD7, 0x00, 0x5C, 0x1B, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x7C, -0x03, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xC3, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0x40, -0x37, 0x00, 0x9F, 0x40, 0x4C, 0x80, 0x20, 0x09, 0xC2, 0x43, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x82, 0x39, 0x00, 0x6D, 0x00, 0xC4, 0x2B, 0x10, -0x0E, 0x40, 0x1B, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, -0xED, 0x00, 0xB4, 0x33, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xEF, 0x00, 0xB4, 0x03, -0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0E, 0x00, 0x3B, -0x00, 0x8D, 0x00, 0x84, 0x01, 0xB0, 0x02, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xCD, 0x03, 0xA5, 0x17, 0x50, 0x1E, -0x40, 0x7B, 0x00, 0xED, 0x11, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0x7B, 0x00, 0xED, -0x01, 0x96, 0x27, 0xD0, 0x1E, 0x40, 0x7B, 0x88, 0xED, 0x01, 0xB4, 0x07, 0xD0, -0x36, 0x40, 0x73, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x00, -0xED, 0x11, 0x14, 0x44, 0x19, 0x3E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x28, 0x73, 0x00, 0xCD, 0x01, 0x24, 0x03, 0x10, 0x0C, 0x40, -0x33, 0x00, 0x49, 0x05, 0x34, 0x03, 0xD0, 0x18, 0x40, 0xF3, 0x00, 0x8D, 0x01, -0x74, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0x45, 0x1A, 0x34, 0x03, 0xD0, 0x5C, -0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x07, 0x50, 0x2C, 0x60, 0xB3, 0x00, 0xCD, -0x47, 0x14, 0x07, 0x90, 0x1C, 0x40, 0x5B, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x17, 0xA0, 0x1D, 0x00, 0x7F, 0x02, 0x6C, 0x01, 0x70, 0x27, 0xC0, 0x9F, -0x00, 0x7F, 0x01, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x01, 0x5C, -0x01, 0xF0, 0x05, 0xC0, 0xDF, 0x00, 0x7D, 0x02, 0x7C, 0x81, 0xF1, 0x37, 0xC0, -0xDF, 0x40, 0x43, 0x00, 0xEC, 0x01, 0xB0, 0x27, 0xC0, 0x1B, 0x01, 0x7F, 0x23, -0x9D, 0xA5, 0x20, 0xB7, 0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x08, 0x45, 0x02, 0x1F, 0x02, 0x1C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, -0x1D, 0x20, 0x7C, 0x00, 0xF2, 0x21, 0xC8, 0x07, 0x06, 0x1F, 0x0A, 0x7C, 0x00, -0xF0, 0x21, 0xC0, 0x07, 0x04, 0x1F, 0x80, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87, -0x06, 0x1F, 0x42, 0x7C, 0x28, 0xB0, 0x41, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x64, -0x88, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x25, 0x00, 0x9F, 0x19, 0x7C, 0x06, 0x30, 0x08, 0xC5, 0x24, 0x04, 0x9F, -0x08, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x01, 0x7C, 0x02, 0x30, -0x09, 0xC2, 0x23, 0x80, 0x93, 0x04, 0x4C, 0x02, 0xF0, 0x59, 0xC0, 0x27, 0x00, -0x93, 0x03, 0x5C, 0x02, 0x71, 0x59, 0xC0, 0xA7, 0x40, 0x83, 0x00, 0x4C, 0x22, -0x30, 0x28, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, -0x64, 0x00, 0x9D, 0x12, 0x74, 0x0A, 0x14, 0x09, 0x50, 0x24, 0x00, 0x97, 0x01, -0x74, 0x02, 0xD8, 0x49, 0x40, 0x27, 0x40, 0x91, 0x11, 0x74, 0x0A, 0x50, 0x29, -0x40, 0x27, 0xC0, 0x8B, 0x01, 0x44, 0x4A, 0xD0, 0x09, 0x44, 0xE7, 0x40, 0x91, -0x86, 0x00, 0x12, 0x20, 0x19, 0x40, 0xE7, 0x10, 0x91, 0x01, 0x44, 0x06, 0x14, -0x39, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24, -0x25, 0x9D, 0x00, 0x74, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, -0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x0A, 0x10, 0x09, 0x40, -0x37, 0x08, 0x91, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00, -0x50, 0x03, 0x50, 0x0D, 0x40, 0x36, 0x00, 0x99, 0x04, 0x44, 0x03, 0x10, 0x0D, -0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x20, 0x05, -0x8D, 0x14, 0x36, 0x12, 0x10, 0x48, 0x40, 0x20, 0x01, 0x85, 0x80, 0x34, 0x02, -0xD0, 0x08, 0x40, 0x23, 0x01, 0x81, 0x08, 0x74, 0x12, 0x50, 0x08, 0x40, 0x23, -0x01, 0x91, 0x00, 0x04, 0x02, 0xD2, 0x48, 0x40, 0x33, 0x01, 0x89, 0x00, 0x44, -0x02, 0x10, 0x08, 0x44, 0x33, 0x00, 0x89, 0x01, 0x05, 0x93, 0x10, 0x48, 0x50, -0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F, -0x04, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0, -0xA1, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x7C, 0x28, 0x30, 0xE5, 0xC5, 0x87, 0x02, -0x11, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22, 0x1B, 0x00, 0x5C, 0x00, -0x72, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x14, 0x4C, 0x00, 0x30, 0xA1, 0xC0, 0x74, -0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x05, 0xBF, 0x14, -0x74, 0xA2, 0xF2, 0x8B, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x0B, -0xC0, 0x2F, 0x0A, 0xB7, 0x04, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF, -0x00, 0x7D, 0x02, 0xF0, 0x8F, 0x00, 0x2F, 0x02, 0xB7, 0x80, 0xFC, 0x02, 0x70, -0x0B, 0xC0, 0x2F, 0x08, 0xF7, 0x00, 0xFD, 0x23, 0xF0, 0x8B, 0xC2, 0x77, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x0C, 0xFC, -0x82, 0x32, 0x09, 0xC0, 0x24, 0x00, 0xB3, 0x00, 0x7C, 0x02, 0xF0, 0x8A, 0xC0, -0x24, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0x30, 0x4B, 0xC0, 0x26, 0x05, 0xBF, 0x00, -0xFC, 0x02, 0x30, 0x0B, 0xE0, 0x2F, 0x02, 0xFF, 0x00, 0xCD, 0x02, 0xB0, 0x0F, -0xC2, 0x2F, 0x48, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC4, 0x74, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D, 0x0C, 0x74, 0x48, -0x10, 0x05, 0x40, 0x04, 0x02, 0x51, 0x00, 0x74, 0x00, 0xD0, 0x41, 0x48, 0x84, -0x04, 0x1D, 0x10, 0x74, 0x20, 0x14, 0x41, 0x41, 0x04, 0x01, 0x57, 0x80, 0x74, -0x40, 0x10, 0x01, 0x60, 0x07, 0x02, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, -0x17, 0x50, 0x11, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x05, 0x36, 0x32, 0x14, -0x88, 0x40, 0x62, 0x60, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x50, 0x20, 0x03, -0x8D, 0x00, 0x34, 0x02, 0x10, 0xCC, 0x40, 0x22, 0x05, 0xCD, 0x00, 0x36, 0x13, -0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x24, 0x02, 0x94, 0x18, 0x40, 0x23, -0x00, 0x85, 0x40, 0x14, 0x02, 0xD2, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x04, 0x9D, 0x80, 0x74, 0x02, 0x10, 0x09, -0x50, 0x26, 0x01, 0x91, 0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x9D, -0x00, 0x74, 0x02, 0x11, 0x09, 0x40, 0x64, 0x10, 0x9D, 0x01, 0x74, 0x02, 0x10, -0x09, 0x40, 0xE7, 0x10, 0x9D, 0x00, 0x64, 0x12, 0x12, 0x09, 0x40, 0x27, 0x08, -0xD5, 0x04, 0x44, 0x02, 0xD0, 0x29, 0x40, 0x62, 0x28, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, -0x66, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x01, -0x7C, 0x02, 0x30, 0x09, 0xC0, 0xA6, 0x04, 0x9F, 0x03, 0x74, 0x02, 0x34, 0x29, -0x40, 0xA7, 0x00, 0x8F, 0x00, 0x2C, 0x82, 0xB0, 0x29, 0xC0, 0xA3, 0x00, 0x97, -0x02, 0x5C, 0x06, 0xF0, 0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x16, 0x08, 0x65, 0x0A, 0x9F, 0x14, 0x7C, 0x02, 0xF2, 0x48, 0xC0, 0x21, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C, -0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x97, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0x82, -0x27, 0x00, 0x9F, 0x18, 0x5C, 0x02, 0xD0, 0x99, 0xC0, 0xA7, 0x64, 0x9B, 0x00, -0x7C, 0x8E, 0x78, 0x38, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x08, 0x85, 0x04, 0x1F, 0x08, 0x7C, 0x40, 0xF1, 0x01, 0xC0, 0x07, 0x80, -0x13, 0x20, 0x7C, 0x00, 0xF2, 0x41, 0xD0, 0x84, 0x00, 0x1F, 0x00, 0x0C, 0x00, -0x30, 0x01, 0xC2, 0x87, 0x08, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x21, 0xF0, 0x04, -0x0C, 0x1B, 0x80, 0x7C, 0x00, 0x70, 0x01, 0xC9, 0x87, 0x00, 0x07, 0x80, 0x4D, -0x08, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0xDC, 0x20, 0x7D, 0x01, 0xF6, 0x1D, 0x70, 0x05, 0x60, 0x17, 0x00, 0x51, -0x00, 0x74, 0x01, 0xD0, 0x07, 0xC0, 0x16, 0x00, 0x7D, 0x05, 0xCD, 0x19, 0x30, -0x27, 0x60, 0x17, 0x20, 0x5D, 0x00, 0xFC, 0xA9, 0x72, 0x45, 0x62, 0x1C, 0x11, -0x71, 0x25, 0xDC, 0x8D, 0x14, 0x27, 0xC0, 0x9D, 0x01, 0x71, 0x89, 0xCC, 0x01, -0x10, 0x37, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, -0xF2, 0x02, 0xCD, 0x02, 0x74, 0x03, 0x52, 0x0C, 0x44, 0x33, 0x00, 0x81, 0x00, -0x34, 0x03, 0xD0, 0x2D, 0x40, 0x30, 0x00, 0xCD, 0x01, 0x24, 0x1F, 0x10, 0x2C, -0x49, 0x33, 0x10, 0x8D, 0x00, 0x74, 0x03, 0x51, 0x18, 0x40, 0x30, 0x00, 0x41, -0x01, 0x34, 0x40, 0x10, 0x0C, 0x40, 0xA3, 0x20, 0xC5, 0x09, 0x20, 0x07, 0x10, -0x2C, 0x41, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, -0x00, 0xED, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x33, 0x40, 0xE1, 0x80, 0xB4, -0x03, 0xD8, 0x0F, 0x41, 0x38, 0x00, 0x6D, 0x01, 0x84, 0x03, 0x10, 0x0E, 0x48, -0x3B, 0x02, 0xED, 0x40, 0xB4, 0x01, 0x50, 0x1E, 0x48, 0x59, 0x00, 0x61, 0x81, -0xD4, 0x42, 0x10, 0x06, 0x40, 0x2D, 0x00, 0x61, 0x00, 0x04, 0x46, 0x10, 0x0E, -0x41, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, -0x6F, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7B, 0x08, 0xE1, 0x01, 0xBC, 0x07, -0xF0, 0x1E, 0x40, 0x78, 0x81, 0xBD, 0x01, 0xEC, 0x05, 0x34, 0x1E, 0x40, 0x7B, -0x02, 0xEF, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7C, 0x40, 0x6B, 0x00, 0xBC, -0x06, 0x30, 0x1A, 0xC0, 0x6B, 0x00, 0xE7, 0x01, 0xAC, 0x07, 0x34, 0x17, 0xC0, -0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, -0x00, 0x7C, 0x81, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x37, 0x04, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0xB7, 0x00, -0xDF, 0x00, 0x5C, 0x83, 0x72, 0x0C, 0xE0, 0x16, 0x08, 0xDF, 0x00, 0x3C, 0x02, -0xC4, 0x01, 0xC0, 0x23, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0xF0, 0x01, 0xD0, 0x43, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x7D, 0x00, 0xF3, 0x01, -0xCC, 0x13, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, -0xC0, 0x7F, 0x04, 0xF3, 0x01, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x02, 0xFF, -0x89, 0xFC, 0x87, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0x73, 0x01, 0xFC, 0x26, 0xF0, -0x17, 0xC8, 0x6B, 0x20, 0xBB, 0x01, 0xFC, 0x07, 0xD0, 0x13, 0xC0, 0x1B, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x3D, 0x50, 0x71, 0x20, 0x84, -0x83, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2A, 0x48, -0x3F, 0x00, 0x61, 0x00, 0xD4, 0x08, 0x11, 0x0B, 0xC0, 0x38, 0x00, 0xE9, 0x88, -0xDC, 0x82, 0x10, 0xCE, 0x40, 0x3B, 0x01, 0x61, 0x00, 0xB4, 0x32, 0xD0, 0x06, -0x42, 0x3B, 0x12, 0x21, 0x30, 0xB4, 0x02, 0xD0, 0x4A, 0x42, 0x57, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x61, 0x00, 0x84, 0x20, -0xD0, 0x0E, 0x40, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x40, 0x3B, -0x00, 0xB1, 0x00, 0xA4, 0x21, 0x10, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x08, 0xB6, -0x03, 0x10, 0x0E, 0x49, 0x2B, 0x00, 0x61, 0x10, 0xB4, 0x02, 0xD1, 0x02, 0x40, -0x2F, 0x00, 0x29, 0x00, 0xB4, 0x03, 0xD0, 0x02, 0x44, 0x23, 0x02, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xE1, 0x00, 0x01, 0x07, 0x04, 0x00, 0xD0, -0x0C, 0x40, 0x73, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD1, 0x00, 0x44, 0x33, 0x00, -0x11, 0x00, 0x34, 0x00, 0x14, 0x09, 0x50, 0xB6, 0x10, 0xCD, 0x03, 0x34, 0x02, -0x14, 0x3C, 0x40, 0xA3, 0x40, 0x41, 0x01, 0x34, 0x4A, 0xD0, 0x20, 0x40, 0x23, -0x02, 0x01, 0x03, 0x34, 0x6F, 0xD0, 0x11, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA0, 0xC5, 0x00, 0x93, 0x04, 0x47, 0x02, 0xF1, 0x2D, -0x80, 0xF7, 0x01, 0xDF, 0x07, 0x74, 0x03, 0xF0, 0x01, 0x40, 0x3F, 0x42, 0xD3, -0x00, 0x6C, 0x02, 0x30, 0x09, 0xC0, 0x3C, 0x00, 0xDF, 0x05, 0x74, 0x02, 0x30, -0x1D, 0xC4, 0x27, 0x00, 0x53, 0x01, 0x7C, 0x12, 0xF0, 0x25, 0xC0, 0x73, 0x00, -0xDB, 0x03, 0x7C, 0x0B, 0xF2, 0x69, 0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x08, 0x27, 0x03, 0x9F, 0x00, 0x7E, 0x0A, 0xF0, 0x1D, 0xC0, -0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x39, 0xC0, 0x77, 0x10, 0xDF, 0x03, -0x5C, 0x0A, 0xF0, 0x29, 0xC0, 0x35, 0x00, 0xDB, 0x10, 0x54, 0x80, 0xF0, 0x0D, -0xCD, 0x27, 0x01, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x85, 0xC1, 0xB7, 0x04, 0xDF, -0x04, 0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x08, 0x0B, 0x00, 0x33, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC1, 0x3F, -0x24, 0xFF, 0x30, 0xFC, 0x03, 0xF2, 0x03, 0xC4, 0x3B, 0x00, 0x73, 0x05, 0x8D, -0x02, 0x30, 0x03, 0xC2, 0x3C, 0x04, 0xF3, 0x04, 0xFC, 0x00, 0xF1, 0x0E, 0xC0, -0x06, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x27, 0xC0, 0x3C, 0x40, 0xF3, 0x02, -0xCC, 0x01, 0xF1, 0x0B, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x81, 0x20, 0xC6, 0x34, 0x91, 0x13, 0x5C, 0x16, 0xD0, 0x0D, 0x40, 0x37, 0x00, -0xDD, 0x00, 0x74, 0x03, 0xD9, 0x39, 0x40, 0x37, 0x00, 0x51, 0x04, 0x44, 0x0E, -0x10, 0x71, 0x40, 0x34, 0x00, 0xD3, 0x01, 0x74, 0x0C, 0xD0, 0x0D, 0x40, 0x44, -0x00, 0x5D, 0x03, 0x34, 0x17, 0x11, 0x34, 0x40, 0xF4, 0x04, 0x81, 0x00, 0x44, -0x07, 0xD0, 0x59, 0x48, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0xA0, 0x46, 0x00, 0x91, 0x01, 0x74, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, -0x04, 0x74, 0x83, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x91, 0x40, 0x44, 0x06, 0x90, -0x11, 0x40, 0x34, 0x20, 0xD1, 0x00, 0x74, 0x46, 0xD0, 0x1D, 0x40, 0x66, 0x04, -0x5D, 0x11, 0x74, 0x06, 0x50, 0x25, 0x40, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x0E, -0xD0, 0x11, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x20, 0x00, 0x81, 0x20, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, -0x34, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x48, 0x81, 0x00, 0x06, 0x00, 0x90, 0x08, -0x40, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x42, 0x20, 0x00, 0x49, -0x00, 0x74, 0x02, 0x18, 0x04, 0x40, 0x10, 0x00, 0xC1, 0x20, 0x04, 0x02, 0xD0, -0x08, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x40, 0x13, 0x40, 0x7E, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7E, -0x03, 0xD0, 0x01, 0xC2, 0x3F, 0x00, 0x13, 0x00, 0x4C, 0x02, 0xB0, 0x01, 0xC0, -0x3C, 0x00, 0xD3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x06, 0x00, 0x5F, 0x00, -0x7C, 0x02, 0x70, 0x05, 0xD0, 0x34, 0x10, 0x53, 0x00, 0x4C, 0x00, 0xF2, 0x01, -0xD0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x10, -0xBF, 0x00, 0xDE, 0x00, 0xF0, 0x0F, 0xC6, 0x3F, 0x00, 0xFF, 0x80, 0xFC, 0x03, -0xD0, 0x03, 0xE0, 0x3F, 0x00, 0x2F, 0x00, 0xF4, 0x00, 0x70, 0x03, 0xD0, 0x3F, -0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0xFC, -0x02, 0xF0, 0x07, 0xC8, 0x3F, 0x00, 0x3F, 0xA0, 0xFD, 0x02, 0xF0, 0x0B, 0xC0, -0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x00, 0xB3, -0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30, -0x0A, 0xC0, 0x0C, 0x01, 0x33, 0x00, 0xCC, 0x00, 0xF0, 0x03, 0xC0, 0x0B, 0x00, -0xFB, 0x06, 0xEC, 0x05, 0x30, 0x4F, 0xC1, 0x2F, 0x00, 0xF3, 0x14, 0xFC, 0x23, -0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0xF7, 0x04, 0xCC, 0x22, 0x34, 0x03, 0xC0, 0x0C, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x07, 0x10, 0x91, 0x80, -0x44, 0x00, 0x70, 0x01, 0x40, 0x07, 0x00, 0x9D, 0x00, 0x44, 0x43, 0x10, 0x09, -0x48, 0x84, 0x00, 0x91, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x27, 0x00, 0xF9, -0x0B, 0x44, 0x55, 0x15, 0x2F, 0x40, 0x6F, 0x00, 0xD1, 0x03, 0x70, 0x3B, 0xD0, -0x39, 0x40, 0x47, 0x40, 0xF1, 0x00, 0x6C, 0x0A, 0x10, 0x15, 0x40, 0x0D, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x05, 0x01, 0x20, 0x14, -0x00, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x0D, 0x20, 0x14, 0x13, 0x10, 0x00, 0x40, -0x01, 0x02, 0x01, 0x20, 0x04, 0x02, 0xD0, 0x08, 0x42, 0x23, 0x00, 0xC1, 0x04, -0x24, 0x81, 0x10, 0x0C, 0x4A, 0x27, 0x08, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x88, -0x40, 0x03, 0x00, 0xC5, 0x08, 0x44, 0xA2, 0x13, 0x08, 0x46, 0x4C, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x05, 0x11, 0x11, 0x04, 0x54, 0x04, -0xD0, 0x11, 0x41, 0x47, 0x00, 0x1D, 0x11, 0x74, 0x03, 0x10, 0x15, 0x40, 0x41, -0x00, 0x11, 0x01, 0x44, 0x04, 0xD2, 0x31, 0x4C, 0xE7, 0x00, 0xD1, 0x00, 0x64, -0x21, 0x10, 0x0D, 0x40, 0x27, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x48, -0x87, 0x00, 0xD1, 0x00, 0x64, 0x46, 0x10, 0x0D, 0x40, 0x0D, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x5D, 0x46, 0xF0, -0x39, 0xC0, 0x47, 0x01, 0x1F, 0x03, 0x5C, 0x03, 0x10, 0x29, 0xE1, 0x45, 0x40, -0x93, 0x05, 0x4C, 0x0C, 0xD0, 0x19, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x17, -0x30, 0x0D, 0x60, 0x23, 0x40, 0xDF, 0x80, 0x7C, 0x03, 0xF2, 0x09, 0xC0, 0xC7, -0x00, 0xD7, 0x00, 0x0C, 0x0E, 0x30, 0xB1, 0x81, 0x00, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x40, 0x9F, 0x01, 0xEC, 0x00, 0x70, 0x0B, -0xC0, 0x0F, 0x00, 0xAF, 0x20, 0x8C, 0x03, 0xF0, 0x0B, 0xE2, 0x0E, 0x00, 0xAF, -0x00, 0xFD, 0x00, 0xF0, 0x01, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x06, 0xF8, -0x0F, 0xC1, 0x6F, 0x00, 0xF2, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x4F, 0x02, -0xFF, 0x00, 0xDF, 0x02, 0xF0, 0x07, 0xE0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x83, 0x00, 0x4D, 0x0A, 0xF0, 0x21, 0xC0, -0x24, 0x81, 0x1F, 0x02, 0x5C, 0x03, 0x30, 0xA5, 0xC0, 0x44, 0x00, 0x1B, 0x00, -0x7C, 0x0A, 0x32, 0x29, 0xC9, 0xA6, 0x42, 0xC3, 0x00, 0x5C, 0x01, 0x34, 0x0D, -0xC0, 0x27, 0x80, 0xD3, 0x08, 0x7C, 0x03, 0x30, 0x49, 0xC0, 0x07, 0x10, 0xDF, -0x00, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x2C, 0x14, 0x91, 0x20, 0x44, 0x2A, 0xD0, 0x89, 0x41, 0x84, -0x00, 0x1D, 0x09, 0xF0, 0x03, 0x30, 0x85, 0x00, 0x24, 0x00, 0x11, 0x1A, 0x74, -0x82, 0x30, 0x01, 0x40, 0xA4, 0x00, 0xFB, 0x40, 0x44, 0x01, 0x10, 0x0F, 0x40, -0x27, 0x00, 0xF1, 0x01, 0xF4, 0x03, 0x50, 0x79, 0x40, 0x03, 0x00, 0xFD, 0x24, -0x54, 0x02, 0xB0, 0x1C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x20, 0x30, 0x08, 0x81, 0x00, 0x20, 0x26, 0xD1, 0x38, 0x40, 0x60, 0x20, -0x8D, 0x20, 0x34, 0x03, 0x10, 0x39, 0x40, 0x00, 0x00, 0x09, 0x03, 0x16, 0x02, -0x10, 0x20, 0x40, 0x04, 0x01, 0xC1, 0x00, 0x54, 0x02, 0x10, 0x3C, 0x40, 0x31, -0x00, 0xC8, 0x01, 0x14, 0x03, 0x90, 0x28, 0x40, 0x13, 0x00, 0xD9, 0x00, 0x06, -0x03, 0x10, 0x8C, 0x40, 0x5F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x02, 0x50, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x60, 0x7A, 0x20, 0xED, -0x01, 0xB4, 0x03, 0x90, 0x1E, 0x40, 0x40, 0x00, 0xE1, 0x41, 0xB6, 0x0D, 0x94, -0x16, 0x42, 0x4A, 0x00, 0xC9, 0x01, 0x84, 0x05, 0x10, 0x1E, 0x40, 0x7B, 0x00, -0xE9, 0x01, 0xB4, 0x27, 0xD0, 0x1A, 0x40, 0x5B, 0x00, 0xCD, 0x01, 0x16, 0x26, -0x90, 0x9A, 0x40, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, -0x30, 0x02, 0x01, 0x00, 0x0D, 0x01, 0xF0, 0x8D, 0xC0, 0x30, 0x04, 0xCD, 0x30, -0x7C, 0x23, 0x10, 0x08, 0xC0, 0x00, 0x01, 0x0B, 0x00, 0x7C, 0x0B, 0x30, 0x88, -0xC0, 0x12, 0x02, 0xC3, 0x00, 0x5C, 0x22, 0x32, 0x0C, 0xC1, 0x23, 0x00, 0xC9, -0x08, 0x7C, 0x03, 0x30, 0x08, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0x30, -0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x1D, -0x14, 0x7F, 0x00, 0xDD, 0x01, 0xF2, 0x87, 0xD0, 0x3D, 0x00, 0xFF, 0x08, 0xFC, -0x13, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0x70, 0x0F, 0xC8, -0x1D, 0x40, 0xFF, 0x10, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0xAB, 0x42, 0xF7, 0x20, -0xFC, 0x03, 0x70, 0x0B, 0xC8, 0x2F, 0x12, 0xFC, 0x00, 0xFC, 0x02, 0xF0, 0x03, -0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x27, 0x00, -0xDF, 0x00, 0x4E, 0x03, 0x31, 0x0D, 0xC0, 0x17, 0x00, 0x5F, 0x01, 0xCC, 0x03, -0xF0, 0x0D, 0xC0, 0x04, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x1F, -0x20, 0xDF, 0x06, 0x5C, 0x00, 0xF0, 0x2D, 0xC1, 0xB6, 0x00, 0xD3, 0x00, 0x7C, -0x03, 0xA8, 0x1D, 0xC0, 0x15, 0x00, 0xDF, 0x06, 0x4D, 0x01, 0x30, 0x1D, 0xC0, -0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x29, 0x09, 0xED, -0x20, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x07, 0xD0, -0x0C, 0x40, 0x08, 0x00, 0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x08, -0xFD, 0x10, 0xAC, 0x00, 0xD0, 0x2E, 0x44, 0x3B, 0x00, 0xE1, 0x02, 0xF4, 0x03, -0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x16, 0xC4, 0x02, 0xB0, 0x0A, 0xC0, 0x4E, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xF9, 0x00, 0xED, 0x81, -0x84, 0x07, 0x11, 0x1E, 0x48, 0xFB, 0x08, 0xED, 0x11, 0x84, 0x07, 0xD0, 0x1E, -0x40, 0x48, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0xFB, 0x00, 0xED, -0x05, 0x94, 0x44, 0xD9, 0x5E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xB4, 0x07, 0x90, -0x1C, 0x44, 0x79, 0x00, 0xED, 0x41, 0x84, 0x07, 0x10, 0x14, 0x40, 0x04, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x04, 0xCD, 0x02, 0x05, -0x83, 0x12, 0x6C, 0x60, 0x73, 0x10, 0xCD, 0x03, 0x04, 0x03, 0xD0, 0x1C, 0x50, -0x30, 0x02, 0xC1, 0x09, 0x34, 0x0B, 0xD0, 0x3C, 0x44, 0x73, 0x01, 0xCD, 0x40, -0x24, 0x04, 0xD8, 0x0C, 0x40, 0x73, 0x80, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x0C, -0x42, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0x90, 0x00, 0x50, 0x4A, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x5D, 0x00, 0x7F, 0x00, 0xCC, 0x05, -0x30, 0x27, 0xC0, 0x1F, 0x00, 0x7F, 0x08, 0x4D, 0x01, 0xF0, 0x17, 0xC1, 0x5C, -0x40, 0x73, 0x01, 0xFC, 0x01, 0xF0, 0x27, 0x40, 0x5F, 0x00, 0x5F, 0x00, 0xDC, -0x01, 0xF0, 0x05, 0xC0, 0x56, 0x41, 0x57, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0, -0x1D, 0x89, 0x5F, 0x00, 0x8C, 0x01, 0x30, 0x07, 0xC0, 0x5C, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x08, 0x1F, 0x10, 0x7C, 0x24, 0xF4, -0xA1, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47, 0x08, -0x1F, 0x26, 0x7C, 0x00, 0xF0, 0x41, 0xC2, 0x87, 0x00, 0x0F, 0x00, 0x7C, 0x00, -0xF2, 0x00, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0, 0x03, -0x00, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x83, 0x00, 0x0C, 0x02, 0x30, 0x89, -0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x60, 0x02, 0x93, -0x01, 0x7C, 0x46, 0xF0, 0x59, 0xC0, 0x23, 0x00, 0x9B, 0x00, 0x4C, 0x42, 0xB0, -0x09, 0xC0, 0x22, 0x01, 0x93, 0x00, 0x3C, 0x02, 0x90, 0x49, 0xC0, 0xA7, 0x40, -0x93, 0x00, 0x4D, 0x02, 0x14, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x00, 0xE4, 0x21, 0x91, 0x00, 0x44, 0x0E, 0x14, 0x29, 0xC0, -0x25, 0x02, 0x9D, 0x1B, 0x74, 0x02, 0xD0, 0x09, 0xC0, 0x24, 0x00, 0x95, 0x12, -0x5C, 0x22, 0xD2, 0x19, 0x40, 0x67, 0x00, 0x91, 0x80, 0x44, 0x02, 0x10, 0x29, -0x41, 0x64, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x39, 0x41, 0x67, 0x00, 0x91, -0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x64, 0x00, 0x91, 0x00, 0x44, 0x22, 0x10, 0x09, 0x41, 0x27, -0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x99, 0x08, 0x74, -0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00, 0x04, 0x82, 0x94, 0x09, 0x40, -0x26, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x20, 0x89, 0x42, -0x44, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x21, 0x82, -0x8D, 0x10, 0x34, 0x12, 0xD0, 0x58, 0x40, 0x20, 0x01, 0x8D, 0x10, 0x14, 0x42, -0xD0, 0x78, 0x41, 0x33, 0x06, 0x81, 0x00, 0x04, 0x02, 0x10, 0x48, 0x40, 0x20, -0x01, 0x85, 0x04, 0x34, 0x52, 0x59, 0x48, 0x40, 0x23, 0x01, 0x89, 0x04, 0x44, -0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB8, 0x86, 0x42, 0x03, 0x0A, 0x45, 0x31, 0x30, 0xE1, 0x40, 0x97, 0x04, 0x1F, -0x08, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x80, 0x02, 0x1B, 0x06, 0x7C, 0x19, 0xF0, -0x21, 0xC0, 0x87, 0x01, 0x1B, 0x1E, 0x4C, 0x28, 0xB1, 0xA1, 0xC0, 0x06, 0x40, -0x17, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0x80, 0x07, 0x00, 0x0B, 0x0A, 0x4C, 0x28, -0x70, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, -0x2F, 0x0A, 0xBF, 0x08, 0xFC, 0x0A, 0xF2, 0xCB, 0xC0, 0x2D, 0x00, 0xBF, 0x00, -0x7C, 0x22, 0xF0, 0x8B, 0xC8, 0x2D, 0x02, 0xB7, 0x14, 0xDC, 0x52, 0xF0, 0x0B, -0xC2, 0x3F, 0x00, 0x9F, 0x00, 0xFD, 0x83, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9B, -0x08, 0x7C, 0x02, 0x70, 0x8B, 0xC8, 0x2E, 0x02, 0x97, 0x08, 0xFC, 0x22, 0xB0, -0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8, 0x2F, -0x05, 0xD3, 0x4C, 0xCC, 0x02, 0xF1, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04, 0xFC, -0x52, 0x30, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0, -0x2D, 0x05, 0x9F, 0x0C, 0x5C, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB3, 0x05, -0x5C, 0x16, 0xB0, 0x0F, 0xC0, 0x2C, 0x00, 0xBF, 0x80, 0xCD, 0x02, 0x31, 0x0B, -0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, -0x11, 0x0C, 0x45, 0x48, 0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x54, 0x74, 0x00, -0x38, 0xC1, 0xC0, 0x90, 0x04, 0x11, 0x10, 0x44, 0x20, 0xD2, 0x41, 0x41, 0x07, -0x21, 0x1D, 0x0C, 0x44, 0x40, 0x40, 0x01, 0x41, 0x04, 0x02, 0x1B, 0x00, 0x70, -0x54, 0x10, 0x01, 0xC0, 0x96, 0x00, 0x03, 0x10, 0x45, 0x20, 0x50, 0x01, 0x40, -0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, -0x04, 0x04, 0x32, 0xD0, 0x88, 0x60, 0x23, 0x00, 0x81, 0x2C, 0x36, 0x02, 0x18, -0x4C, 0x62, 0x21, 0x4B, 0x80, 0x08, 0x24, 0x02, 0xD0, 0xC8, 0x40, 0x21, 0x2D, -0x8D, 0x44, 0x74, 0x12, 0x80, 0x88, 0x50, 0x20, 0x00, 0x85, 0x02, 0x14, 0x0A, -0x50, 0x0C, 0x48, 0x22, 0x12, 0x8D, 0x08, 0x24, 0x02, 0x10, 0x08, 0x40, 0x48, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x82, -0x44, 0x42, 0xD0, 0x0D, 0x40, 0x27, 0x05, 0x91, 0x00, 0x74, 0x02, 0x10, 0x49, -0x40, 0x25, 0x01, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x8D, -0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x74, 0x02, 0x50, -0x0D, 0x40, 0x26, 0x00, 0x91, 0x00, 0x64, 0x02, 0x50, 0x29, 0x40, 0x61, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x42, 0x93, 0x00, 0x4D, -0x02, 0xF0, 0x79, 0xC0, 0x67, 0x40, 0x93, 0x11, 0x7C, 0x02, 0x34, 0x39, 0xC1, -0x25, 0x00, 0x93, 0x10, 0x6D, 0x4E, 0xF0, 0x69, 0xC0, 0xE5, 0x00, 0x9F, 0x00, -0x7C, 0x8A, 0xB0, 0x09, 0xC0, 0x64, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x70, 0x09, -0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x6D, 0x1A, 0x30, 0x29, 0xC0, 0x14, 0xA0, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x00, 0x9F, 0x20, 0x7C, 0x26, -0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x04, 0x3C, 0x02, 0xF0, 0x19, 0xD0, 0x24, -0x00, 0x9F, 0x00, 0x4C, 0x26, 0xF0, 0x09, 0xC0, 0x67, 0x84, 0x9F, 0x00, 0x5C, -0x22, 0x70, 0x09, 0xC0, 0x67, 0x08, 0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, -0x67, 0x82, 0x9F, 0x00, 0x5D, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00, 0x0F, 0x00, 0x4E, 0x48, 0xF2, -0x41, 0xE4, 0x87, 0x01, 0x1F, 0x08, 0x7C, 0x80, 0x70, 0x00, 0xC0, 0x84, 0x00, -0x13, 0x01, 0x7C, 0x00, 0xF8, 0x21, 0xC4, 0x87, 0x08, 0x1F, 0x00, 0x5C, 0x08, -0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x87, -0x40, 0x13, 0x00, 0x0C, 0x00, 0xF0, 0xA0, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x00, 0x5D, 0x20, 0xC6, 0x1D, 0x70, 0x27, -0x40, 0x5F, 0x04, 0x7D, 0x08, 0x74, 0x15, 0xD0, 0x27, 0xC0, 0x14, 0x00, 0x71, -0x00, 0xDC, 0x09, 0xF0, 0x37, 0x60, 0x9F, 0x00, 0x5D, 0x00, 0x04, 0x01, 0x30, -0x47, 0x40, 0x17, 0x40, 0x52, 0x00, 0x5C, 0x01, 0xD0, 0x26, 0x40, 0x17, 0x04, -0x74, 0x82, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0xF2, 0x04, 0xCD, 0x00, 0x24, 0x0F, 0x50, 0x8C, 0x40, -0x77, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD0, 0x2C, 0x41, 0x36, 0x00, 0xD1, 0x20, -0x34, 0x47, 0xD2, 0x0C, 0x41, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C, -0x40, 0x23, 0x08, 0x88, 0x20, 0x74, 0x03, 0xD0, 0x20, 0x60, 0x63, 0x00, 0x90, -0x12, 0x05, 0x03, 0xD0, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x80, 0xA8, 0x10, 0xED, 0x00, 0xA4, 0x01, 0x50, 0x0E, 0x40, 0x3B, -0x20, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0B, 0x60, 0x28, 0x00, 0xE1, 0x00, 0x94, -0x09, 0x10, 0x0E, 0x41, 0x9B, 0x08, 0xCD, 0x04, 0xC4, 0x13, 0x12, 0x06, 0x40, -0x2B, 0x00, 0xE9, 0x00, 0xB6, 0x03, 0xD0, 0x06, 0x40, 0x63, 0x00, 0xE5, 0x00, -0x84, 0x02, 0xD0, 0x0E, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x18, 0x48, 0x10, 0xFF, 0x01, 0xA5, 0x07, 0x70, 0x1E, 0x40, 0x5B, 0x00, -0xED, 0x01, 0xBC, 0x87, 0xF0, 0x16, 0xC0, 0x7A, 0x42, 0xE1, 0x01, 0xBC, 0x07, -0xD0, 0x16, 0x40, 0x7B, 0x00, 0xEF, 0x09, 0x9D, 0x5F, 0x70, 0x16, 0xE4, 0x73, -0x00, 0xAB, 0x01, 0xBC, 0x07, 0xF0, 0x12, 0x80, 0x7B, 0x00, 0x21, 0x01, 0x8C, -0x07, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xB8, 0x05, 0x00, 0xDF, 0x16, 0x5C, 0x01, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xA1, 0x42, 0xD1, 0x37, 0x20, 0x1F, 0x00, 0x7C, 0x01, 0xF0, -0x05, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x3C, 0x1B, 0x70, 0x05, 0xC0, 0x37, 0x40, -0xD3, 0x00, 0x5C, 0x83, 0xF0, 0x0D, 0x80, 0x37, 0x00, 0x5B, 0x20, 0x7C, 0x02, -0xF0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, -0x4D, 0x00, 0xF7, 0x31, 0xCC, 0x13, 0xF0, 0x97, 0xC0, 0x7C, 0x00, 0xFF, 0x01, -0xFC, 0x06, 0xB0, 0x9F, 0xC0, 0x7C, 0x00, 0x73, 0x09, 0xFC, 0x27, 0xF0, 0x1F, -0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xCC, 0x07, 0x70, 0x9F, 0xC0, 0x6C, 0x40, 0xB7, -0x41, 0xCC, 0x07, 0xB0, 0x1A, 0xC0, 0x6C, 0x20, 0xBF, 0x21, 0xCC, 0x07, 0xF0, -0x1B, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0D, -0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, -0x22, 0xD0, 0xC6, 0x50, 0x28, 0x30, 0x60, 0x18, 0x9C, 0x23, 0xD0, 0x0E, 0xC0, -0x39, 0x02, 0xED, 0x04, 0x84, 0x13, 0x40, 0x03, 0xC0, 0x2A, 0x00, 0xE5, 0x00, -0xAC, 0x23, 0x10, 0x0E, 0xC2, 0x2A, 0x00, 0xE9, 0x00, 0x85, 0x42, 0xD0, 0x0E, -0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, -0xE5, 0x10, 0x84, 0x23, 0xD0, 0x06, 0x42, 0x18, 0x04, 0x6D, 0x00, 0xB4, 0x02, -0xD0, 0x06, 0x42, 0x38, 0x00, 0x61, 0x80, 0xB4, 0x02, 0xD0, 0x8A, 0x40, 0xBB, -0x00, 0xED, 0x20, 0xC4, 0x4B, 0x42, 0x06, 0x40, 0x32, 0x00, 0xA5, 0x00, 0xA4, -0x03, 0x90, 0x02, 0x40, 0x28, 0x00, 0xA5, 0x08, 0xA4, 0x03, 0xD0, 0x0A, 0x40, -0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xD1, -0x01, 0x04, 0x02, 0xD0, 0x28, 0x50, 0x80, 0x04, 0x8D, 0x47, 0x34, 0x02, 0xD0, -0x05, 0x58, 0x34, 0x42, 0x01, 0x91, 0x14, 0xCE, 0xD0, 0x39, 0x40, 0x01, 0x20, -0xCD, 0x00, 0x04, 0x07, 0x00, 0x00, 0x40, 0x32, 0x40, 0xC5, 0x00, 0x24, 0x03, -0x10, 0x0C, 0x40, 0x22, 0x00, 0xC9, 0x00, 0x24, 0x0E, 0xD0, 0x8C, 0x40, 0x1B, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x05, 0x06, 0xF5, 0x20, -0x4C, 0x02, 0xF0, 0xB9, 0xC1, 0xA4, 0x00, 0x1F, 0x05, 0x74, 0x82, 0xB0, 0x09, -0xC0, 0x74, 0x00, 0x93, 0x03, 0x7C, 0x42, 0xD0, 0x39, 0xC1, 0xB7, 0x00, 0xFF, -0x00, 0xCC, 0x07, 0x70, 0x05, 0xC0, 0x26, 0x40, 0x85, 0x00, 0xEC, 0x03, 0xB0, -0x01, 0xC8, 0x24, 0x00, 0x57, 0x80, 0x6C, 0x0E, 0xF0, 0x0D, 0xC0, 0x57, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x07, 0x20, 0xDF, 0x00, 0x7C, -0x28, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF2, 0x19, 0xC0, -0x27, 0x04, 0x9F, 0x02, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x17, 0x00, 0xCF, 0x00, -0x7D, 0x03, 0xF0, 0x05, 0xC0, 0x23, 0x40, 0x9E, 0x00, 0x7C, 0x03, 0xF0, 0x01, -0xC0, 0x27, 0x00, 0x5C, 0x00, 0x1C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0B, 0x00, 0xFB, 0x00, 0xCC, 0x42, -0xF0, 0x09, 0xC0, 0x2B, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x01, 0xC0, 0x34, -0x00, 0xB3, 0x00, 0xB4, 0x00, 0x30, 0x03, 0xC0, 0x3C, 0x00, 0xDF, 0x00, 0xCC, -0x03, 0xF0, 0x06, 0xC0, 0xEC, 0x00, 0x93, 0x08, 0x0C, 0x03, 0x34, 0x53, 0x40, -0x38, 0x00, 0xE3, 0xC0, 0xCC, 0x56, 0x31, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x01, 0xD1, 0x00, 0x44, 0x14, 0xD0, -0x39, 0x40, 0x47, 0x01, 0x91, 0x01, 0x74, 0x02, 0xC8, 0x11, 0x50, 0x34, 0x00, -0x1F, 0x83, 0x74, 0x0C, 0x12, 0x31, 0x44, 0xC4, 0x0C, 0xDF, 0x00, 0x54, 0x03, -0xF0, 0x25, 0x44, 0x24, 0x00, 0x91, 0x01, 0x45, 0x03, 0xB0, 0x04, 0x40, 0x35, -0x00, 0xD3, 0x03, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x40, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x11, -0x40, 0x67, 0x00, 0x11, 0x11, 0x76, 0x06, 0xD1, 0x19, 0x54, 0x34, 0x00, 0x91, -0x01, 0x76, 0x46, 0x10, 0x39, 0x60, 0x64, 0x10, 0xDD, 0x40, 0x44, 0x03, 0xD0, -0x25, 0x40, 0x24, 0x18, 0x91, 0x40, 0x54, 0x03, 0x10, 0x0D, 0x40, 0x25, 0x40, -0xD1, 0x0A, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0xC1, 0x40, 0x04, 0x00, 0xD0, 0x00, 0x42, -0x23, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x20, 0x00, 0x81, 0x00, -0x34, 0x02, 0x10, 0x00, 0x70, 0x00, 0x00, 0xC5, 0x00, 0x14, 0x03, 0x10, 0x00, -0x50, 0x20, 0x20, 0x81, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x48, 0x21, 0x00, 0xC9, -0x80, 0x14, 0x02, 0x10, 0x0C, 0x4C, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x06, 0x00, 0xE3, 0x00, 0x4C, 0x02, 0xD0, 0x01, 0xC2, 0x27, -0x00, 0x13, 0x00, 0x7E, 0x02, 0xC0, 0x03, 0xC0, 0x3C, 0x40, 0x91, 0x00, 0x7C, -0x00, 0x38, 0x09, 0xC0, 0x24, 0x00, 0xFC, 0x00, 0xCC, 0x83, 0xD0, 0x05, 0xC0, -0x24, 0x40, 0x93, 0x40, 0x5C, 0x03, 0x10, 0x09, 0xC0, 0x25, 0x00, 0xC3, 0x80, -0x4C, 0x02, 0x34, 0x09, 0xC0, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xB8, 0x0D, 0x00, 0xF7, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x40, -0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00, -0xF0, 0x03, 0xC4, 0x0F, 0x00, 0xFF, 0x00, 0xB8, 0x03, 0xF0, 0x03, 0xC4, 0x2F, -0x40, 0xBF, 0x00, 0xEC, 0x03, 0x70, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x00, 0xFC, -0x02, 0xF0, 0x0F, 0xC0, 0x17, 0xE0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x80, 0x7F, 0x00, 0xBF, 0x20, 0xCC, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x02, 0xF3, -0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30, -0x1F, 0xC0, 0x7D, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x00, -0xF3, 0x03, 0xEC, 0x07, 0xB0, 0x16, 0xC0, 0x5C, 0x00, 0x2B, 0x01, 0xEC, 0x05, -0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, -0x37, 0x00, 0x9D, 0x00, 0xEC, 0x0B, 0x10, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00, -0x44, 0x00, 0x14, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20, 0x40, 0x00, 0x10, 0x01, -0x40, 0x04, 0x00, 0x13, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11, -0x84, 0x4C, 0x04, 0x52, 0x1D, 0x40, 0x55, 0x00, 0x11, 0x01, 0x54, 0x03, 0xB4, -0x01, 0x40, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, -0x00, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x60, 0x33, 0x01, 0xC1, 0x00, 0x44, -0x83, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0D, 0x48, -0x34, 0x80, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x35, 0x00, 0xC1, 0x04, -0x64, 0x03, 0x10, 0x04, 0x44, 0x16, 0x80, 0x59, 0x00, 0x66, 0x83, 0x5C, 0x00, -0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, -0x9D, 0x21, 0x44, 0x03, 0x91, 0x01, 0x60, 0x03, 0x00, 0x11, 0x00, 0x60, 0x00, -0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, -0x80, 0x19, 0x20, 0x44, 0x00, 0x10, 0x01, 0x40, 0x06, 0x00, 0x11, 0x00, 0x44, -0x00, 0x50, 0x1D, 0x4C, 0x17, 0x04, 0x51, 0x10, 0x54, 0x0B, 0xDC, 0x11, 0x40, -0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0x1F, -0x33, 0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x10, 0xD3, 0x00, 0x4C, 0x03, 0x30, -0x0D, 0xC0, 0x37, 0x00, 0xDD, 0x00, 0x4D, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x00, -0xD3, 0x20, 0x0C, 0x03, 0x10, 0x0D, 0xC0, 0x31, 0x00, 0xD3, 0x00, 0x2C, 0x03, -0xB0, 0x18, 0xC0, 0x92, 0x00, 0x9B, 0x01, 0x2C, 0x0B, 0x70, 0x59, 0xC2, 0x00, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0xAF, 0x00, -0xFC, 0x03, 0x72, 0x03, 0xCB, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, -0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0E, 0x04, 0x37, -0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x04, 0x3F, 0x00, 0xFC, 0x00, 0xF0, -0x0F, 0xC0, 0x8D, 0x10, 0xBF, 0x08, 0xFC, 0x23, 0xB0, 0x09, 0xC0, 0x3F, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x06, 0x1F, 0x00, 0x7C, -0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0xC0, -0x34, 0x1B, 0xD3, 0x00, 0x4C, 0x47, 0x30, 0x1D, 0xC0, 0x77, 0x00, 0xD7, 0x01, -0x7C, 0x47, 0xF0, 0x0D, 0xC0, 0x34, 0x02, 0xDF, 0x00, 0x4D, 0x43, 0x30, 0x0D, -0xC0, 0x35, 0x00, 0x9F, 0x06, 0x4C, 0x0B, 0x30, 0x01, 0xC0, 0x29, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74, 0x10, 0x9D, 0x08, 0xF4, 0x03, -0xD1, 0x21, 0x40, 0x04, 0x00, 0x1D, 0x03, 0x1C, 0x00, 0xD0, 0x81, 0x40, 0xC4, -0x00, 0x01, 0x00, 0x44, 0x0C, 0x12, 0x31, 0x40, 0x47, 0x00, 0x15, 0x03, 0x74, -0x04, 0xD0, 0x21, 0x40, 0x44, 0x00, 0x1D, 0x0B, 0x46, 0x40, 0xB2, 0xAD, 0x48, -0xC4, 0x22, 0x8B, 0x07, 0x6C, 0x0B, 0xA0, 0x91, 0xC0, 0x4C, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0xF2, 0x00, 0x0D, 0x09, 0x74, 0x17, 0xD0, -0x0C, 0x40, 0x32, 0x00, 0xDD, 0x04, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xF0, 0x00, -0xC1, 0x0C, 0x54, 0x03, 0x14, 0x4C, 0x40, 0x33, 0x00, 0xD9, 0x04, 0x34, 0x0B, -0xD0, 0x4C, 0x40, 0xB0, 0x20, 0xD9, 0x00, 0x04, 0x0B, 0x10, 0x24, 0x40, 0x53, -0x00, 0xC1, 0x01, 0x24, 0x22, 0x90, 0x99, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x47, 0xD8, 0x13, -0x40, 0x4A, 0x00, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4C, 0x00, 0x21, -0x01, 0xC4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x2D, 0x08, 0xB4, 0x00, 0xD0, -0x12, 0x40, 0x48, 0x00, 0x2D, 0x31, 0x84, 0x04, 0x90, 0x9F, 0x44, 0x5E, 0x08, -0x79, 0x21, 0xA4, 0x0F, 0x90, 0x12, 0x48, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, -0x32, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x30, 0x00, 0xD3, 0x00, -0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x37, 0x80, 0xC9, 0x00, 0x3C, 0x03, 0xD0, 0x0D, -0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x23, 0x30, 0x04, 0xC0, 0x13, 0x14, 0xC3, -0x00, 0x4C, 0x23, 0xB0, 0x88, 0xC6, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x83, 0xF0, 0x02, 0xC0, 0x0D, -0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x02, 0x3F, 0x08, 0x7C, -0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x08, 0xFC, 0x10, 0xF0, 0x01, 0x80, -0x0F, 0x00, 0x3E, 0x00, 0xBC, 0x84, 0xF9, 0x0F, 0xC8, 0x19, 0x00, 0x7F, 0x00, -0xFC, 0x23, 0xF0, 0x03, 0xC8, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0x37, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, -0xDF, 0x00, 0x7C, 0x07, 0x34, 0x1D, 0xD0, 0x30, 0x00, 0xD3, 0x01, 0x4D, 0x03, -0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x1D, 0xD0, 0x34, -0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x1C, 0xD0, 0x54, 0x00, 0xD3, 0x00, 0x4C, -0x03, 0xD1, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x88, 0x39, 0x00, 0x6D, 0x00, 0xB4, 0x2B, 0xD0, 0x02, 0x40, 0x0B, 0x00, 0x2D, -0x00, 0xF4, 0x00, 0x10, 0x03, 0x40, 0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0xD0, -0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x03, 0x40, 0x08, 0x10, -0x2D, 0x00, 0xA4, 0x00, 0xD0, 0x0E, 0x40, 0x18, 0x40, 0xE1, 0x00, 0x94, 0x03, -0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -0x79, 0x00, 0xED, 0x03, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, -0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, -0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x78, 0x00, 0xED, -0x01, 0xA5, 0x07, 0xD0, 0x1F, 0x49, 0x58, 0x80, 0xF5, 0x01, 0x84, 0x07, 0xD0, -0x1E, 0x42, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, -0x00, 0xDD, 0x01, 0x34, 0x03, 0xD0, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34, -0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0xD0, 0x00, 0x44, -0x07, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00, -0x24, 0x00, 0xD0, 0x5C, 0x44, 0xD0, 0x01, 0xC5, 0x13, 0x14, 0x4F, 0xD8, 0x5D, -0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, -0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, -0x30, 0x05, 0xC0, 0x14, 0x50, 0x53, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0, 0x17, -0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x44, -0x01, 0xD0, 0x27, 0xC0, 0xDC, 0x00, 0x67, 0x07, 0x8C, 0x01, 0xF0, 0x57, 0x44, -0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, -0x12, 0x7C, 0x00, 0xF2, 0x23, 0xC0, 0x0F, 0x00, 0x3F, 0x02, 0xFC, 0x00, 0xF0, -0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00, -0x3F, 0x02, 0xFC, 0x80, 0xF3, 0x23, 0xC0, 0x8F, 0x00, 0x3F, 0x22, 0xDC, 0x00, -0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1B, 0x00, 0x7C, 0x20, 0xF0, 0x21, 0xC0, 0x4B, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x05, -0x4C, 0x06, 0xF0, 0x99, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x67, 0x40, 0x93, -0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x22, 0xF0, -0x49, 0xE0, 0xA7, 0x00, 0x9F, 0x00, 0x5E, 0x0A, 0x30, 0x09, 0xC0, 0x40, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x04, 0x9D, 0x12, 0x44, -0x02, 0xD0, 0x29, 0x41, 0x20, 0x00, 0x91, 0x00, 0x74, 0x0E, 0xD0, 0x19, 0x41, -0x27, 0x00, 0x91, 0x03, 0x74, 0x02, 0xD0, 0x19, 0x40, 0x67, 0x00, 0x91, 0x02, -0x74, 0x02, 0xD8, 0x39, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x45, 0x86, 0xD0, 0x39, -0x40, 0x67, 0x14, 0x97, 0x0A, 0x44, 0x0A, 0x56, 0x49, 0x40, 0x04, 0x08, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x64, 0x2A, -0xD0, 0x09, 0x40, 0x2C, 0x08, 0xB1, 0x00, 0xF4, 0x0E, 0xD0, 0x1B, 0x40, 0xAF, -0x02, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x02, 0xB1, 0x02, 0xF4, -0x0A, 0xD1, 0x1B, 0x41, 0x2F, 0x01, 0xA9, 0x00, 0xC6, 0x02, 0x91, 0x09, 0x40, -0x25, 0x00, 0x9D, 0x42, 0x54, 0x02, 0x15, 0x49, 0x40, 0x60, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x14, 0x25, 0x12, 0xD0, -0x0A, 0x40, 0x2C, 0x00, 0xE1, 0x80, 0xB4, 0x02, 0xD0, 0x0A, 0x4A, 0x2B, 0x00, -0xA1, 0x00, 0xB4, 0x06, 0xD0, 0x0E, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x02, -0xD2, 0x0A, 0x40, 0x2B, 0x00, 0xED, 0x08, 0x84, 0x02, 0xD2, 0x0C, 0x4A, 0x23, -0x00, 0x95, 0x00, 0x64, 0x06, 0x58, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x04, 0x6C, 0x28, 0xF0, 0xA1, -0xC8, 0x84, 0x42, 0x13, 0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13, -0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x7C, 0x28, 0xD0, -0xA1, 0xC0, 0x87, 0x02, 0x0F, 0x82, 0xCC, 0x01, 0xF8, 0x01, 0xCA, 0x05, 0x00, -0x1F, 0x00, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x19, 0xB8, 0x27, 0x05, 0xBF, 0x14, 0x5C, 0x22, 0xF0, 0x09, 0xD0, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x20, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xE0, 0x0B, 0xC0, 0x2B, 0x00, 0xA7, -0x40, 0xDC, 0x02, 0xF0, 0x8B, 0xD4, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0x80, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x32, 0x30, 0x0A, 0xC0, 0x24, -0x00, 0xAF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC, -0x02, 0xF0, 0x8B, 0xC8, 0x2F, 0x08, 0xBF, 0x00, 0xFC, 0x22, 0x70, 0x0B, 0xC0, -0x2F, 0x00, 0xB3, 0x28, 0xCE, 0x02, 0xF0, 0x0A, 0xC0, 0x2E, 0x00, 0xB3, 0x00, -0xFC, 0x02, 0xC1, 0x0B, 0xC2, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x00, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x30, 0x10, 0x01, 0x41, 0x04, 0x04, -0x1D, 0x20, 0x74, 0x50, 0xD0, 0x41, 0x4C, 0x07, 0x01, 0x11, 0x10, 0x74, 0x40, -0xD0, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x10, 0xD0, 0x01, 0x41, 0x07, -0x04, 0x01, 0x00, 0x44, 0x00, 0xD0, 0x01, 0xC0, 0x16, 0x00, 0x1B, 0x00, 0x74, -0x00, 0xD0, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA2, 0x23, 0x21, 0x8D, 0x14, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x00, 0x8D, -0x00, 0x34, 0x12, 0xD0, 0x48, 0x41, 0x23, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0, -0x08, 0x40, 0x23, 0x01, 0x8D, 0x14, 0x34, 0x12, 0x50, 0x48, 0x40, 0x27, 0x00, -0x85, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x44, 0x24, 0x00, 0x85, 0x40, 0x34, 0x82, -0xD1, 0x08, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, -0x25, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x12, 0x09, 0x50, 0x24, 0x20, 0x9D, 0x00, -0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, -0x40, 0x27, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0x91, -0x00, 0x64, 0x82, 0xD1, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x01, 0x74, 0x0A, 0xD8, -0x09, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0x27, -0x00, 0x9D, 0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF1, 0x09, 0xC0, 0x27, 0x20, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x40, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, -0x4C, 0x02, 0xF0, 0x09, 0x80, 0x20, 0x00, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x49, -0xCA, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, -0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x7C, 0x02, -0xF0, 0x09, 0xC8, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC6, 0x27, 0x50, 0x9F, 0x80, 0x5C, -0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9B, 0x00, 0x7E, 0x12, 0xF0, 0x49, 0xD1, -0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, -0x04, 0x3C, 0x40, 0x30, 0x01, 0xD0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0x00, 0xF0, -0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x11, 0xC0, 0x06, 0x00, -0x1F, 0x01, 0x7C, 0x20, 0xF0, 0x91, 0xC0, 0x07, 0x04, 0x13, 0x80, 0x7C, 0x40, -0xF0, 0x11, 0xC4, 0x84, 0x04, 0x1F, 0x10, 0x5C, 0x48, 0xF0, 0x21, 0xC0, 0x53, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x9C, 0x00, 0x7D, 0x12, -0xF4, 0x01, 0x12, 0x17, 0xC0, 0x14, 0x20, 0x71, 0x0A, 0xEC, 0x01, 0xD0, 0x87, -0x48, 0x9F, 0x80, 0x7D, 0x00, 0xF4, 0x6D, 0xD0, 0x07, 0xC0, 0x1E, 0x00, 0x7D, -0x00, 0xF4, 0x29, 0x70, 0x07, 0xC0, 0x99, 0x00, 0x71, 0x81, 0xCC, 0x0D, 0xD1, -0x16, 0x44, 0x1C, 0x20, 0x7D, 0x02, 0xC4, 0x15, 0xC0, 0x27, 0x40, 0x43, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF2, 0x03, 0xCD, 0x01, 0x34, -0x03, 0x10, 0x9D, 0x41, 0x30, 0x00, 0xC1, 0x02, 0x04, 0x13, 0xD0, 0x2C, 0x48, -0xB7, 0x01, 0xCD, 0x10, 0x34, 0x0B, 0xD0, 0x0C, 0x42, 0x30, 0x01, 0xCD, 0x00, -0x34, 0x07, 0xD0, 0x1C, 0x40, 0x31, 0x00, 0xD1, 0x08, 0x14, 0x09, 0xD8, 0x9C, -0x40, 0x31, 0x10, 0x0D, 0x01, 0x14, 0x0F, 0xD0, 0x8D, 0x40, 0x43, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0x34, 0x01, -0x10, 0x0F, 0x40, 0x78, 0x41, 0xF1, 0x01, 0x84, 0x43, 0xD0, 0x0E, 0x41, 0x3B, -0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x60, 0x38, 0x00, 0xED, 0x10, 0xB4, -0x01, 0x50, 0x0E, 0x42, 0x39, 0x40, 0x21, 0x00, 0xA4, 0x08, 0xD0, 0x0E, 0x40, -0x29, 0x00, 0x7D, 0x11, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x58, 0x08, 0xEF, 0x01, 0xBC, 0x07, 0x30, -0x1E, 0xC0, 0x7C, 0x05, 0xE3, 0x01, 0x84, 0x07, 0xF0, 0x16, 0xC0, 0x7B, 0x00, -0xED, 0x01, 0xB4, 0x05, 0xF0, 0x1F, 0x40, 0x58, 0x00, 0xEF, 0x01, 0xBC, 0x07, -0xF0, 0x1E, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0x9C, 0x05, 0xF0, 0x0E, 0xC0, 0x69, -0x10, 0x2F, 0x01, 0x9C, 0x05, 0xF2, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xBA, 0x15, 0x00, 0xDF, 0x20, 0x7C, 0x02, 0xF4, 0x0D, -0xC8, 0x35, 0x23, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, -0x00, 0x7C, 0x01, 0xF0, 0x09, 0xD8, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC4, 0x25, 0x80, 0xDF, 0x00, 0x5C, 0x00, 0xF2, 0x0D, 0xC0, 0x26, 0x00, -0x8F, 0x20, 0x7C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA0, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x87, 0xF9, 0x0F, 0xC0, -0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x25, 0xF0, 0x1E, 0xC0, 0x7C, 0x00, 0xFF, 0x09, -0xDC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x0A, 0x7F, 0x81, 0xCC, 0x87, 0xF0, 0x17, -0xC0, 0x5F, 0x22, 0xF3, 0x01, 0xCC, 0x25, 0x30, 0x1A, 0xC0, 0x78, 0x02, 0x23, -0x01, 0xCC, 0x06, 0xF0, 0x9B, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x88, 0x39, 0x22, 0x6D, 0x00, 0xB4, 0x19, 0xD8, 0x46, 0x40, 0x3B, -0x05, 0xED, 0x04, 0xB4, 0x83, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0x6D, 0x00, 0xB4, -0x88, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xAD, 0x18, 0x85, 0x0A, 0xD0, 0xAE, 0x40, -0x1F, 0x03, 0x21, 0x84, 0xC4, 0x01, 0xB0, 0x4A, 0x40, 0xA8, 0x02, 0x2F, 0x00, -0x94, 0x02, 0xD0, 0x8A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x19, 0x00, 0xED, 0x00, 0xB4, 0x81, 0xD0, 0x8A, 0x41, 0x39, 0x20, -0x6D, 0x90, 0xB4, 0x08, 0xD1, 0x23, 0x40, 0x38, 0x00, 0xED, 0x20, 0x96, 0x23, -0xD0, 0x0E, 0x40, 0x1B, 0x10, 0xFD, 0x00, 0x84, 0x03, 0xD0, 0x22, 0x40, 0x3B, -0x60, 0xB1, 0x00, 0xD6, 0x01, 0x11, 0x0E, 0x48, 0x28, 0x00, 0x25, 0x0A, 0x84, -0x40, 0xD0, 0x8A, 0x41, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x28, 0x05, 0x00, 0x8D, 0x03, 0x74, 0x00, 0xD0, 0x30, 0x44, 0xF3, 0x00, 0x1D, -0x03, 0x74, 0x02, 0xD0, 0x08, 0x40, 0xC0, 0x00, 0x0D, 0x02, 0x74, 0x0C, 0xD0, -0x39, 0x00, 0xE7, 0x00, 0x9D, 0x02, 0x44, 0x0E, 0xD0, 0x08, 0x40, 0xE3, 0x00, -0x81, 0x02, 0x14, 0x08, 0x90, 0x1C, 0x44, 0x20, 0x04, 0x0D, 0x00, 0x56, 0x0C, -0xD0, 0x28, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x28, -0x25, 0x00, 0x1F, 0x06, 0x7E, 0x02, 0xD8, 0x91, 0xC8, 0xB9, 0x00, 0x1F, 0x01, -0x7C, 0x16, 0xF0, 0x59, 0xC0, 0x84, 0x04, 0x1D, 0x07, 0x5C, 0x06, 0xF0, 0x19, -0xC0, 0x27, 0x04, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x58, 0xC0, 0x67, 0x02, 0xC3, -0x00, 0x1C, 0x4D, 0x10, 0x8C, 0xD0, 0xE0, 0x01, 0x17, 0x00, 0x4C, 0x0E, 0xF0, -0x01, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, -0x00, 0x9F, 0x02, 0x7C, 0x82, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0x9F, 0x10, 0x7C, -0x0A, 0xF0, 0x09, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x6A, 0xF0, 0x89, 0xC1, -0xA7, 0x04, 0x9F, 0x10, 0x7C, 0x60, 0xF0, 0x09, 0xC8, 0x87, 0x02, 0x1F, 0x23, -0x6C, 0x00, 0xF0, 0x8D, 0xC2, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2D, 0x00, -0x33, 0x10, 0xFC, 0x02, 0x30, 0x0B, 0xE2, 0x3F, 0x04, 0xB3, 0x00, 0xCC, 0x00, -0x38, 0x0B, 0xC0, 0x2F, 0x04, 0xBF, 0x10, 0xFC, 0x02, 0x30, 0x03, 0xC2, 0x2C, -0x80, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xC0, 0x2C, 0x00, 0x7F, 0x10, 0xCC, -0x41, 0x31, 0x0F, 0xC0, 0x2D, 0x10, 0x33, 0x00, 0xFC, 0x42, 0x30, 0x0A, 0xC0, -0x04, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x91, -0x05, 0x74, 0x06, 0x12, 0x39, 0x40, 0x37, 0x00, 0x91, 0x81, 0x44, 0x04, 0xB8, -0x19, 0x44, 0x47, 0x30, 0x9D, 0x43, 0x5C, 0x0E, 0x10, 0x31, 0x40, 0x65, 0x00, -0x1F, 0x01, 0x44, 0x0C, 0x10, 0x11, 0x40, 0x44, 0x01, 0x5D, 0x02, 0x4C, 0x0C, -0x70, 0x3D, 0x40, 0xE4, 0x00, 0x95, 0x01, 0x74, 0x0C, 0x12, 0x71, 0x40, 0x04, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC4, 0x40, 0x11, 0x01, -0x74, 0x06, 0x14, 0x39, 0x44, 0x37, 0x00, 0x11, 0x03, 0x44, 0x46, 0x1A, 0x11, -0x41, 0x67, 0x00, 0x9D, 0x43, 0x74, 0x06, 0x10, 0x11, 0x40, 0x44, 0x04, 0x11, -0x01, 0x44, 0x06, 0x10, 0x19, 0x64, 0x66, 0x00, 0xDD, 0x02, 0x44, 0x45, 0x10, -0xA5, 0x40, 0x66, 0x20, 0x19, 0x81, 0x74, 0x0E, 0x11, 0x11, 0x54, 0x04, 0x08, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x01, 0x00, 0x34, -0x02, 0x10, 0x00, 0x68, 0x37, 0x00, 0x81, 0x00, 0x05, 0x02, 0x10, 0x00, 0x40, -0x63, 0x00, 0x0D, 0x00, 0x16, 0x00, 0x14, 0x08, 0x50, 0x00, 0x40, 0x81, 0x00, -0x05, 0x02, 0x1C, 0x09, 0x64, 0x02, 0x00, 0x1D, 0x00, 0x45, 0x00, 0x94, 0x0D, -0x40, 0x02, 0x00, 0x0D, 0x00, 0x34, 0x02, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0x11, 0x00, 0x7C, 0x00, -0x30, 0x09, 0x60, 0x3F, 0x40, 0x13, 0x00, 0x4C, 0x00, 0x14, 0x01, 0xC0, 0x27, -0x20, 0x9F, 0x00, 0x7E, 0x82, 0x30, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x4C, -0x00, 0x30, 0x01, 0xC0, 0x26, 0x00, 0x1F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xD0, -0x27, 0x08, 0x1B, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xD0, 0x04, 0x64, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF1, -0x03, 0xC2, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00, -0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x2F, 0x40, 0xCC, 0x00, 0x59, 0x0F, 0xC8, 0x2D, -0x00, 0x37, 0x80, 0xFC, 0x02, 0xF4, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA0, 0x0F, 0x00, 0x3F, 0x41, 0xEC, 0x02, 0xF0, 0x0F, -0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xBE, 0x07, 0xF0, 0x03, 0xC1, 0x3E, 0x00, 0xA3, -0x01, 0xDC, 0x00, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0xAC, 0x01, 0xDC, 0x33, 0x34, -0x3F, 0xC0, 0x2F, 0x80, 0xA3, 0x01, 0xFC, 0x53, 0xF0, 0x83, 0xC0, 0x4F, 0x00, -0x33, 0x01, 0xBC, 0x0C, 0x30, 0x13, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x08, 0x27, 0x12, 0x1D, 0x00, 0x44, 0x02, 0xD0, 0x0F, 0x44, -0x04, 0x14, 0x1D, 0x00, 0x55, 0x07, 0xD0, 0x21, 0x50, 0x3C, 0x00, 0x91, 0x41, -0x44, 0x02, 0x10, 0x01, 0x40, 0x27, 0x20, 0x9D, 0x11, 0x54, 0x3B, 0x10, 0x4D, -0x40, 0x27, 0x20, 0x91, 0x10, 0x74, 0x0F, 0xD2, 0x0B, 0x40, 0x07, 0x08, 0x11, -0x80, 0x74, 0x00, 0x14, 0x05, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x03, 0x00, 0x0D, 0x00, 0x05, 0x00, 0xD0, 0x0C, 0x40, 0x20, -0x08, 0x8D, 0x00, 0x35, 0x02, 0x50, 0x00, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x14, -0x02, 0x10, 0x08, 0x44, 0x03, 0x00, 0x9D, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x60, -0x23, 0x00, 0x81, 0x04, 0x34, 0x03, 0xD0, 0x58, 0x48, 0x23, 0x15, 0x81, 0x14, -0x34, 0x10, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x88, 0x65, 0x10, 0x1D, 0x03, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x44, 0x00, -0x1D, 0x01, 0x54, 0x12, 0xD0, 0x00, 0x40, 0x35, 0x00, 0xD1, 0x00, 0x44, 0x06, -0x14, 0x19, 0x40, 0x47, 0x14, 0x9D, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x27, -0x42, 0x91, 0x20, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74, -0x04, 0x10, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x88, 0x47, 0x04, 0x1F, 0x01, 0x4C, 0x8E, 0xF1, 0x0D, 0xC8, 0x64, 0x20, 0x0F, -0x43, 0x7D, 0x07, 0x70, 0x55, 0xC0, 0x35, 0x40, 0xC3, 0x00, 0x5C, 0x14, 0x30, -0x59, 0xC0, 0xE7, 0x00, 0x8E, 0x00, 0x5C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x20, -0xD1, 0x20, 0x7C, 0x03, 0xF2, 0x19, 0xC2, 0x47, 0x00, 0x13, 0x81, 0x3C, 0x02, -0x34, 0x01, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, -0x2D, 0x08, 0x3F, 0x00, 0xFC, 0x42, 0xF0, 0x0E, 0xC0, 0x2F, 0x00, 0x3F, 0x00, -0xFC, 0x03, 0xF0, 0x87, 0xC0, 0x38, 0x00, 0xFF, 0x00, 0xBC, 0x42, 0xF0, 0x0B, -0xC1, 0x2F, 0x00, 0xBF, 0x04, 0xBC, 0x03, 0x70, 0x0F, 0xC0, 0x7B, 0x20, 0xBF, -0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x02, 0xF0, -0x07, 0xC1, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x05, -0x00, 0x13, 0x02, 0x5D, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C, -0x82, 0x30, 0x27, 0xC0, 0x34, 0x44, 0xD3, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC6, -0x87, 0x04, 0x9F, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x20, -0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x64, 0x00, 0x93, 0x01, 0x7C, 0x02, 0x30, 0x01, -0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, -0x01, 0x00, 0x44, 0x06, 0xD0, 0x2F, 0xC5, 0x26, 0x00, 0x9B, 0x20, 0x74, 0x02, -0xB0, 0x45, 0x40, 0x7C, 0x40, 0xD1, 0x01, 0x6C, 0x02, 0xD0, 0x29, 0x40, 0x87, -0x00, 0x9D, 0x00, 0xC4, 0x03, 0x12, 0x0D, 0x40, 0xB7, 0x06, 0x91, 0x0A, 0xC4, -0x03, 0xD0, 0x0D, 0x50, 0xE4, 0x00, 0x91, 0x03, 0x74, 0x42, 0x10, 0x05, 0x40, -0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x80, 0x01, -0x12, 0x04, 0x20, 0xD0, 0x3C, 0x41, 0x00, 0x00, 0x81, 0x09, 0x24, 0x03, 0x10, -0x00, 0x40, 0x30, 0x20, 0x8D, 0x13, 0x24, 0x08, 0x90, 0x20, 0x40, 0x83, 0x00, -0xCD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x00, 0x23, 0x00, 0x81, 0x02, 0x04, 0x03, -0xC0, 0x08, 0x40, 0x90, 0x14, 0x41, 0x12, 0x34, 0x85, 0x10, 0x08, 0x40, 0x1F, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x68, 0x40, 0x21, 0x01, -0x84, 0x07, 0xD0, 0x1C, 0x40, 0x5A, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x90, 0x10, -0x54, 0x70, 0x26, 0xAD, 0x91, 0xA4, 0x05, 0xD0, 0x12, 0x08, 0x6B, 0x02, 0xFD, -0x01, 0x84, 0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0xB5, 0x01, 0x84, 0x07, 0xD0, -0x9A, 0x40, 0x58, 0x02, 0x61, 0x81, 0xF4, 0x0D, 0x12, 0x9E, 0x40, 0x13, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x24, 0x02, 0x11, 0x00, 0x1D, -0x21, 0xF0, 0x0C, 0x40, 0xB4, 0x00, 0xC3, 0x02, 0x3C, 0x03, 0x30, 0x40, 0xC0, -0x30, 0x02, 0xCF, 0x00, 0x2C, 0x00, 0xB3, 0x84, 0xC0, 0x13, 0x8A, 0xCF, 0x00, -0x5C, 0x03, 0x70, 0x0C, 0xC0, 0x27, 0x40, 0x83, 0x08, 0x0C, 0x03, 0xF0, 0x0C, -0xC0, 0x34, 0x02, 0xC3, 0x04, 0x3C, 0x01, 0x30, 0x08, 0xC0, 0x4B, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x88, 0xFC, 0x01, -0xC0, 0x0F, 0xC1, 0x1D, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x03, 0xC0, 0xBF, -0x06, 0xF3, 0x08, 0xFC, 0x21, 0xF0, 0x8F, 0xC8, 0x3F, 0xA2, 0xFF, 0x08, 0xFC, -0x23, 0xF0, 0x0F, 0xC0, 0x3E, 0x02, 0xBB, 0x20, 0xFD, 0x43, 0xF0, 0x0F, 0xC0, -0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2F, 0x00, 0x0F, 0x00, 0x4C, 0x01, 0xF0, -0x4D, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF8, 0x01, 0xC0, 0xB6, 0x40, -0xD3, 0x01, 0x7C, 0x81, 0xF2, 0x05, 0xC8, 0x77, 0x00, 0x93, 0x00, 0x6C, 0x23, -0x30, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x29, 0xC0, 0x54, -0x00, 0x53, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x56, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0x88, 0x29, 0x00, 0x2D, 0x00, 0x84, 0x03, 0xD0, 0x0E, -0x41, 0x3B, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x03, 0x50, 0x38, 0x01, 0xE1, -0x00, 0x84, 0x03, 0xD1, 0x0E, 0x40, 0x3F, 0x00, 0xA1, 0x00, 0x94, 0x83, 0x10, -0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x00, 0xB6, 0x13, 0xD0, 0x8A, 0x40, 0x19, 0x00, -0x61, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x00, 0x69, 0x00, 0x3D, 0x01, 0x84, 0x0F, 0xD1, 0x5E, 0x40, -0x7B, 0x00, 0xED, 0x81, 0xB4, 0x07, 0xD2, 0x12, 0x40, 0x71, 0x00, 0xE1, 0x11, -0x94, 0x07, 0xD0, 0x16, 0x40, 0x7B, 0x00, 0xB9, 0x43, 0x24, 0x07, 0x50, 0x1E, -0x40, 0x73, 0x00, 0xED, 0x01, 0xB4, 0x17, 0xD0, 0x1C, 0x41, 0x78, 0x00, 0xE1, -0x01, 0x84, 0x07, 0xD0, 0x1A, 0x40, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x28, 0x73, 0x10, 0xCD, 0x40, 0x04, 0x0F, 0xD0, 0x0C, 0x40, 0xB3, -0x00, 0xCD, 0x02, 0x34, 0x03, 0xD0, 0x69, 0x40, 0x37, 0x00, 0xC1, 0x00, 0x06, -0x27, 0xD0, 0x9D, 0x40, 0x33, 0x00, 0x99, 0x00, 0x14, 0x03, 0x10, 0x0D, 0x40, -0x77, 0x02, 0x89, 0x08, 0x34, 0x03, 0xD0, 0x6D, 0x42, 0x31, 0x00, 0xD1, 0x00, -0x44, 0x03, 0xD0, 0x0C, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x17, 0xA8, 0x5D, 0x01, 0x7F, 0x02, 0xCD, 0x05, 0xF0, 0x05, 0xC0, 0x5F, 0x04, -0x7D, 0x0B, 0x7C, 0x81, 0xF0, 0x37, 0xC0, 0x15, 0x00, 0x53, 0x00, 0xDC, 0x09, -0xF0, 0xA7, 0xC0, 0x1F, 0x41, 0x5B, 0x00, 0x6C, 0x01, 0x34, 0x05, 0xC0, 0x17, -0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xE0, 0x14, 0x40, 0x53, 0x00, 0x4D, -0x01, 0xF0, 0x05, 0xC0, 0x5E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x00, 0x07, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0xF0, 0x01, 0xCC, 0x07, 0x00, 0x1F, -0x0A, 0x7C, 0x00, 0xF8, 0x81, 0x40, 0x04, 0x10, 0x1F, 0x02, 0x5C, 0x48, 0xF8, -0x21, 0xC2, 0x07, 0x01, 0x17, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC0, 0x87, 0x40, -0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04, -0xF0, 0x01, 0xC8, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, -0x23, 0x00, 0x9B, 0x00, 0x4E, 0x62, 0xF0, 0x19, 0xC0, 0x27, 0x04, 0x87, 0x04, -0x4C, 0x82, 0xF0, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x40, 0x7C, 0x02, 0xF2, 0x09, -0xC0, 0x24, 0x00, 0x9E, 0x80, 0x2C, 0x02, 0x70, 0x09, 0xC0, 0x64, 0x08, 0x93, -0x05, 0x78, 0x06, 0xF0, 0x09, 0x40, 0x26, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0x30, -0x39, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, -0x00, 0x81, 0x04, 0x44, 0x0A, 0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44, -0x02, 0xD0, 0x09, 0xC0, 0x26, 0x40, 0x91, 0x01, 0x74, 0x16, 0xD0, 0x19, 0x40, -0xA4, 0x00, 0x9D, 0x80, 0x4C, 0x82, 0x10, 0x09, 0x40, 0x24, 0x41, 0x91, 0x01, -0x74, 0x06, 0xD2, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x03, 0x44, 0x02, 0x12, 0x08, -0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08, -0x99, 0x00, 0x44, 0x8A, 0xD0, 0x69, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x82, -0x50, 0x09, 0x40, 0x24, 0x02, 0x99, 0x21, 0x56, 0x12, 0x90, 0x69, 0x42, 0x24, -0x86, 0x9D, 0x00, 0x64, 0x02, 0x50, 0x09, 0x40, 0x24, 0x02, 0x91, 0x00, 0x74, -0x22, 0xD0, 0x09, 0x40, 0x67, 0x00, 0xBD, 0x04, 0xC4, 0x02, 0x1C, 0x0F, 0x40, -0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x01, 0x91, -0x00, 0x04, 0x82, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04, 0x02, 0xD2, -0x48, 0x40, 0x30, 0x01, 0xC9, 0x00, 0x34, 0x1A, 0xD8, 0x08, 0x41, 0x20, 0x80, -0x8D, 0x00, 0x04, 0x22, 0x10, 0x08, 0x50, 0x20, 0x01, 0x81, 0x00, 0x34, 0x12, -0xD0, 0x48, 0x40, 0x69, 0x00, 0xAD, 0x01, 0x84, 0x06, 0x00, 0x0B, 0x40, 0x40, -0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x22, 0x1B, 0x0A, -0x45, 0x18, 0xF0, 0x21, 0xC0, 0x87, 0x02, 0x1F, 0x06, 0x4C, 0x00, 0xF0, 0xA1, -0x50, 0x84, 0x02, 0x1B, 0x00, 0x5C, 0x08, 0xB0, 0x61, 0xD0, 0x84, 0x00, 0x1F, -0x0A, 0x6C, 0x58, 0x71, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0, -0xA1, 0xC0, 0x83, 0x02, 0x0F, 0x4A, 0x4C, 0x28, 0x30, 0xA2, 0xD0, 0x74, 0xC0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x12, 0xBF, 0x00, 0xFC, -0x5A, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x46, 0xFD, 0x02, 0xF0, 0x8B, 0xC0, -0x27, 0x22, 0xA7, 0x20, 0xFC, 0x0A, 0xF0, 0x4B, 0xC3, 0x2F, 0x27, 0xAF, 0x00, -0x5C, 0x12, 0xF0, 0x09, 0xC8, 0x2F, 0x02, 0xBD, 0x00, 0x7C, 0x22, 0xF0, 0x8B, -0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x05, 0xBF, 0x08, 0xEC, 0x02, -0x30, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x04, 0x7C, 0x02, 0x30, 0xCA, 0xC0, 0x2C, -0x00, 0x83, 0x40, 0xD0, 0x22, 0xF0, 0x4B, 0xC0, 0x2F, 0x05, 0x8F, 0x88, 0x5C, -0x82, 0xB0, 0x09, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC, 0x16, 0xF0, 0x49, 0xD0, -0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x22, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x03, 0x01, 0x5D, 0x04, 0x44, 0x48, 0x14, -0x01, 0x49, 0x04, 0x02, 0x17, 0x14, 0x74, 0x00, 0x14, 0xC1, 0x44, 0x80, 0x04, -0x11, 0x00, 0x44, 0x20, 0xD2, 0x41, 0x49, 0x07, 0x21, 0x1D, 0x04, 0x44, 0x48, -0x10, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x81, 0x40, 0x16, -0x04, 0x5D, 0x90, 0x44, 0x00, 0x10, 0x01, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x05, 0x8D, 0x04, 0x05, 0x32, 0x10, 0x88, -0x40, 0x20, 0x00, 0x8D, 0x8D, 0x74, 0x02, 0x11, 0x58, 0x40, 0x20, 0x43, 0x81, -0x40, 0x16, 0x02, 0xD0, 0xC8, 0x40, 0x23, 0x05, 0x8D, 0x24, 0x14, 0x32, 0x90, -0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0, 0x08, 0x40, 0x21, 0x01, -0x8D, 0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x04, 0x44, 0x42, 0x10, 0x09, 0x40, -0xA4, 0x01, 0x95, 0x40, 0x74, 0x06, 0x10, 0x09, 0x42, 0x24, 0x00, 0x91, 0x00, -0x46, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, -0x40, 0x27, 0x40, 0x91, 0x20, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x24, 0x00, 0x8D, -0x20, 0x45, 0x02, 0x00, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xA8, 0x27, 0x02, 0x9F, 0x01, 0x44, 0x02, 0x30, 0x09, 0xD0, 0x24, -0x00, 0x9F, 0x01, 0x3C, 0x02, 0x30, 0x09, 0xF0, 0x24, 0x00, 0x83, 0x01, 0x5C, -0x1A, 0xD2, 0x39, 0xC5, 0x27, 0x24, 0x9E, 0x00, 0x5E, 0x02, 0xB0, 0x09, 0xC0, -0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02, -0x4C, 0x02, 0x30, 0x09, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x16, 0x80, 0x65, 0x00, 0x9F, 0x00, 0x1C, 0x26, 0xF0, 0x08, 0xC0, 0x67, 0x00, -0x97, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x82, 0x7C, 0xC2, -0xF0, 0x49, 0xC0, 0xE7, 0x00, 0x9D, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0xE7, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, -0x42, 0xF4, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x08, 0x05, 0x00, 0x13, 0x00, 0x4C, 0x48, 0xF0, 0x01, 0xD3, 0x04, 0x00, 0x1F, -0x00, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x40, 0x13, 0x00, 0x4C, 0x08, 0xF3, -0x21, 0xC5, 0xC7, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, -0x1B, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x41, 0x13, 0x02, 0x4D, 0x00, -0xF0, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, -0x14, 0x00, 0x71, 0x07, 0xC5, 0x0D, 0x70, 0x17, 0x40, 0x14, 0x00, 0x7D, 0x04, -0x74, 0x01, 0xD0, 0x05, 0x42, 0x58, 0x00, 0x51, 0x00, 0xD4, 0x09, 0xD0, 0x27, -0x40, 0x1F, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x78, 0x05, 0x40, 0x5F, 0x00, 0x71, -0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x1E, 0x00, 0x71, 0x11, 0x84, 0x05, 0xD2, -0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, -0x00, 0x91, 0x07, 0x24, 0x2F, 0x50, 0x1C, 0x40, 0x30, 0x80, 0x4D, 0x11, 0x34, -0x03, 0xD0, 0x0D, 0x40, 0x32, 0x10, 0xC9, 0x06, 0x04, 0x07, 0xD0, 0x3C, 0x40, -0x33, 0x80, 0xDD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x37, 0x86, 0x8D, 0x00, -0x34, 0x02, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x2F, 0xD0, 0x01, -0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x00, -0x21, 0x24, 0x84, 0x03, 0x50, 0x0E, 0x41, 0x38, 0x02, 0x6D, 0x00, 0xB4, 0x03, -0xD0, 0x0B, 0x50, 0x28, 0x05, 0x69, 0x10, 0xB4, 0x09, 0xD0, 0x2E, 0x42, 0x3B, -0x04, 0xFD, 0x00, 0x84, 0x03, 0x51, 0x0E, 0x40, 0x1B, 0x00, 0x25, 0x00, 0xB4, -0x02, 0xD2, 0x4F, 0x64, 0x7A, 0x20, 0xE1, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x60, -0x17, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0x23, -0x07, 0xAD, 0x05, 0x70, 0x14, 0xC0, 0x78, 0x01, 0xEF, 0x01, 0xBC, 0x07, 0xF0, -0x9E, 0xC0, 0x68, 0x41, 0xA9, 0x09, 0x8C, 0x07, 0xF3, 0x1E, 0xC0, 0x7B, 0x10, -0xEF, 0x01, 0x94, 0x17, 0x70, 0x3E, 0x80, 0x7F, 0x00, 0xEF, 0x01, 0xBC, 0x07, -0xF0, 0x5E, 0x80, 0x7C, 0x00, 0xF1, 0x01, 0x8C, 0x07, 0xF0, 0x16, 0xC0, 0x57, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5, 0x42, 0x0F, 0x00, -0x7C, 0x01, 0x72, 0x05, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x49, -0xD0, 0x07, 0x0A, 0x17, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x06, 0x7C, 0x03, 0x70, 0x1D, 0xC0, 0x27, 0x40, 0x5B, 0x00, 0x7C, 0x03, 0xF0, -0x1C, 0xC0, 0x27, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0xFF, 0x00, 0xB3, 0x01, 0xCC, -0x23, 0xF0, 0x5F, 0xC2, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0, -0x6C, 0x00, 0xFB, 0x41, 0xC8, 0x27, 0x30, 0x17, 0xC0, 0x5F, 0x20, 0xFF, 0x13, -0xDC, 0x47, 0xB0, 0x1F, 0xC8, 0x7F, 0x00, 0xBF, 0x01, 0xDC, 0x06, 0x30, 0x1F, -0xD1, 0x7C, 0x00, 0xFF, 0x81, 0xFC, 0x87, 0xF0, 0x1B, 0xC0, 0x03, 0x08, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x3D, 0x00, 0xA1, 0x0A, 0x84, 0x09, -0x70, 0x0E, 0x48, 0x3B, 0x04, 0xAD, 0x00, 0xB4, 0x03, 0x10, 0x0F, 0x40, 0x28, -0x10, 0x61, 0x04, 0xC4, 0x23, 0x10, 0x86, 0x40, 0x3B, 0x0A, 0xED, 0x00, 0xC4, -0x03, 0xB2, 0x0E, 0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x02, 0xB0, 0x0E, 0x40, -0x38, 0x00, 0xAD, 0x88, 0xB4, 0x22, 0xD0, 0x02, 0x40, 0x57, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x39, 0x00, 0x31, 0x00, 0x84, 0x23, 0xD8, -0x46, 0x40, 0x3B, 0x00, 0xED, 0x02, 0xF4, 0x03, 0x90, 0x2E, 0x40, 0x20, 0x00, -0xA1, 0x20, 0x86, 0x22, 0x98, 0x2A, 0x40, 0x8B, 0x00, 0xED, 0x00, 0x94, 0x03, -0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x94, 0x23, 0x10, 0x0C, 0x40, 0x18, -0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x41, 0x03, 0x08, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x04, 0x01, 0x03, 0x45, 0x00, 0x50, 0x01, -0x40, 0xF3, 0x00, 0x9D, 0x40, 0x36, 0x83, 0x90, 0x0C, 0x40, 0x04, 0x00, 0x01, -0x20, 0x06, 0x02, 0x90, 0x08, 0x44, 0x23, 0x08, 0xCD, 0x00, 0x04, 0x03, 0x90, -0x0C, 0x40, 0x33, 0x02, 0x4D, 0x08, 0x04, 0x03, 0x90, 0x1C, 0x40, 0x20, 0x00, -0xCD, 0x00, 0x74, 0x02, 0xD0, 0x14, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xA0, 0xBD, 0x40, 0x73, 0x11, 0x4C, 0x0A, 0xF0, 0x09, 0xC0, -0x3F, 0x10, 0x5F, 0x03, 0x74, 0x83, 0xB4, 0x09, 0x40, 0x2C, 0x00, 0xD3, 0x00, -0x4C, 0x1A, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0F, -0x40, 0x27, 0x00, 0x5F, 0x00, 0x1C, 0x02, 0x30, 0xBF, 0xC1, 0x34, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x14, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x77, 0x00, 0x5F, 0x06, 0x7C, 0x62, 0xF0, 0x09, 0xC0, 0x37, -0x01, 0x5F, 0x01, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xD7, 0x02, 0x7D, -0x00, 0x70, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2, 0x0D, 0xC4, -0x27, 0x00, 0x5F, 0x02, 0x7C, 0x02, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDF, 0x02, -0x7C, 0x0B, 0xF1, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x3F, 0x00, 0x73, 0x08, 0xCC, 0x00, 0x30, 0x0B, 0xC2, 0x38, 0x00, -0xF3, 0x00, 0xCC, 0x03, 0x31, 0x1B, 0xC0, 0x2E, 0x00, 0xF3, 0x00, 0xCC, 0x40, -0xF0, 0x0A, 0xC4, 0x08, 0x00, 0xF3, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC0, 0x2F, -0x00, 0x7F, 0x01, 0x4C, 0x06, 0x30, 0x0E, 0xC8, 0x3C, 0x00, 0x7F, 0x00, 0xFC, -0x03, 0x30, 0x83, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x36, 0x00, 0x51, 0x00, 0x45, 0x0C, 0x11, 0x39, 0x41, 0x34, 0x00, 0xD1, -0x01, 0x2C, 0x03, 0x50, 0x09, 0x40, 0x44, 0x00, 0xC1, 0x02, 0x7C, 0x0C, 0xD0, -0x31, 0xC0, 0x46, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x0D, 0xC0, 0x65, 0x00, -0x5D, 0x02, 0x6C, 0x06, 0x14, 0x0D, 0x40, 0x34, 0x00, 0xDD, 0x04, 0x70, 0x07, -0x10, 0x09, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA8, -0x30, 0x40, 0x01, 0x00, 0x64, 0x06, 0x90, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x01, -0x44, 0x03, 0x18, 0x88, 0x40, 0x24, 0x01, 0xD1, 0x14, 0x44, 0x06, 0xD0, 0x11, -0x40, 0x44, 0x00, 0xD1, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x67, 0x04, 0x49, -0x06, 0x44, 0x22, 0x10, 0x0D, 0x40, 0x34, 0x22, 0xDD, 0x40, 0x74, 0x0F, 0x10, -0x0D, 0x40, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, -0x00, 0x01, 0x00, 0x05, 0x02, 0x90, 0x08, 0x56, 0x30, 0x40, 0xC1, 0x00, 0x45, -0x03, 0x50, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x00, 0x40, -0x60, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x21, 0x00, 0x4D, 0x00, -0x24, 0x02, 0x10, 0x0C, 0x00, 0x30, 0x08, 0x8D, 0x00, 0x34, 0x03, 0x10, 0x05, -0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x10, -0x13, 0x00, 0x4D, 0x02, 0xB0, 0x01, 0x42, 0x34, 0x00, 0x93, 0x20, 0x46, 0x03, -0x30, 0x0B, 0xC0, 0x26, 0x00, 0x53, 0x00, 0x44, 0x00, 0xF1, 0x09, 0x40, 0x04, -0x40, 0xE3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x27, 0x00, 0x5F, 0x00, 0x4C, -0x02, 0x30, 0x0D, 0x90, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0x30, 0x09, 0xD0, -0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x3F, 0x00, 0x2F, -0x00, 0xFC, 0x02, 0x70, 0x0B, 0xC4, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x03, 0xF0, -0x0B, 0xC0, 0x0F, 0x00, 0x2F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00, -0xFF, 0x20, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x2D, 0x00, 0x7F, 0x00, 0xFC, 0x02, -0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x17, -0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xFF, 0x09, -0xFC, 0x32, 0xF0, 0x4F, 0xE1, 0x2D, 0x21, 0xFF, 0x09, 0xFC, 0x00, 0xF0, 0x0F, -0xC0, 0x3C, 0x00, 0xFF, 0x1C, 0xCC, 0x52, 0xF0, 0x4F, 0xC0, 0x7C, 0x80, 0xFF, -0x00, 0xCC, 0x13, 0xB0, 0x0F, 0xC0, 0x7C, 0x00, 0xFF, 0x84, 0xBC, 0x05, 0x30, -0x1F, 0xC0, 0x7C, 0x40, 0xFB, 0x01, 0xCC, 0x04, 0xB0, 0x0B, 0xC0, 0x0C, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCD, 0x00, 0x74, -0x3A, 0xD0, 0x3F, 0x40, 0xA7, 0x03, 0xDD, 0x04, 0x74, 0x06, 0xD0, 0x2F, 0x40, -0xFC, 0x00, 0xFD, 0x06, 0x44, 0x1A, 0xD0, 0xBF, 0x46, 0x74, 0x00, 0xFD, 0x06, -0xC4, 0x3B, 0x34, 0xAF, 0x40, 0x74, 0x00, 0xFC, 0x02, 0x74, 0x05, 0x10, 0x1D, -0x40, 0x74, 0x00, 0x91, 0x01, 0x54, 0x03, 0x52, 0x01, 0x40, 0x0D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x01, 0xCD, 0x00, 0x34, 0x00, -0xD0, 0x0C, 0x40, 0x03, 0x04, 0xCD, 0x04, 0x34, 0x02, 0xD0, 0x8C, 0x40, 0x32, -0x02, 0xCD, 0x00, 0x04, 0x40, 0xD1, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x18, 0x04, -0x43, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xCD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40, -0x31, 0x00, 0x49, 0x80, 0x04, 0x01, 0x80, 0x08, 0x60, 0x4C, 0x80, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x0C, 0xD0, -0x0D, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x36, 0x00, -0xDD, 0x00, 0x45, 0x06, 0xD0, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x00, 0x44, 0x03, -0x10, 0x0D, 0x40, 0x34, 0x14, 0xDD, 0x00, 0x74, 0x21, 0x10, 0x0D, 0x60, 0x74, -0x90, 0x11, 0x00, 0x56, 0x01, 0x09, 0x31, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0C, 0xF0, 0x0D, -0xC0, 0x67, 0x04, 0xDF, 0x00, 0x7C, 0x04, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDF, -0x20, 0x4C, 0x1E, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30, -0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0x31, 0x2C, 0xC0, 0xF0, 0x04, -0xDB, 0x00, 0x4C, 0x16, 0xA0, 0x31, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0x88, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xC2, -0x2F, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xD0, 0x35, 0x00, 0xDF, 0x00, -0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFC, 0x43, 0xF0, 0x0F, -0xC4, 0x3F, 0x02, 0xFD, 0x00, 0xF8, 0x01, 0xF4, 0x2F, 0x40, 0x3F, 0x40, 0xFF, -0x00, 0xFC, 0x67, 0xF0, 0x02, 0xC2, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x08, 0x35, 0x80, 0xDF, 0x00, 0x5C, 0x08, 0x30, 0x0D, 0xC0, 0xA4, -0x08, 0xDF, 0x00, 0x4C, 0x08, 0x30, 0x5C, 0xC0, 0x34, 0x00, 0xC3, 0x40, 0x4C, -0x48, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x3C, 0x83, 0xF0, 0x0C, 0xC0, -0x34, 0x04, 0xD7, 0x91, 0x4C, 0x13, 0x74, 0x0D, 0xC5, 0x35, 0x00, 0xDF, 0x84, -0x4C, 0x05, 0xE0, 0x29, 0x81, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x04, 0x10, 0x0F, 0x40, 0xE4, 0x02, -0xDD, 0x00, 0x44, 0x00, 0xB0, 0x2F, 0x40, 0x3D, 0x00, 0xF1, 0x01, 0x44, 0x16, -0xD0, 0x0F, 0xC0, 0x34, 0x00, 0xF7, 0x04, 0xF4, 0x4B, 0xD0, 0xAF, 0x40, 0xB5, -0x00, 0xF0, 0x02, 0x04, 0x15, 0x10, 0x3D, 0x44, 0x34, 0x10, 0xC9, 0x80, 0x44, -0x85, 0x90, 0x31, 0x41, 0x6D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0x20, 0x30, 0x10, 0xCD, 0x00, 0x04, 0x4E, 0x11, 0x0C, 0x44, 0x40, 0x00, 0xCD, -0x00, 0x04, 0x00, 0x10, 0x2C, 0x40, 0x30, 0x08, 0xC1, 0x04, 0x24, 0x04, 0xD0, -0x0C, 0x50, 0x32, 0x00, 0xC1, 0x07, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0xD0, 0x00, -0xC5, 0x02, 0x00, 0x09, 0x10, 0x14, 0x40, 0x83, 0x41, 0xC1, 0x02, 0x64, 0x00, -0xD0, 0x18, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, -0x78, 0x00, 0xED, 0x01, 0x85, 0x07, 0x14, 0x1C, 0x50, 0x78, 0x04, 0xED, 0x01, -0x85, 0x06, 0x10, 0x1E, 0x40, 0x78, 0x80, 0xE1, 0x11, 0xA4, 0x05, 0xD0, 0x1C, -0x40, 0x7C, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x59, 0x06, 0xE5, -0x01, 0x84, 0x05, 0x10, 0x9E, 0x40, 0x7A, 0x07, 0xA1, 0x01, 0xA4, 0x06, 0x91, -0x1A, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x30, -0x00, 0xCD, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x10, 0x00, 0xDF, 0x00, 0x04, -0x03, 0x10, 0x0D, 0xC0, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x21, 0xF0, 0x0C, 0xC0, -0x36, 0x02, 0xC3, 0x00, 0x3C, 0x03, 0xF2, 0x0D, 0xE0, 0x20, 0x00, 0xD7, 0x00, -0x0C, 0x33, 0x30, 0x8C, 0xC1, 0x23, 0x03, 0x4B, 0x20, 0x2C, 0x20, 0xF0, 0x09, -0xC0, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x10, -0xFF, 0x48, 0xFC, 0x23, 0xF8, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03, -0xF0, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x02, 0x5D, 0x21, 0xF0, 0x0F, 0xC0, 0x3F, -0x00, 0xF7, 0x10, 0x7C, 0x43, 0xF0, 0x0D, 0xC1, 0x2A, 0x00, 0xFB, 0x02, 0x7C, -0x21, 0xF2, 0x88, 0x00, 0x28, 0x03, 0x2F, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC4, -0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x80, 0xDF, -0x00, 0x7E, 0x01, 0x30, 0x4D, 0xC1, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, -0xAD, 0xD0, 0x34, 0x01, 0xDF, 0x02, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0x37, 0x00, -0xDF, 0x04, 0x7C, 0x1B, 0xF8, 0x6D, 0xC0, 0x37, 0x00, 0xD3, 0x0E, 0x7C, 0x01, -0xF0, 0x1D, 0xC0, 0x22, 0x40, 0xCB, 0x00, 0x4C, 0x02, 0xF0, 0x11, 0x40, 0x40, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x00, -0xF4, 0x03, 0x10, 0x4E, 0x40, 0x3B, 0x00, 0xEC, 0x00, 0xB4, 0x03, 0xD0, 0x8E, -0x40, 0xB8, 0x05, 0xFD, 0x04, 0x84, 0x03, 0xD0, 0x0E, 0x41, 0x3B, 0x00, 0xED, -0x0C, 0xB4, 0x53, 0x70, 0xCE, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x00, 0xD0, -0x0E, 0x40, 0x28, 0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x06, 0x40, 0x4C, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xE5, 0x01, 0xB4, -0x87, 0x92, 0xDE, 0x42, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x5C, 0x40, -0x78, 0x00, 0xFD, 0x4D, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x7B, 0x00, 0xED, 0x05, -0xB4, 0x07, 0xD0, 0x1E, 0x44, 0x7F, 0x00, 0xE1, 0x05, 0xB4, 0x07, 0xD0, 0x1E, -0x41, 0x6E, 0x80, 0xF9, 0x01, 0x84, 0x07, 0xD0, 0x1C, 0x60, 0x10, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xDD, 0x00, 0x74, 0x43, -0x94, 0x0C, 0x40, 0xF3, 0x01, 0xCD, 0x00, 0x36, 0x3F, 0xD0, 0x0D, 0x40, 0x30, -0x10, 0xDD, 0x00, 0x04, 0x47, 0x90, 0x0C, 0x42, 0x33, 0x00, 0xDD, 0x00, 0x74, -0x03, 0x52, 0x0C, 0x40, 0xB3, 0x02, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x4C, 0x46, -0x60, 0xA2, 0xC9, 0x09, 0x44, 0x03, 0xC0, 0x1C, 0x40, 0x58, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x08, 0x5F, 0x00, 0xF4, 0x15, 0xB0, -0x05, 0xC0, 0x9F, 0x01, 0x5F, 0x00, 0xFC, 0x01, 0xF2, 0x05, 0xC0, 0x14, 0x08, -0x5F, 0x00, 0xDC, 0x19, 0xF3, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, -0xF0, 0x05, 0xC0, 0x5F, 0x20, 0x53, 0x00, 0xFC, 0x15, 0xF0, 0x07, 0xCC, 0x9A, -0x20, 0x6B, 0x02, 0xCD, 0x09, 0xF0, 0x37, 0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x0A, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, -0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, -0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, -0x21, 0xC0, 0x87, 0x01, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x01, 0xC0, 0x07, 0x04, -0x1F, 0x10, 0x7C, 0x48, 0xB0, 0xE1, 0xC8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x30, 0x09, 0xC0, -0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x80, 0x9F, 0x08, -0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x0E, 0x30, 0x08, -0xC0, 0x24, 0x00, 0x97, 0x00, 0x7C, 0x86, 0x72, 0x29, 0xCA, 0xA7, 0x08, 0x97, -0x05, 0x5C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x20, 0x24, 0x08, 0x9D, 0x20, 0x44, 0x36, 0x04, 0x09, 0x44, 0xE7, -0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x25, 0x90, 0x9C, 0x01, 0x44, -0x0A, 0x14, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x45, 0x0A, 0xA4, 0x09, 0x51, -0xA0, 0x00, 0x90, 0x12, 0x34, 0x26, 0x10, 0x29, 0x40, 0x27, 0x00, 0x99, 0x00, -0x6C, 0x8A, 0x50, 0x19, 0x41, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x00, 0x09, 0x40, 0x27, 0x00, -0x9D, 0x00, 0x40, 0x02, 0xD0, 0x09, 0x00, 0x24, 0x20, 0x9C, 0x10, 0x44, 0x22, -0x10, 0x09, 0x44, 0x25, 0x00, 0x9D, 0x14, 0x44, 0x42, 0x90, 0x19, 0x40, 0x24, -0x04, 0x95, 0x00, 0x54, 0x02, 0x40, 0x0D, 0x41, 0x26, 0x00, 0x9D, 0x42, 0x54, -0x12, 0x10, 0x49, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x20, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x12, 0x11, 0x48, 0x40, 0x33, 0x01, 0x8D, -0x00, 0x34, 0x12, 0xD0, 0x4D, 0x4C, 0x21, 0x11, 0x8D, 0x04, 0x04, 0x13, 0x10, -0x48, 0x60, 0x23, 0x00, 0x8D, 0x04, 0x04, 0x12, 0x90, 0x48, 0x44, 0x24, 0x00, -0x81, 0x84, 0x76, 0x02, 0x1A, 0x08, 0x40, 0x23, 0x88, 0x89, 0x80, 0x24, 0x02, -0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x38, -0x86, 0x0A, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F, 0x0A, -0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x04, 0x00, 0x1D, 0x0A, 0x4D, 0x28, 0x32, 0x01, -0xC4, 0x07, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0x40, 0x04, 0x08, 0x17, -0x4A, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x5C, 0x29, 0x30, -0xA1, 0xC0, 0x77, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB2, 0x25, -0x00, 0x9F, 0x40, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F, 0x00, 0xFC, -0x22, 0xF0, 0x89, 0xC0, 0x27, 0x02, 0x9F, 0x48, 0xFC, 0x22, 0xF0, 0x89, 0xC2, -0x27, 0x00, 0x9F, 0x08, 0x7C, 0x22, 0x70, 0x89, 0xC0, 0x3B, 0x00, 0x9F, 0x08, -0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xB7, 0x80, 0xDC, 0x02, 0xF1, 0x8F, -0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x80, 0x27, 0x00, -0x9F, 0x08, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x2C, 0x02, 0x93, 0x00, 0x7C, 0x52, -0xF0, 0xCB, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x49, 0xC0, 0x27, -0x00, 0xBF, 0x0C, 0xFC, 0x02, 0xE0, 0x0B, 0xC0, 0x2D, 0x00, 0xB3, 0x04, 0xDC, -0x02, 0xB0, 0x0B, 0xC0, 0x2A, 0x40, 0xB3, 0x00, 0xBC, 0x03, 0x30, 0x0B, 0xC0, -0x77, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D, -0x04, 0x74, 0x49, 0x10, 0x01, 0x44, 0x14, 0x42, 0x01, 0x14, 0x74, 0x00, 0xD0, -0xC1, 0x4C, 0x87, 0x10, 0x1D, 0x50, 0x74, 0x20, 0x10, 0x01, 0x40, 0x07, 0x00, -0x1D, 0x0C, 0x74, 0x48, 0xD0, 0x01, 0x45, 0x07, 0x00, 0x11, 0x14, 0x74, 0x00, -0xD0, 0x05, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x63, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x04, -0x34, 0xB2, 0x14, 0x88, 0x40, 0x20, 0x00, 0x81, 0x04, 0x36, 0x02, 0xD0, 0x48, -0x48, 0x23, 0x82, 0x8D, 0x08, 0x34, 0x02, 0x14, 0x88, 0x60, 0x23, 0x00, 0x8D, -0x04, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x0C, 0x36, 0x02, 0x52, -0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x14, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x80, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x74, -0x12, 0x10, 0x09, 0x50, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x10, 0x09, 0x40, 0x27, 0x00, 0xDD, 0x00, -0x74, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, -0x40, 0x27, 0x04, 0x91, 0x02, 0x70, 0x12, 0x19, 0x09, 0x40, 0x63, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x00, 0x9F, 0x00, 0x78, 0x06, -0x30, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x7C, 0x4E, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF2, 0x09, 0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x42, 0xB0, 0xB9, 0xC0, -0x27, 0x00, 0x93, 0x00, 0x7C, 0x46, 0x34, 0x19, 0xC0, 0x17, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x06, 0xF0, -0x08, 0xC0, 0x67, 0x00, 0x9C, 0x00, 0x7C, 0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF0, 0x09, 0xC1, 0x27, 0x02, 0x9F, 0xB0, 0x7C, 0x42, 0xF0, 0x19, 0x02, 0x24, -0x01, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x99, 0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, -0xC0, 0xC7, 0x00, 0x1F, 0x00, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, -0x01, 0x7C, 0x30, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x5C, 0x04, 0xF0, -0x01, 0xC8, 0x86, 0x09, 0x13, 0x08, 0x6D, 0x08, 0xE0, 0x41, 0xC0, 0x84, 0x00, -0x17, 0x40, 0x6C, 0x10, 0x10, 0xA1, 0xC2, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x14, 0x00, 0x5D, 0x80, 0xF4, 0x1D, 0x70, 0x05, 0x40, -0x5F, 0x20, 0x5D, 0x00, 0x4C, 0x01, 0x10, 0x27, 0x40, 0x14, 0x00, 0x7D, 0x00, -0xF4, 0x0D, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01, 0xC4, 0x05, 0x70, 0x27, -0x40, 0x18, 0x00, 0x71, 0x82, 0xC4, 0x19, 0xD0, 0x16, 0x41, 0x18, 0x01, 0x71, -0x1B, 0xE4, 0x45, 0x10, 0x07, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x1F, 0x58, 0x0C, 0x40, 0x77, -0x00, 0xC9, 0x00, 0x25, 0x03, 0x14, 0x2C, 0x50, 0x30, 0x00, 0xCD, 0x01, 0x74, -0x07, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C, 0x50, -0xB0, 0x42, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x2C, 0x40, 0x50, 0x40, 0xC5, 0x02, -0x64, 0x07, 0x94, 0x1C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x80, 0x38, 0x02, 0xED, 0x08, 0xB4, 0x03, 0x58, 0x0E, 0x40, 0x3B, 0x0C, -0xED, 0x05, 0x04, 0x07, 0x10, 0x1E, 0x41, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03, -0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x03, 0x84, 0x09, 0x50, 0x36, 0x40, 0x3C, -0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0xE6, -0x82, 0x90, 0x16, 0x40, 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x18, 0x78, 0x00, 0xEF, 0x11, 0xBC, 0x05, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, -0x87, 0xAC, 0x87, 0x30, 0x1F, 0xC0, 0x78, 0x00, 0xED, 0x21, 0xBC, 0x07, 0xF0, -0x1E, 0xC0, 0x7B, 0x00, 0xCF, 0x81, 0x9C, 0x07, 0x78, 0x1F, 0xC0, 0x78, 0x00, -0xC3, 0x81, 0x8C, 0x07, 0xDA, 0x0A, 0xC4, 0x58, 0x20, 0xE7, 0x21, 0xAE, 0x07, -0xB1, 0x1B, 0xC4, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, -0x35, 0x01, 0xDF, 0x06, 0x7E, 0x01, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x16, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x31, 0x00, 0x5F, -0x00, 0x5C, 0x03, 0xF8, 0x0C, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x70, 0x02, 0x70, -0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0xFD, -0x02, 0xF3, 0x01, 0xFC, 0x23, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x81, 0xFC, -0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, -0x7F, 0x00, 0xF7, 0x01, 0xCC, 0x27, 0x38, 0x1F, 0xC0, 0x7F, 0x00, 0x73, 0x01, -0x8C, 0x87, 0xB8, 0x97, 0xC0, 0x5C, 0x00, 0xEF, 0x21, 0xCC, 0x05, 0xF0, 0x17, -0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, -0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x02, 0xE1, 0x00, 0xB4, 0x03, -0xD0, 0x82, 0x40, 0x3B, 0x00, 0x7D, 0x08, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B, -0x00, 0x7D, 0x04, 0x84, 0x01, 0x14, 0x4E, 0x40, 0x3B, 0x01, 0x3B, 0x00, 0x85, -0x43, 0x10, 0xCE, 0x40, 0x18, 0x01, 0xED, 0x08, 0x94, 0x62, 0xD0, 0x62, 0x40, -0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x08, 0xE1, -0x00, 0xB4, 0x23, 0xD8, 0x0E, 0x40, 0x9B, 0x04, 0xE1, 0x00, 0xB4, 0x23, 0xD0, -0x0E, 0x40, 0x3B, 0x88, 0x6D, 0x00, 0x84, 0x09, 0x10, 0x0E, 0x40, 0x3B, 0x00, -0xE5, 0x80, 0x94, 0x03, 0x18, 0x0A, 0x4C, 0x3B, 0x10, 0xE1, 0x00, 0xB4, 0x03, -0x90, 0x0F, 0x44, 0x89, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x0A, 0x61, 0x60, -0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x40, -0x34, 0x1A, 0xD0, 0x0C, 0x40, 0x67, 0xC0, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00, -0x40, 0x33, 0x80, 0x0D, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x10, 0x8D, -0x40, 0x44, 0x00, 0x18, 0x08, 0x40, 0x33, 0x20, 0x01, 0x00, 0x24, 0x03, 0x10, -0x2C, 0x40, 0x50, 0x10, 0xCD, 0x01, 0x14, 0x0A, 0xD8, 0x20, 0x42, 0x08, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x3D, 0x00, 0xF3, 0x00, 0x7C, -0x16, 0xD0, 0x0D, 0xC4, 0x47, 0x00, 0xF3, 0x00, 0x7C, 0x0B, 0xD0, 0x01, 0xC0, -0x37, 0x00, 0x9F, 0x00, 0x4C, 0x04, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00, -0x5C, 0x02, 0x30, 0x09, 0x00, 0x37, 0x00, 0x91, 0x00, 0x6C, 0x8B, 0xB0, 0x2C, -0xC1, 0x50, 0x01, 0xDF, 0x00, 0x40, 0x08, 0xD0, 0x89, 0xC0, 0x74, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, -0xF0, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x01, 0xC0, 0x33, -0x00, 0x1F, 0x02, 0x7C, 0x20, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x9F, 0x02, 0x7C, -0x0A, 0xF0, 0x09, 0xE0, 0xA7, 0x08, 0x9F, 0x42, 0x5C, 0x43, 0xF2, 0x0D, 0xD0, -0xB7, 0x08, 0xDF, 0x2A, 0x7C, 0x08, 0xF0, 0x29, 0xD0, 0x17, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0xF0, -0x0F, 0xC0, 0x27, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40, -0xB3, 0x00, 0x9C, 0x02, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0x7C, 0x02, -0xB0, 0x03, 0xC0, 0x3F, 0x20, 0xAF, 0x20, 0xDC, 0x03, 0x30, 0x0F, 0xC1, 0x1D, -0x00, 0xB6, 0x00, 0xCC, 0x42, 0x80, 0x09, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x40, 0xD1, 0x00, 0x74, 0x04, 0xD0, 0x0D, -0x60, 0x67, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91, -0x03, 0x5C, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01, 0x74, 0x46, 0x10, -0x11, 0x41, 0x67, 0x01, 0x19, 0x01, 0x04, 0x06, 0xB0, 0x3D, 0x40, 0x74, 0x01, -0x01, 0x45, 0x44, 0x4E, 0x90, 0x19, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x76, 0x04, 0xD0, 0x0D, 0x4A, -0x47, 0x04, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91, 0x11, -0x74, 0x04, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x01, 0x74, 0x04, 0x10, 0x19, -0x40, 0x77, 0x00, 0x9D, 0x03, 0x40, 0x47, 0x10, 0x8D, 0x01, 0x55, 0x00, 0xD5, -0x81, 0x44, 0x84, 0x90, 0x11, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x00, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x06, 0xD0, 0x0C, 0x40, 0x03, -0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x01, 0x00, 0x14, -0x00, 0x10, 0x0C, 0x40, 0x33, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x90, 0x08, 0x64, -0x33, 0x00, 0x89, 0x00, 0x47, 0x01, 0x90, 0x0C, 0x40, 0x30, 0x08, 0xD5, 0x00, -0x04, 0x00, 0x90, 0x00, 0x44, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x38, 0x3A, 0x00, 0xF3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x40, 0x07, 0x00, -0xF3, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x00, -0x30, 0x0D, 0xC0, 0x37, 0x00, 0x1D, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC0, 0x37, -0x00, 0x9F, 0x00, 0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x15, 0x08, 0xD7, 0x00, 0x4D, -0x80, 0xB0, 0x09, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC4, 0x2F, 0x00, 0xFF, -0x00, 0xFC, 0x03, 0xF2, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDC, 0x02, 0xF0, -0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x1B, 0x80, -0x3F, 0x00, 0xFC, 0x01, 0xD0, 0x0E, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFE, 0x02, -0xF0, 0x0B, 0xC0, 0x17, 0x42, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, -0x6F, 0x00, 0xF3, 0x01, 0xFC, 0x40, 0xF0, 0x02, 0xC0, 0x2C, 0x00, 0xB3, 0x40, -0xEC, 0x02, 0x70, 0x1F, 0xC0, 0x2F, 0x00, 0xFB, 0x10, 0xFC, 0x02, 0x30, 0x03, -0xC0, 0x68, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xB0, 0x0F, 0xC0, 0x3E, 0x09, 0xFF, -0x01, 0xAC, 0x07, 0xF0, 0x4F, 0xC0, 0x7B, 0x00, 0xB3, 0x00, 0xCD, 0x03, 0x34, -0x0F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x21, -0x00, 0xD1, 0x10, 0x5C, 0x00, 0xD0, 0x11, 0x40, 0x6C, 0x08, 0x91, 0x0B, 0x58, -0x00, 0x10, 0x1D, 0xC0, 0xA5, 0x06, 0xC1, 0x12, 0x74, 0x02, 0x10, 0x11, 0xC8, -0x65, 0x00, 0xCD, 0x00, 0x54, 0x07, 0x10, 0x0D, 0x40, 0x74, 0x12, 0xDD, 0x01, -0x54, 0x07, 0xD2, 0xBD, 0x40, 0x77, 0x40, 0x91, 0x10, 0x44, 0x0B, 0x10, 0x1D, -0x00, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00, -0xC1, 0x00, 0x34, 0x04, 0xD0, 0x10, 0x40, 0x20, 0x00, 0xD1, 0x00, 0x04, 0x00, -0x50, 0x0C, 0x40, 0x23, 0x09, 0xC1, 0x84, 0x34, 0x02, 0x12, 0x00, 0x40, 0x20, -0x00, 0xC1, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, -0x03, 0x90, 0x0C, 0x40, 0x35, 0x80, 0x95, 0x84, 0x04, 0x70, 0x14, 0x0C, 0x40, -0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, -0x00, 0x74, 0x04, 0xD0, 0x41, 0x40, 0x64, 0x40, 0xD1, 0x08, 0x74, 0x44, 0x10, -0x0D, 0x40, 0x27, 0x40, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x01, 0x40, 0x26, 0x00, -0xDD, 0x00, 0x54, 0x83, 0x10, 0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x54, 0x13, -0xD0, 0x0D, 0x40, 0x27, 0x40, 0xD5, 0x18, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x0F, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x88, 0x36, 0x00, 0xD3, 0x00, -0x7C, 0x04, 0xF2, 0x14, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x4C, 0x0E, 0x70, 0x0D, -0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x1E, 0x30, 0x15, 0xD0, 0x24, 0x00, 0xDF, -0x00, 0x0C, 0x03, 0xB1, 0x0D, 0xC0, 0x36, 0x00, 0xCF, 0x81, 0x4C, 0x03, 0xF0, -0x0D, 0xC0, 0x33, 0x00, 0x87, 0x03, 0x4C, 0x27, 0x30, 0x0D, 0xC0, 0x03, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xDC, -0x40, 0xF0, 0x07, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0x9C, 0x02, 0xD0, 0x0F, 0xC0, -0x21, 0x00, 0xFF, 0x00, 0xBC, 0x02, 0xF0, 0x96, 0xC0, 0x6D, 0x01, 0xEF, 0x00, -0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xDC, 0x07, 0xF0, 0x0F, -0xC0, 0x3F, 0x00, 0xFB, 0x01, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD3, 0x00, 0x74, 0x00, -0x30, 0x85, 0xC0, 0x25, 0x00, 0xD3, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0, 0x37, -0x00, 0xDF, 0x00, 0x4C, 0x3A, 0xD0, 0x05, 0x40, 0x24, 0x20, 0xD3, 0x08, 0x4D, -0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0, -0x37, 0x00, 0x93, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x28, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xD5, 0x05, 0x74, 0x14, 0x10, -0x07, 0xC0, 0xB2, 0x00, 0xD1, 0x00, 0x74, 0x28, 0xD0, 0x0D, 0x40, 0x37, 0x00, -0xF1, 0x00, 0x7C, 0x06, 0xD1, 0x0D, 0x43, 0x25, 0x00, 0xF5, 0x00, 0x54, 0x2F, -0xD0, 0x0F, 0x40, 0x7C, 0x00, 0x51, 0x11, 0x7C, 0x02, 0x10, 0x1F, 0x40, 0x37, -0x00, 0xD1, 0x04, 0x2C, 0x2F, 0xD0, 0x0F, 0x50, 0x4C, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0xA0, 0x26, 0x00, 0xC1, 0x01, 0x34, 0x0C, 0x18, 0x10, -0x40, 0x20, 0x04, 0x81, 0x00, 0x34, 0x06, 0xD8, 0x0C, 0x40, 0x23, 0x00, 0xC9, -0x40, 0x14, 0x0C, 0xD0, 0x04, 0x70, 0x20, 0x40, 0xC1, 0x00, 0x04, 0x03, 0xD8, -0x0C, 0x40, 0x71, 0x00, 0xC1, 0x00, 0x34, 0x02, 0x18, 0x1C, 0x40, 0x33, 0x00, -0x88, 0x80, 0x14, 0x07, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0F, 0x80, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x24, 0x18, 0x3B, 0x40, -0x62, 0x00, 0xA0, 0x01, 0xB4, 0x45, 0xD8, 0x1E, 0x42, 0x6B, 0x60, 0xE1, 0x03, -0xA4, 0x26, 0xD0, 0x14, 0x40, 0x6D, 0x00, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x1E, -0x40, 0x79, 0x00, 0xE1, 0x01, 0xF4, 0x06, 0x10, 0x1E, 0x40, 0x7F, 0x40, 0x49, -0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x10, 0x30, 0x08, 0xC3, 0x08, 0x7C, 0x20, 0x30, 0x00, 0x40, 0xA1, -0x40, 0xC3, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x1C, -0x03, 0xF0, 0x84, 0x42, 0x20, 0x02, 0xC3, 0x00, 0x0C, 0x43, 0xF0, 0x0D, 0x48, -0x31, 0x44, 0xC3, 0x88, 0x3E, 0x02, 0x71, 0x0C, 0xC1, 0x33, 0x00, 0x0B, 0x00, -0x1C, 0x01, 0xF0, 0x8C, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x20, 0xC4, 0x8B, 0xC0, 0x1F, 0x02, -0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x10, 0xFC, 0x03, -0xA0, 0x87, 0xC0, 0x2E, 0x10, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3A, -0x02, 0x7F, 0x08, 0xDC, 0x22, 0xF4, 0x8F, 0xC0, 0x2F, 0x42, 0xF7, 0x00, 0xCE, -0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7E, 0x04, 0x30, 0x01, 0xC0, 0x2C, 0x01, 0x93, -0x00, 0xEC, 0x07, 0x30, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x1C, 0x02, 0x30, -0x05, 0xC0, 0x26, 0x00, 0xFF, 0x00, 0x4C, 0x03, 0xF0, 0x8D, 0xE0, 0x37, 0x00, -0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x13, 0x81, 0x4C, 0x07, -0x34, 0x0F, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88, -0x39, 0x00, 0xED, 0x00, 0xB6, 0x00, 0x12, 0x62, 0xC0, 0x38, 0x04, 0xE1, 0x00, -0xF4, 0x03, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xFB, 0x01, 0x84, 0x02, 0x10, 0x06, -0x40, 0x3B, 0x00, 0xFD, 0x01, 0x85, 0x03, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xE1, -0x40, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xAD, 0x03, 0x10, -0x1E, 0x40, 0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79, -0x00, 0xED, 0x01, 0xB4, 0x86, 0x12, 0x13, 0x40, 0x60, 0x00, 0xED, 0x21, 0xB4, -0x0F, 0xD0, 0x1E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xD4, 0x07, 0xD9, 0x16, 0x41, -0x6B, 0x00, 0xED, 0x21, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x72, 0x20, 0xE1, 0x03, -0xB4, 0x06, 0xD0, 0x1C, 0x40, 0x7E, 0x00, 0x25, 0x03, 0x84, 0x07, 0x10, 0x1E, -0x40, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x73, 0x02, -0xCD, 0x00, 0x34, 0x03, 0x10, 0x48, 0x06, 0x52, 0x00, 0xC9, 0x00, 0x34, 0xCF, -0x90, 0x0C, 0x40, 0x73, 0x00, 0xC9, 0x00, 0x04, 0x13, 0x90, 0x7C, 0x40, 0x23, -0x00, 0xDD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x49, 0x01, 0x34, -0x02, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x04, 0x24, 0x4B, 0x10, 0x0C, 0x40, -0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F, -0x00, 0xFC, 0x49, 0x34, 0x47, 0xD0, 0x5C, 0x41, 0x5F, 0x11, 0xFC, 0x01, 0xF4, -0x05, 0xC0, 0x57, 0x00, 0x57, 0x00, 0xDC, 0x01, 0xE0, 0x27, 0xE0, 0x17, 0x00, -0x5F, 0x00, 0x6E, 0x81, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x63, 0x01, 0x3C, 0x15, -0xF2, 0x05, 0xF0, 0x54, 0x01, 0x77, 0x03, 0xC4, 0x1D, 0x30, 0x05, 0xC0, 0x5F, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02, -0x7C, 0xC0, 0xF0, 0x01, 0xC0, 0x85, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x72, 0x01, -0xC0, 0x07, 0x02, 0x1F, 0x02, 0x7C, 0x00, 0x74, 0x01, 0xC0, 0x07, 0x02, 0x1F, -0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0, -0x21, 0xE0, 0x07, 0x40, 0x1A, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8, 0x4B, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x02, 0x7C, -0x02, 0xF0, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x03, 0x6C, 0x06, 0xF0, 0x09, 0xC0, -0x23, 0x40, 0x91, 0x00, 0x04, 0x26, 0x34, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x00, -0x68, 0x06, 0xD0, 0x09, 0xE0, 0xE7, 0x08, 0x93, 0x45, 0x4C, 0x06, 0x32, 0x09, -0xC0, 0x27, 0x08, 0x93, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x40, 0x91, 0x01, 0x74, 0x82, -0xD0, 0x09, 0x40, 0xA4, 0x04, 0x91, 0x01, 0x44, 0x36, 0xD0, 0x09, 0x40, 0x27, -0x00, 0x95, 0x12, 0x6C, 0x0A, 0x10, 0x19, 0x42, 0x27, 0x00, 0x9D, 0x20, 0x44, -0x06, 0xF0, 0x09, 0x40, 0x63, 0x01, 0x9B, 0x01, 0x44, 0x06, 0xB0, 0x29, 0x44, -0x23, 0x40, 0x93, 0x0E, 0x5C, 0x1E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x91, 0x00, 0x54, 0x06, 0xD2, -0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, -0x8D, 0x01, 0x74, 0x02, 0x50, 0x89, 0x64, 0x27, 0x00, 0x9D, 0x00, 0x75, 0x12, -0xD2, 0x09, 0x00, 0x27, 0x80, 0x91, 0x00, 0x45, 0x12, 0x50, 0x89, 0x41, 0x27, -0x00, 0x99, 0x00, 0x74, 0x02, 0xD2, 0x09, 0x44, 0x63, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x22, 0x24, 0x00, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x48, -0x50, 0x20, 0x01, 0x81, 0x84, 0x04, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x01, 0x89, -0x04, 0x34, 0x13, 0x00, 0x48, 0x60, 0x23, 0x20, 0x8D, 0x04, 0x14, 0x02, 0x50, -0xC8, 0x40, 0x23, 0x01, 0x89, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x00, -0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x53, 0x0A, 0x1C, 0x28, 0xF0, 0x05, 0x50, -0x04, 0x40, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC4, 0x87, 0x02, 0x1D, 0x0A, -0x7C, 0x28, 0x50, 0x01, 0xC0, 0x07, 0x00, 0x1D, 0x0A, 0x7C, 0x80, 0xC2, 0x61, -0x40, 0x07, 0x05, 0x13, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1B, -0x8A, 0x38, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF2, 0x8A, 0xD0, 0x2F, -0x02, 0xBF, 0x08, 0xFC, 0x62, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x97, 0x08, 0xEC, -0x22, 0xF2, 0x8B, 0xC0, 0x2F, 0x00, 0x9B, 0x08, 0x6C, 0x02, 0xF0, 0x29, 0xCA, -0x27, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x89, 0xC2, 0x2B, 0x00, 0xA7, 0x08, -0xDC, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x2C, 0x00, -0xBF, 0x04, 0xFC, 0x52, 0xB0, 0x0B, 0xC0, 0x27, 0x40, 0xBB, 0x00, 0xC8, 0x22, -0x34, 0x4B, 0xC0, 0x24, 0x00, 0xBF, 0x0C, 0xDD, 0x02, 0xB0, 0x19, 0xC0, 0x6F, -0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x5B, 0xC0, 0x20, 0x00, 0xB3, 0x00, 0xCC, -0x22, 0x30, 0x4B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, -0x08, 0x07, 0x01, 0x1D, 0x04, 0x36, 0xC9, 0x10, 0x05, 0xE2, 0x04, 0x02, 0x1D, -0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x13, 0x00, 0x54, 0x20, 0x18, -0x01, 0xE0, 0x06, 0x80, 0x0D, 0x0C, 0x44, 0x00, 0x50, 0x11, 0x40, 0x07, 0x02, -0x11, 0x00, 0x74, 0x00, 0xD0, 0xA1, 0x40, 0x04, 0x00, 0x11, 0x10, 0x44, 0x20, -0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, -0x23, 0x05, 0x8D, 0x04, 0x34, 0xB2, 0x10, 0x88, 0x40, 0x20, 0x00, 0x8D, 0x08, -0x34, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x00, 0x85, 0x00, 0x04, 0x02, 0x54, 0x88, -0x42, 0x22, 0x00, 0x8D, 0x04, 0x14, 0x02, 0x10, 0x68, 0x41, 0x23, 0x00, 0x81, -0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x26, 0x10, 0x85, 0x48, 0x04, 0x07, 0x14, -0x88, 0x40, 0x4B, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, -0x00, 0x9D, 0x00, 0x74, 0x06, 0x14, 0x09, 0x40, 0x26, 0x04, 0x9D, 0x01, 0x74, -0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x89, 0x00, 0x54, 0x52, 0x10, 0x09, 0x40, -0x26, 0x01, 0x9D, 0x00, 0x44, 0x02, 0x52, 0x09, 0x40, 0x27, 0x40, 0x91, 0x08, -0x74, 0x12, 0xD0, 0x0D, 0x40, 0x66, 0x40, 0x95, 0x04, 0x04, 0x06, 0x10, 0x09, -0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, -0x9F, 0x00, 0x74, 0x0E, 0x30, 0x29, 0x50, 0xE4, 0x00, 0x9F, 0x01, 0x7C, 0x46, -0xF0, 0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x50, 0x09, 0x41, 0x26, -0x80, 0x9D, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x03, 0x7C, -0x06, 0xF2, 0x09, 0xD0, 0x22, 0x00, 0x97, 0x07, 0x4D, 0x02, 0x30, 0x09, 0xC0, -0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x65, 0x02, 0x9F, -0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x05, 0x9F, 0x00, 0x7C, 0x4E, 0xF0, -0x09, 0xC0, 0x67, 0x02, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0x80, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x06, -0xF0, 0x08, 0xC0, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x5B, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, -0x7C, 0x18, 0x94, 0x31, 0x50, 0x06, 0x40, 0x13, 0x00, 0x7C, 0x20, 0x70, 0x01, -0xC0, 0x07, 0x00, 0x1D, 0x48, 0x78, 0x48, 0x32, 0x21, 0xC0, 0x07, 0x00, 0x1F, -0x00, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0xF0, -0x41, 0xC0, 0x07, 0x00, 0x03, 0x02, 0x4C, 0x04, 0x30, 0x01, 0xC0, 0x50, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x7D, 0x04, 0xF4, -0x01, 0x30, 0x46, 0x40, 0x5C, 0x00, 0x51, 0x11, 0xF4, 0x09, 0x70, 0x55, 0x40, -0x17, 0x00, 0x7D, 0x00, 0xF4, 0x09, 0x10, 0x14, 0x40, 0x17, 0x00, 0x5D, 0x00, -0x84, 0x41, 0x70, 0x05, 0x40, 0x1F, 0x01, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27, -0x40, 0x17, 0x00, 0x72, 0x00, 0xC4, 0x01, 0x14, 0x05, 0xC1, 0x52, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x03, 0x74, 0x03, -0x10, 0x1C, 0x60, 0xB0, 0x00, 0xC1, 0x00, 0x34, 0x0B, 0x58, 0x0C, 0x40, 0x37, -0x00, 0x8D, 0x01, 0x74, 0x09, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x01, 0x14, -0x8F, 0xD0, 0x0C, 0x40, 0xF3, 0x01, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40, -0x33, 0x80, 0x49, 0x0D, 0x04, 0x02, 0x12, 0x18, 0x00, 0x50, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x01, 0xA9, 0x00, 0xB4, 0x18, 0x10, -0x02, 0x40, 0x70, 0x04, 0xE1, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x3A, 0x01, -0x29, 0x00, 0xA4, 0x00, 0x14, 0x0A, 0x41, 0x3B, 0x00, 0xED, 0x02, 0x84, 0x03, -0x40, 0x4E, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x03, 0xD0, 0x06, 0x41, 0x3F, -0x00, 0x61, 0x00, 0x84, 0x02, 0x10, 0x18, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x01, 0xAD, 0x01, 0xBC, 0x0E, 0x30, 0x14, -0xD0, 0x78, 0x00, 0xE3, 0x41, 0xBE, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x01, 0x6D, -0x01, 0x3C, 0x05, 0x30, 0x1A, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0x9D, 0x07, 0xD0, -0x5E, 0xC2, 0x7B, 0x00, 0xAB, 0x01, 0xB4, 0x06, 0xF0, 0x16, 0xC0, 0x7B, 0x00, -0xF9, 0x01, 0x8D, 0x07, 0x30, 0x1A, 0xC4, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xB8, 0xB5, 0x00, 0xBF, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0, -0x17, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0xC0, 0x0D, 0xC0, 0x77, 0x00, 0x5F, 0x00, -0xFC, 0x00, 0xF0, 0x09, 0x80, 0x37, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x8D, -0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x37, 0x40, 0xDF, -0x00, 0x3C, 0x00, 0xF4, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xA0, 0xFF, 0x04, 0xB3, 0x01, 0xFC, 0x23, 0x38, 0x03, 0xC0, 0x6C, -0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0x40, 0x7F, 0x06, 0xF3, 0x01, 0xCC, -0x85, 0x30, 0x1B, 0xE0, 0x7F, 0x02, 0xAF, 0x03, 0xCC, 0x06, 0xF0, 0x1F, 0xC0, -0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x16, 0xC0, 0x7C, 0x40, 0xFB, 0x81, -0xFC, 0x06, 0x31, 0x1A, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x88, 0x3D, 0x00, 0xA1, 0x00, 0xB4, 0x13, 0x18, 0x42, 0x00, 0x28, 0x40, -0xE1, 0x50, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3F, 0x00, 0x6F, 0x00, 0x94, 0x02, -0x10, 0x0A, 0xC0, 0x3B, 0x00, 0xED, 0x24, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x1B, -0x00, 0xAD, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0xC0, 0x38, 0x00, 0xE1, 0x00, 0xB4, -0x02, 0x10, 0x0A, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, -0x00, 0x39, 0x00, 0x21, 0x00, 0xB4, 0x22, 0x18, 0x83, 0x40, 0x20, 0x00, 0xE9, -0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x40, 0x61, 0x00, 0x04, 0x01, 0x90, -0x0A, 0x40, 0x3B, 0x20, 0xAD, 0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x2B, 0x00, -0xAD, 0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x3D, 0x00, 0xE1, 0x00, 0x34, 0x0B, -0x10, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, -0x33, 0x00, 0x11, 0x00, 0x34, 0x02, 0x12, 0x20, 0x40, 0x00, 0x00, 0xC9, 0x00, -0x34, 0x26, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00, 0x14, 0x00, 0x90, 0x28, -0x40, 0x71, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x02, 0x24, 0x02, 0xD0, 0x04, 0x40, 0x30, 0x10, 0x81, 0x02, 0x34, 0x03, 0x11, -0x08, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x3D, -0x40, 0x93, 0x00, 0xFC, 0x03, 0x14, 0x21, 0xC0, 0xE4, 0x02, 0xDB, 0x01, 0x74, -0x2A, 0xF0, 0x0C, 0xC0, 0x3F, 0x00, 0x93, 0x00, 0x4C, 0x01, 0xB4, 0x09, 0x40, -0x37, 0x00, 0x9F, 0x00, 0x6D, 0x01, 0xF0, 0x0F, 0xC0, 0x37, 0x00, 0x8F, 0x13, -0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x53, 0x0B, 0x7C, 0x82, 0x30, 0x0D, -0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, -0x9F, 0x00, 0x7C, 0x20, 0xF0, 0x00, 0xD0, 0xE7, 0x10, 0xD7, 0x00, 0x7C, 0x80, -0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00, 0x3C, 0x40, 0x70, 0x09, 0xC0, 0x37, -0x02, 0x9F, 0x00, 0x5C, 0x83, 0xF2, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, -0x02, 0xF0, 0x05, 0xC0, 0x75, 0x00, 0x47, 0x81, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, -0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00, 0xBF, -0x00, 0x8C, 0x23, 0xB0, 0x03, 0xD1, 0x28, 0x00, 0xB3, 0x05, 0xFC, 0x00, 0xF0, -0x0F, 0xC0, 0x38, 0x00, 0x6B, 0x00, 0xCC, 0x00, 0xB0, 0x8B, 0xE1, 0x3F, 0x00, -0xBF, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x4F, 0x00, 0xBF, 0x14, 0xDC, 0x0F, -0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x22, 0x10, 0x9F, 0xC0, 0x07, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x36, 0x00, 0x9D, 0x01, -0x44, 0x04, 0x90, 0x11, 0x58, 0x44, 0x04, 0x91, 0x00, 0x76, 0x04, 0xD0, 0x0D, -0xE0, 0x36, 0x00, 0x51, 0x00, 0x44, 0x04, 0x10, 0x09, 0xC0, 0x36, 0x00, 0x9D, -0x00, 0x6C, 0x47, 0xD0, 0x0D, 0x40, 0x97, 0x02, 0xDD, 0x01, 0x6C, 0x07, 0xD0, -0x3D, 0xC0, 0x32, 0x00, 0xD1, 0x01, 0x44, 0x04, 0x10, 0x1D, 0xC2, 0x25, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0x9D, 0x01, 0x44, -0x03, 0x90, 0x11, 0x40, 0x46, 0x40, 0xD1, 0x00, 0x74, 0x0E, 0xD1, 0x19, 0x42, -0x34, 0x00, 0xD9, 0x00, 0x44, 0x05, 0x9A, 0x09, 0x40, 0x37, 0x20, 0x8D, 0x08, -0x46, 0x07, 0xD0, 0x0D, 0x42, 0x17, 0x04, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x1D, -0x40, 0x34, 0x00, 0xD1, 0x01, 0x40, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x04, 0x03, -0x90, 0x10, 0x40, 0x02, 0x00, 0xC1, 0x00, 0x34, 0x00, 0xD2, 0x08, 0x40, 0x32, -0x00, 0x41, 0x00, 0x04, 0x02, 0x10, 0x08, 0x60, 0x31, 0x00, 0x8D, 0x00, 0x05, -0x03, 0xD8, 0x0C, 0x40, 0x03, 0x00, 0xDD, 0x00, 0x04, 0x02, 0xD0, 0x0C, 0x48, -0x36, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x50, 0x08, 0x40, 0x41, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x05, 0x03, 0xB0, -0x01, 0xC0, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x40, 0x34, 0x00, -0x4B, 0x00, 0x4C, 0x00, 0xB0, 0x09, 0x44, 0x37, 0x00, 0xBF, 0x00, 0x44, 0x03, -0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x00, 0x54, 0x03, 0xF0, 0x0D, 0xC0, 0x34, -0x00, 0xD3, 0x00, 0x4D, 0x02, 0x70, 0x09, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x78, 0x02, -0xC0, 0x0D, 0x00, 0xFF, 0x40, 0xF6, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0x7F, -0x00, 0xFD, 0x00, 0xF0, 0x0B, 0xC8, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3B, 0x00, -0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x0B, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x7F, 0x02, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x1F, 0xC0, -0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, -0xCC, 0x07, 0xF0, 0x3F, 0xC0, 0x7C, 0x02, 0xFF, 0x21, 0xCC, 0x07, 0x30, 0x9F, -0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x22, 0xF0, 0x3F, 0xC0, 0x5E, 0x10, 0xBB, -0x01, 0xEC, 0x84, 0x38, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x07, 0x00, 0x11, 0x01, 0x74, 0x10, 0xD1, 0x01, 0x40, 0x47, -0x00, 0x11, 0x04, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x1D, 0x04, 0x44, -0x84, 0xD0, 0x01, 0x48, 0x04, 0x01, 0x1D, 0x01, 0x44, 0x04, 0x12, 0x41, 0x40, -0x44, 0x40, 0x11, 0x01, 0x74, 0x38, 0xD0, 0x0D, 0x40, 0x55, 0x00, 0xD1, 0x01, -0x54, 0x03, 0xB0, 0x01, 0x40, 0x0D, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0xA0, 0x33, 0x11, 0xC1, 0x00, 0x34, 0x83, 0xD0, 0x4C, 0x41, 0x37, 0x00, -0xC1, 0x10, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03, -0xD0, 0x4D, 0x40, 0x30, 0x01, 0xD5, 0xA0, 0x64, 0x83, 0x10, 0x4C, 0x40, 0x35, -0x00, 0xC9, 0x00, 0x34, 0x10, 0xD0, 0x4C, 0x40, 0x30, 0x60, 0xD9, 0x40, 0x24, -0x01, 0x10, 0x08, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA8, 0x05, 0x40, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x01, 0x40, 0x07, 0x00, 0x11, -0x00, 0x74, 0x00, 0xD1, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, -0x01, 0x48, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20, -0x19, 0x00, 0x74, 0x0C, 0xD0, 0x1C, 0x40, 0x75, 0x00, 0xD1, 0x01, 0x54, 0x0B, -0x15, 0x19, 0x41, 0x0D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, -0x37, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00, -0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x00, 0xCF, 0x00, 0x4C, 0x03, 0xF0, 0x0D, -0xD0, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x03, 0x30, 0x0D, 0xD0, 0x34, 0x00, 0xDB, -0x00, 0x7C, 0x0E, 0xE0, 0x1D, 0xC0, 0xC0, 0x04, 0xCB, 0x01, 0x6C, 0x04, 0x10, -0x19, 0xC0, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x0D, -0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x0F, 0x00, 0x3F, 0x00, 0xFC, -0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4, -0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x37, 0x40, -0x7C, 0x42, 0xF0, 0x07, 0xC2, 0x1F, 0x00, 0xFF, 0x00, 0xEC, 0xA4, 0xF0, 0x00, -0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x75, 0x01, -0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xD0, 0x74, 0x00, 0xD3, 0x00, 0x4D, 0x03, -0xF0, 0x0D, 0xC8, 0x37, 0x40, 0xD3, 0x00, 0x7C, 0x07, 0x30, 0x8D, 0xC1, 0x37, -0x14, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D, 0xC0, 0x76, 0x04, 0xD3, 0x40, 0x6C, -0x28, 0x30, 0x09, 0xC0, 0x37, 0x01, 0xD3, 0x00, 0x7C, 0xC8, 0x20, 0x29, 0xC6, -0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x1D, -0x0F, 0x74, 0x10, 0x10, 0x11, 0x42, 0x04, 0x00, 0x11, 0x0A, 0x44, 0x00, 0xD0, -0x01, 0x40, 0x07, 0x00, 0x11, 0x13, 0x74, 0x00, 0x10, 0x00, 0x40, 0xC7, 0x10, -0x0D, 0x00, 0x34, 0x04, 0xD0, 0x31, 0x40, 0x83, 0x00, 0x11, 0xA5, 0x74, 0x08, -0x10, 0x05, 0x40, 0x37, 0x00, 0xD1, 0x11, 0x74, 0x0E, 0xB0, 0x09, 0x40, 0x4C, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xB4, 0x00, 0xCD, 0x03, -0x34, 0x43, 0x10, 0x6C, 0x40, 0x30, 0x00, 0xC1, 0x01, 0x04, 0x03, 0xD0, 0x0C, -0x40, 0x73, 0x00, 0xC1, 0x00, 0x14, 0x03, 0x10, 0x2C, 0x44, 0x33, 0x00, 0xCD, -0x00, 0x34, 0x07, 0xD0, 0x7D, 0x40, 0x33, 0x80, 0xC1, 0x81, 0x34, 0x0E, 0xD0, -0x0C, 0x40, 0xB3, 0x00, 0xC1, 0x11, 0x64, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0x2D, 0x01, 0xF4, -0x04, 0x10, 0x13, 0x48, 0x4C, 0x00, 0x21, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40, -0x4B, 0x04, 0x21, 0x03, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x14, 0x2D, 0x01, -0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4F, 0x40, 0x21, 0x01, 0xB4, 0x05, 0xD0, 0x1E, -0x40, 0x7F, 0x00, 0x61, 0x01, 0xB4, 0xA7, 0x90, 0x12, 0x40, 0x3C, 0x20, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x92, 0xCF, 0x00, 0x3C, 0x03, -0x30, 0x0C, 0xC1, 0x30, 0x00, 0xD3, 0x10, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x33, -0x00, 0xC3, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x1C, -0x03, 0xF0, 0x0C, 0xC1, 0x33, 0x20, 0xC1, 0x00, 0x3E, 0x23, 0xF4, 0x0C, 0xC0, -0x33, 0x80, 0xC3, 0x08, 0x7C, 0x63, 0x30, 0x80, 0xD0, 0x48, 0x40, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xF0, -0x02, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x83, 0xC0, 0x03, 0x00, -0x1F, 0x40, 0xBC, 0x20, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0x7C, 0x00, -0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x41, 0xFC, 0xA3, 0x20, 0x8F, 0xC8, 0x3B, -0x00, 0x7F, 0x00, 0xFC, 0x23, 0xF0, 0x07, 0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xD0, 0x74, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xF0, -0x1D, 0xD0, 0x30, 0x00, 0xC3, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x80, -0xDF, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x32, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40, -0x0B, 0x20, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00, -0xB4, 0x00, 0xD0, 0x03, 0x40, 0x0C, 0x00, 0x21, 0x00, 0xB4, 0x00, 0xD0, 0x03, -0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x83, 0xD0, 0x06, 0x40, 0x3B, 0x20, 0x6D, -0x40, 0xF4, 0x01, 0x10, 0x02, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, -0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4, -0x87, 0xD0, 0x1E, 0x40, 0x7A, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, -0x78, 0x00, 0xF1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x51, -0xB4, 0x87, 0x10, 0x1E, 0x41, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x36, 0x28, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, -0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x02, 0x10, 0x1D, 0x20, 0x34, 0x00, -0xD0, 0x00, 0x40, 0x02, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00, -0x10, 0x01, 0x00, 0x14, 0x9B, 0xD0, 0x04, 0x42, 0x33, 0x00, 0x4D, 0x01, 0x34, -0x03, 0x11, 0x2C, 0x41, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, -0xA0, 0x15, 0x00, 0x4F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC4, 0x13, 0x00, 0x5F, -0x00, 0x7C, 0x01, 0xF0, 0x05, 0xD0, 0x16, 0x00, 0x5F, 0x00, 0x74, 0x01, 0xF0, -0x05, 0xC2, 0x16, 0x00, 0x51, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x40, -0x53, 0x00, 0xCC, 0x09, 0xD1, 0x87, 0x40, 0x1F, 0x00, 0x7D, 0x01, 0xBC, 0x05, -0x14, 0x27, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, -0x0D, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x20, 0x3F, 0x80, 0xFC, 0x00, 0xB0, 0x03, -0xC0, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F, -0x00, 0x65, 0x20, 0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x38, 0xF0, -0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, -0x02, 0x9F, 0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x05, 0x7C, -0x02, 0x30, 0x09, 0xC0, 0x67, 0x02, 0x9F, 0x08, 0x6C, 0x82, 0xF0, 0x49, 0xC0, -0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC8, 0x27, 0x00, 0x93, 0x05, -0x0C, 0x02, 0x32, 0x09, 0xC2, 0x27, 0x02, 0x9D, 0x04, 0x5C, 0x02, 0x34, 0x09, -0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, -0x9D, 0x02, 0x44, 0x0E, 0xD8, 0x29, 0x40, 0x27, 0x00, 0x9B, 0x43, 0x34, 0x02, -0x10, 0x09, 0x40, 0x27, 0x08, 0x9F, 0x02, 0x44, 0x02, 0xE0, 0x29, 0x40, 0xA7, -0x00, 0x9D, 0x00, 0x74, 0x02, 0xB0, 0x29, 0x40, 0x23, 0x10, 0x8B, 0x01, 0x44, -0x16, 0x10, 0x09, 0x48, 0xA7, 0x04, 0x8D, 0x00, 0x6C, 0x4E, 0x10, 0x09, 0x48, -0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24, 0x00, 0xBD, -0x50, 0xE6, 0x02, 0xD0, 0x8B, 0x41, 0x6F, 0x08, 0xB5, 0x40, 0xF4, 0x02, 0x10, -0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x10, 0xC4, 0x06, 0xC0, 0x0B, 0x40, 0x2F, 0x01, -0xBD, 0x08, 0xF4, 0x06, 0x10, 0x8B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0x45, 0x22, -0x18, 0x09, 0x40, 0x27, 0x00, 0xDC, 0x00, 0x64, 0x06, 0x10, 0x09, 0x40, 0x73, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x68, 0x00, 0xAD, 0x00, -0x86, 0x86, 0xD0, 0x0A, 0x40, 0x2B, 0x80, 0xA1, 0x01, 0xF4, 0x02, 0x10, 0x0A, -0x40, 0x2B, 0x00, 0xA5, 0x00, 0x84, 0x02, 0x50, 0x1A, 0x40, 0x6B, 0x00, 0xAD, -0x00, 0xB4, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xB9, 0x00, 0x04, 0x12, 0x14, -0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x64, 0x02, 0x10, 0x48, 0x40, 0x53, 0xA0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x1F, 0x00, 0x6C, -0x28, 0xD0, 0xA1, 0xC0, 0x07, 0x00, 0x15, 0x4A, 0x7C, 0x00, 0x34, 0x01, 0xC0, -0x07, 0x00, 0x1D, 0x0A, 0x4D, 0x00, 0xD0, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x00, -0x7C, 0x00, 0x30, 0xA1, 0x40, 0x07, 0x00, 0x33, 0x00, 0x4C, 0x28, 0x30, 0xA1, -0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x28, 0x39, 0xA1, 0xC0, 0x77, 0xC0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82, -0xF0, 0x09, 0xC0, 0x27, 0x48, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x08, 0xC0, 0x27, -0x08, 0x9F, 0x40, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x0B, 0xC0, -0x2F, 0x00, 0xBF, 0x20, 0xFC, 0x02, 0xF0, 0x8F, 0xC0, 0x67, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30, -0x0B, 0xC2, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x28, -0xBF, 0x00, 0xDC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x02, -0xF0, 0x0B, 0x80, 0x2F, 0x10, 0xBF, 0x00, 0xDC, 0x52, 0x30, 0x88, 0xC2, 0x29, -0x00, 0xB3, 0x00, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x11, 0x00, 0x74, 0x40, 0x12, 0x01, -0x49, 0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xD0, 0x01, 0x48, 0x07, 0x20, 0x17, -0x10, 0x74, 0x00, 0x50, 0x41, 0x41, 0x07, 0x01, 0x1D, 0x80, 0x74, 0x00, 0xD0, -0x01, 0x49, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x10, 0x10, 0x41, 0x44, 0x07, 0x00, -0x11, 0x00, 0x5C, 0x81, 0xD2, 0x41, 0x45, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x60, 0x14, 0x12, 0x14, 0x08, 0x40, -0x20, 0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x00, -0x14, 0x03, 0x10, 0x48, 0x40, 0x33, 0x85, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x08, -0x40, 0x23, 0x00, 0x8D, 0x00, 0x14, 0x52, 0xD0, 0x48, 0x40, 0x21, 0x00, 0x89, -0x00, 0x14, 0x02, 0xD9, 0x48, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0x08, 0x25, 0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x50, 0x24, -0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74, -0x02, 0x51, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x74, 0x06, 0xD0, 0x89, 0x40, 0xE7, 0x00, 0x99, 0x01, -0x50, 0x12, 0xD0, 0x09, 0x60, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x20, 0x25, 0x00, 0x93, 0x80, 0x5C, 0x02, 0x31, 0x09, 0xC2, 0x24, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x02, -0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x80, 0x5C, 0x12, 0xB4, 0x09, 0xC0, 0xE1, 0x40, 0x9B, 0x01, 0x58, -0x06, 0xF0, 0x09, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x08, 0x25, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF3, 0x09, 0x40, 0x27, 0x10, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x96, 0x00, 0x70, 0x02, 0x70, -0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x04, -0x9F, 0xA0, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27, 0x00, 0x96, 0x00, 0x5C, 0x42, -0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, -0x05, 0x06, 0x1F, 0x01, 0x6C, 0x10, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, -0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC3, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x08, 0x13, -0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x05, 0x08, 0x17, 0x00, 0x6C, 0x28, 0xF0, -0x21, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C, -0x00, 0x7D, 0x11, 0xC4, 0x0D, 0x72, 0x57, 0x40, 0x14, 0x04, 0x7F, 0x41, 0x44, -0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x20, 0x34, 0x01, 0x72, 0x07, 0xC9, -0x1E, 0x02, 0x51, 0x00, 0x74, 0x01, 0x70, 0xD7, 0x00, 0x9F, 0x04, 0x51, 0x01, -0xC4, 0x15, 0x00, 0x05, 0x40, 0x1C, 0x00, 0x71, 0x05, 0xE4, 0x0D, 0xD0, 0x05, -0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF6, 0x00, -0x4D, 0x21, 0x64, 0x2F, 0x50, 0x4D, 0x40, 0x20, 0x20, 0xCD, 0x04, 0x04, 0x03, -0xD0, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x0D, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0xB0, -0x00, 0x89, 0x00, 0x34, 0x02, 0x50, 0x2C, 0x40, 0xF3, 0x00, 0x81, 0x89, 0x44, -0x13, 0x91, 0x0C, 0x40, 0x01, 0x00, 0x85, 0x01, 0x24, 0x0F, 0xD0, 0x0C, 0x42, -0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, -0x01, 0x86, 0x01, 0x50, 0x0E, 0x50, 0x38, 0x00, 0xF5, 0x11, 0x84, 0x03, 0xD0, -0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1F, 0x40, 0x5A, 0x40, -0xE9, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x6B, 0x40, 0xE1, 0x01, 0xC6, 0x03, -0x10, 0x5F, 0x40, 0x2C, 0x08, 0x61, 0x00, 0xA4, 0x03, 0xD2, 0x4E, 0x60, 0x07, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, -0xAC, 0x07, 0x70, 0x1F, 0xC0, 0x78, 0x20, 0xED, 0x01, 0x85, 0x07, 0xF0, 0x1E, -0xC6, 0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xEB, -0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xCC, 0x05, 0xB0, -0x9E, 0xC0, 0x79, 0x00, 0x65, 0x41, 0xAC, 0x04, 0xF0, 0x5E, 0xC0, 0x47, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xCF, 0x00, 0x7C, -0x01, 0x71, 0x0D, 0xC4, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40, -0x37, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x10, 0xD7, 0x80, -0x7C, 0x83, 0x70, 0x0D, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x8D, -0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x8D, 0xC0, 0x43, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xFF, 0x01, 0xCC, 0x13, -0xF0, 0x5F, 0xC0, 0x7B, 0x62, 0x73, 0x41, 0xBC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, -0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xFB, 0x09, 0xEC, -0x27, 0x30, 0x1E, 0xC0, 0x78, 0x00, 0xF3, 0x00, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, -0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x08, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x16, 0xED, 0x00, 0x84, 0x01, 0xD0, -0x06, 0x40, 0x3B, 0x06, 0x65, 0x00, 0xB4, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x02, -0x61, 0x08, 0xB4, 0x03, 0xD2, 0x47, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x84, 0x03, -0x10, 0x0E, 0x40, 0x38, 0x04, 0xE5, 0x08, 0xB4, 0x29, 0xD0, 0x0F, 0x40, 0x29, -0x02, 0x6D, 0x00, 0xB4, 0x22, 0xD0, 0x0E, 0xC0, 0x56, 0x60, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0xFD, 0x00, 0x84, 0x23, 0xD0, 0x4E, -0x48, 0x3B, 0x12, 0x60, 0x00, 0xF4, 0x03, 0x10, 0x2E, 0x40, 0x3F, 0x00, 0xE1, -0x00, 0xB4, 0x03, 0xC1, 0x06, 0x60, 0x9C, 0x00, 0xF1, 0x80, 0xC6, 0x03, 0x10, -0x87, 0x40, 0xB8, 0x00, 0xE1, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00, -0x6D, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x60, 0x08, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xCD, 0x12, 0x44, 0x2C, 0xD0, 0xA8, 0x40, -0xB3, 0x04, 0x11, 0x03, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0xB3, 0x04, 0x91, 0x03, -0x34, 0x0B, 0x90, 0x20, 0x40, 0x00, 0x00, 0xC1, 0x02, 0x04, 0x0B, 0x10, 0x08, -0x41, 0x30, 0x40, 0xC5, 0x01, 0x74, 0x40, 0xD0, 0x1C, 0x40, 0x31, 0x10, 0x4D, -0x0A, 0x30, 0x02, 0xC1, 0x2D, 0x48, 0x1A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA0, 0x61, 0x00, 0xCF, 0x00, 0x4C, 0x22, 0xF0, 0x21, 0xC0, 0xF7, -0x00, 0x93, 0x11, 0x7C, 0x0B, 0x34, 0x5C, 0xC0, 0x33, 0x00, 0x13, 0x01, 0x7C, -0x23, 0xF0, 0x79, 0xD0, 0x64, 0x01, 0xC3, 0x08, 0x4C, 0x23, 0x30, 0x51, 0xC0, -0x34, 0x00, 0xD3, 0x00, 0x7C, 0x06, 0xF0, 0x5F, 0xC0, 0x10, 0x20, 0xCF, 0x23, -0x7C, 0x08, 0xC0, 0xBF, 0x80, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x08, 0x27, 0x20, 0xDF, 0x01, 0x7C, 0x02, 0xF1, 0x21, 0xC8, 0x37, 0x00, -0x9F, 0x02, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x77, 0x00, 0x1F, 0x1A, 0x7C, 0x07, -0xF0, 0x29, 0xC8, 0x87, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x21, 0xC0, 0x87, -0x00, 0xDF, 0x08, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0x5F, 0x04, 0x7C, -0x3A, 0xF1, 0x8D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, -0x08, 0x0F, 0x00, 0xF3, 0x00, 0xCC, 0x00, 0x30, 0x03, 0xC1, 0x7C, 0x08, 0x3F, -0x90, 0xCC, 0x43, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x33, 0x00, 0xCC, 0x07, 0x30, -0x03, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xF0, 0x03, 0xC0, 0x3F, 0x00, -0xFF, 0x12, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x7F, 0x01, 0x73, 0x01, 0xCC, 0x00, -0xF1, 0x0D, 0xC0, 0x14, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, -0xE6, 0x09, 0xD0, 0x01, 0x44, 0x04, 0x12, 0x30, 0x42, 0x34, 0x08, 0x9D, 0x03, -0x4C, 0x03, 0xD0, 0x0D, 0x60, 0x34, 0x00, 0x11, 0x25, 0x04, 0x07, 0x12, 0x39, -0x40, 0xC7, 0x00, 0xDD, 0x80, 0x6C, 0x03, 0xD0, 0x11, 0x40, 0x87, 0x00, 0xDD, -0x01, 0x70, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x51, 0x08, 0x7D, 0x4C, 0xD2, -0x0D, 0x4C, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66, -0x00, 0xD1, 0x01, 0x44, 0x06, 0x98, 0x19, 0x40, 0x36, 0x01, 0x9D, 0x11, 0x64, -0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x90, 0x01, 0x44, 0x23, 0x10, 0x19, 0x41, -0x67, 0x04, 0xDD, 0x04, 0x54, 0xA3, 0xD1, 0x19, 0x40, 0x37, 0x04, 0xDD, 0x00, -0x74, 0x06, 0x18, 0x0D, 0x40, 0x17, 0x00, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x0D, -0x58, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x24, 0x00, -0x91, 0x01, 0x04, 0x02, 0x94, 0x01, 0x50, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x03, -0xD0, 0x0D, 0x40, 0x34, 0x00, 0x01, 0x00, 0x45, 0x03, 0x10, 0x08, 0x40, 0x23, -0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x48, 0x33, 0x00, 0xCD, 0x00, 0x34, -0x02, 0x10, 0x0C, 0x40, 0x37, 0x00, 0x51, 0x00, 0x24, 0x02, 0x90, 0x0C, 0x40, -0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3, -0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC4, 0x36, 0x00, 0x1F, 0x00, 0x6D, 0x03, 0xF0, -0x0D, 0x40, 0x34, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x01, 0xC4, 0x27, 0x00, -0xDF, 0x00, 0x5C, 0x03, 0xF1, 0x01, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, -0x34, 0x0F, 0xC0, 0x37, 0x00, 0x53, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0x04, -0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x2F, 0x00, 0xAF, 0x00, -0xF4, 0x02, 0x70, 0x0B, 0xC4, 0x3D, 0x10, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, -0x80, 0x3B, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xEF, -0x00, 0xB8, 0x03, 0xF0, 0x0B, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, -0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC, 0x02, 0xF8, 0x0F, 0xC0, 0x17, 0x24, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x0B, 0x80, 0x33, 0x00, 0xFC, -0x10, 0x30, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x27, 0x30, 0x03, 0xC8, -0x2C, 0x05, 0xB5, 0x00, 0xCC, 0x02, 0x30, 0x83, 0xC0, 0x2F, 0x03, 0x33, 0x01, -0xCC, 0x01, 0xF0, 0x1B, 0xC0, 0x2F, 0x01, 0x3F, 0x01, 0xCC, 0x26, 0xB0, 0x0B, -0xC0, 0x7C, 0x00, 0xBF, 0x14, 0xFC, 0x27, 0x30, 0x4F, 0xC1, 0x0C, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x10, 0x11, 0x0A, 0x74, 0x28, -0x12, 0x4F, 0x40, 0x7C, 0x10, 0xD5, 0x01, 0x04, 0x02, 0x10, 0x01, 0x50, 0xE4, -0x08, 0x91, 0x08, 0x54, 0x02, 0x10, 0x0B, 0x40, 0xAF, 0x00, 0x91, 0x00, 0x44, -0x2C, 0xD0, 0x19, 0x40, 0xE7, 0x00, 0x1D, 0x01, 0x44, 0x02, 0x14, 0x08, 0x40, -0x74, 0x00, 0x9D, 0x03, 0x74, 0x03, 0x10, 0x3D, 0x40, 0x04, 0x60, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x01, 0x20, 0x34, 0x00, 0x50, -0x0C, 0x51, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x20, 0x00, -0x85, 0x00, 0x04, 0x02, 0x14, 0x48, 0x40, 0xB7, 0x20, 0x91, 0x14, 0x16, 0x81, -0x90, 0x0C, 0x42, 0xB3, 0x00, 0x1D, 0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x30, -0x00, 0x09, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x00, 0x11, 0x01, 0x74, 0x44, 0x10, 0x8D, -0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x02, 0x10, 0x01, 0x40, 0x24, 0x01, 0xD1, -0x20, 0x54, 0x46, 0x10, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x40, 0xD0, -0x15, 0x40, 0x77, 0x00, 0x1D, 0x11, 0x64, 0x12, 0x10, 0x09, 0x41, 0x74, 0x00, -0xDD, 0x44, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x1C, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x47, 0x42, 0x11, 0x81, 0x7C, 0x0C, 0x34, 0x1D, 0xC0, -0x34, 0x00, 0xD3, 0x00, 0x49, 0x03, 0x30, 0x15, 0xD0, 0x24, 0x00, 0x97, 0x80, -0x4C, 0x06, 0x30, 0x39, 0xC0, 0x63, 0x40, 0x83, 0x01, 0x5D, 0x01, 0xF0, 0x19, -0xC0, 0x77, 0x00, 0x0F, 0x01, 0x2D, 0x07, 0xB0, 0x29, 0xD0, 0x34, 0x00, 0x9F, -0x01, 0x7E, 0x06, 0x30, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x88, 0x6D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xE2, 0x1E, 0xE1, 0x3F, -0x00, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x4E, 0xE0, 0x6B, 0x00, 0x8F, 0x20, 0x7C, -0x02, 0xF0, 0x0F, 0xC0, 0x67, 0x22, 0xBF, 0x10, 0xEC, 0x25, 0xF0, 0x0B, 0xC0, -0x3F, 0x08, 0x3F, 0x00, 0xDC, 0x03, 0xF0, 0x47, 0xC0, 0x3F, 0x00, 0xBF, 0x81, -0xFE, 0x06, 0xF4, 0x0C, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x08, 0x21, 0x00, 0x13, 0x80, 0x6C, 0x18, 0x32, 0x0D, 0xC0, 0x73, 0x00, -0xD3, 0x00, 0x7C, 0x03, 0x30, 0x05, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x4C, 0x3A, -0x34, 0x2D, 0xC0, 0x3C, 0x00, 0x93, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0, 0x77, -0x00, 0x1F, 0x02, 0x7C, 0x23, 0x30, 0x24, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x4C, -0x02, 0xF0, 0x0D, 0xE0, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0xA0, 0x6C, 0x01, 0x91, 0x01, 0x44, 0x0C, 0x10, 0x1D, 0xE4, 0x3F, 0x00, 0xE1, -0x00, 0x74, 0x07, 0x10, 0x0D, 0x48, 0x24, 0x00, 0xD1, 0x00, 0x6C, 0x0A, 0x12, -0x0D, 0x48, 0x24, 0x30, 0x9B, 0x00, 0x70, 0x15, 0x11, 0x05, 0x40, 0x34, 0x00, -0x1D, 0x00, 0x74, 0x07, 0x10, 0xA5, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x44, 0x02, -0xD0, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, -0x40, 0x00, 0x01, 0x00, 0x24, 0x84, 0x10, 0x08, 0x40, 0x33, 0x40, 0xC1, 0x80, -0x74, 0x07, 0x90, 0x20, 0x41, 0x20, 0x40, 0x81, 0x00, 0x44, 0x03, 0x91, 0x08, -0x40, 0x21, 0x20, 0x81, 0x02, 0x30, 0x41, 0x16, 0x0C, 0x52, 0x33, 0x00, 0x4D, -0x00, 0x34, 0x06, 0x10, 0x08, 0x40, 0x30, 0x00, 0x8D, 0x01, 0x44, 0x02, 0xD0, -0x0C, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6C, -0x00, 0x01, 0x11, 0x84, 0x64, 0x10, 0x1E, 0x40, 0x79, 0x40, 0xE1, 0x61, 0xB4, -0x4E, 0x90, 0x12, 0x50, 0x78, 0x00, 0xA1, 0x11, 0xA4, 0x26, 0x90, 0x0A, 0x40, -0x69, 0x00, 0xE9, 0x01, 0xB4, 0x06, 0x10, 0x1F, 0x40, 0x5A, 0x00, 0x6D, 0x01, -0xB4, 0x06, 0x10, 0x1A, 0x40, 0x78, 0x20, 0x8D, 0x01, 0x84, 0x06, 0xD0, 0x1E, -0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x20, 0x00, -0x03, 0x20, 0x6E, 0x20, 0x34, 0x08, 0x41, 0x33, 0x00, 0xC3, 0x00, 0x3C, 0x02, -0x90, 0x01, 0xC1, 0x20, 0x00, 0x83, 0x00, 0x0C, 0x23, 0xB4, 0x89, 0xC0, 0x31, -0x09, 0x83, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0x0F, 0x00, 0x7C, -0x02, 0x34, 0x08, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x0D, 0x02, 0xF2, 0x0C, 0xD0, -0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x2D, 0x40, 0x3F, -0x00, 0xF6, 0x20, 0xF5, 0x0F, 0xC0, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x50, -0x03, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xFC, 0xA1, 0x70, 0xCB, 0xE0, 0xBE, 0x00, -0xBF, 0x00, 0xBC, 0x02, 0xF0, 0x06, 0xC0, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x02, -0xF0, 0x8B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0A, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x07, 0x00, 0x13, 0x00, -0xCC, 0x00, 0x30, 0x59, 0xC8, 0x30, 0x13, 0xF7, 0x00, 0x74, 0x03, 0x70, 0x01, -0xC0, 0x24, 0x00, 0x9E, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC1, 0xAC, 0x00, 0x93, -0x00, 0x7C, 0x01, 0xC0, 0x1D, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0x30, -0x05, 0xD0, 0x30, 0x00, 0x93, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x53, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA9, 0x00, 0x21, 0xC0, 0x84, -0x02, 0x11, 0x0E, 0xC1, 0x38, 0x04, 0xE1, 0x01, 0xB4, 0x03, 0xD0, 0x0F, 0x40, -0x38, 0x00, 0xAD, 0x00, 0xBC, 0x03, 0x10, 0x0E, 0x42, 0x20, 0x00, 0xE1, 0xC0, -0xB4, 0x03, 0xC0, 0x0E, 0xC0, 0x38, 0x00, 0x6D, 0x00, 0xB4, 0x02, 0x50, 0x0C, -0x40, 0x38, 0x00, 0xA5, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x4B, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x01, 0x21, 0x01, 0x84, 0x07, -0x10, 0x18, 0x00, 0x78, 0x01, 0xE5, 0x01, 0xB4, 0x47, 0xD1, 0x12, 0x50, 0x6A, -0x00, 0x8D, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x48, 0x78, 0x00, 0xA0, 0x01, 0xB4, -0x05, 0xD0, 0x1F, 0x50, 0x78, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x18, 0x1E, 0x40, -0x68, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x03, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xD1, 0x53, 0x04, 0x03, 0x10, -0x0C, 0x50, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0D, 0x40, 0x32, 0x00, -0xCD, 0x40, 0x34, 0x2B, 0x10, 0x5C, 0x60, 0x30, 0x00, 0x81, 0x00, 0x34, 0x03, -0xD0, 0x04, 0x40, 0xF2, 0x00, 0x8D, 0x00, 0x34, 0x26, 0x50, 0x7C, 0x42, 0x30, -0x00, 0xCD, 0x00, 0x34, 0x07, 0x14, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x17, 0xA0, 0x1D, 0x00, 0x73, 0x27, 0xCC, 0x0D, 0x34, 0x05, -0xC8, 0x10, 0x00, 0x57, 0x20, 0x7C, 0x05, 0xF0, 0x27, 0xC1, 0x16, 0x00, 0x5F, -0x00, 0xCC, 0x05, 0x34, 0x57, 0xD0, 0x14, 0x40, 0x73, 0x00, 0xFC, 0x01, 0xF0, -0x07, 0xC0, 0x1C, 0x01, 0x6B, 0x00, 0x7C, 0x01, 0x30, 0x77, 0xD0, 0x14, 0x00, -0x6B, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x08, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x20, 0xF0, 0x01, 0xC0, -0x05, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x01, 0xC5, 0x05, 0x00, 0x1F, 0x00, -0x7C, 0x40, 0xF0, 0x00, 0xC0, 0x03, 0x40, 0x1F, 0x04, 0x7C, 0x20, 0xF0, 0x01, -0xC0, 0x05, 0x30, 0x1F, 0x01, 0x7C, 0x00, 0xF4, 0x21, 0xC4, 0x07, 0x00, 0x17, -0x01, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x25, 0x00, 0x97, 0x00, 0x4C, 0x4A, 0x30, 0x59, 0xC0, 0xE7, -0x00, 0x8B, 0x01, 0x6C, 0x02, 0xF0, 0x19, 0x80, 0x24, 0x10, 0x8F, 0x89, 0x4C, -0x02, 0x38, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, -0x23, 0x04, 0x93, 0x01, 0x6D, 0x02, 0x30, 0x59, 0x40, 0xA4, 0x00, 0x93, 0x00, -0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x20, 0x24, 0x00, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x19, 0x40, 0x27, 0x00, -0x91, 0x03, 0x44, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x6C, 0x02, -0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x03, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27, -0x20, 0x9B, 0x00, 0x2C, 0x12, 0x50, 0x79, 0x50, 0x60, 0x00, 0x9B, 0x00, 0x44, -0x02, 0xD2, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x20, 0x40, 0x95, 0x20, 0x04, 0x0A, 0x56, 0x29, 0x40, 0x27, 0x40, 0x99, -0xA8, 0x64, 0x06, 0xD8, 0x89, 0x60, 0x25, 0xA0, 0x9D, 0x00, 0x04, 0x02, 0x14, -0x0D, 0x40, 0x26, 0x00, 0xD1, 0x00, 0x74, 0x06, 0xD8, 0x09, 0x40, 0x77, 0x00, -0x91, 0x08, 0x66, 0x92, 0x12, 0x08, 0x42, 0x25, 0xA0, 0x99, 0x00, 0x44, 0x02, -0xD0, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x50, 0x48, 0x40, 0x23, 0x01, 0x81, 0x04, -0x00, 0x06, 0xD0, 0x48, 0x50, 0x21, 0x01, 0x8D, 0x04, 0x25, 0x13, 0x10, 0x48, -0x40, 0x22, 0x11, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x08, 0x42, 0x23, 0x21, 0x99, -0x00, 0x64, 0x02, 0x50, 0x48, 0x40, 0x25, 0x00, 0x89, 0x04, 0x05, 0x02, 0xD0, -0x48, 0x41, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x83, -0x02, 0x07, 0x0A, 0x0C, 0x28, 0x72, 0xA1, 0x40, 0x07, 0x00, 0x5B, 0x00, 0x6C, -0x28, 0xF0, 0xA1, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x10, 0xA1, 0x50, -0x86, 0x02, 0x13, 0x0A, 0x7C, 0x01, 0xD1, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, -0x6D, 0x28, 0x30, 0xA1, 0xC0, 0x05, 0x00, 0x1B, 0x00, 0x4C, 0x08, 0xF0, 0x01, -0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x3F, 0x02, -0xBF, 0x08, 0xFD, 0x22, 0xB0, 0x8B, 0xC0, 0x27, 0x42, 0x9F, 0x08, 0xFC, 0x02, -0xF0, 0x8B, 0xC8, 0x2E, 0x12, 0xBF, 0x48, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2D, -0x42, 0xBF, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xBD, -0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xBF, 0x08, 0xBC, 0x42, 0xF0, 0x09, 0xC0, -0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x3F, 0x05, 0xB3, -0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x04, 0x8C, 0x02, 0xF0, -0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0, 0x24, 0x05, -0xAF, 0x08, 0xFC, 0x16, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02, -0xF0, 0xCA, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x7C, 0x22, 0xF0, 0x19, 0xC0, 0x67, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x51, 0x0C, -0x4C, 0x48, 0x14, 0x01, 0xC1, 0x04, 0x02, 0x11, 0x60, 0x44, 0x10, 0x70, 0xC0, -0x40, 0x05, 0x00, 0x11, 0x10, 0x44, 0x20, 0xD0, 0x05, 0x40, 0x04, 0x01, 0x1D, -0x04, 0x74, 0x08, 0xC0, 0x01, 0x40, 0x07, 0x02, 0x1D, 0x00, 0x74, 0x10, 0xD2, -0xC1, 0x40, 0x04, 0x00, 0x55, 0x00, 0x74, 0x04, 0xD0, 0x01, 0x40, 0x73, 0x60, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x04, 0x24, -0x32, 0x10, 0x88, 0x40, 0x21, 0x00, 0x81, 0x08, 0x04, 0x52, 0xD2, 0x48, 0x40, -0x20, 0x00, 0x81, 0x00, 0x04, 0x06, 0xD0, 0x88, 0x44, 0x20, 0x05, 0x8D, 0x04, -0x34, 0x22, 0xD8, 0x18, 0x40, 0x63, 0x00, 0x8D, 0x20, 0x34, 0x52, 0xD0, 0x48, -0x40, 0x20, 0x00, 0x81, 0x08, 0x34, 0x12, 0xD0, 0x28, 0x40, 0x4B, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x65, 0x58, 0x81, 0x00, 0x44, 0x02, -0x10, 0x09, 0x40, 0x26, 0x00, 0x91, 0x00, 0x45, 0x12, 0x50, 0x08, 0x50, 0x25, -0x00, 0x91, 0x04, 0x45, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x20, 0x9D, 0x24, 0x74, -0x83, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x06, 0x74, 0x02, 0xD0, 0x49, 0x41, -0x24, 0x00, 0x95, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x82, 0x6D, 0x1A, 0x32, -0x09, 0xC0, 0x25, 0x40, 0x93, 0x00, 0x4C, 0x06, 0xF2, 0x09, 0xC0, 0x24, 0x00, -0x93, 0x00, 0x4C, 0x06, 0xF0, 0xB9, 0xC0, 0x24, 0x00, 0x9F, 0x06, 0x7C, 0x02, -0xF0, 0x09, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x24, -0x02, 0x93, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x26, 0xF0, 0x09, -0xC1, 0x21, 0x00, 0x8F, 0x00, 0x7C, 0x46, 0x70, 0x09, 0x40, 0x26, 0x40, 0x9F, -0x01, 0x7C, 0x0A, 0xF0, 0x18, 0xD0, 0x67, 0x01, 0x9F, 0x00, 0x7C, 0x12, 0xF0, -0x39, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xD0, 0x27, 0x80, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x08, 0x85, 0x00, 0x13, 0x02, 0x4C, 0x00, 0xB0, 0x01, 0xC0, -0x04, 0x40, 0x13, 0x04, 0x4C, 0x20, 0x30, 0x01, 0xC0, 0x04, 0x80, 0x1F, 0x00, -0x4C, 0x00, 0x34, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x82, 0x4C, 0x84, 0xB0, 0x01, -0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, -0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x00, 0x14, 0x48, 0x51, 0x00, 0xD4, 0x01, 0x34, 0x07, 0x40, 0x14, -0x00, 0x71, 0x00, 0xC4, 0x01, 0x10, 0x07, 0x50, 0x10, 0x00, 0x5D, 0x10, 0xFC, -0x11, 0x12, 0x05, 0x40, 0x14, 0x00, 0x71, 0x02, 0xC0, 0x05, 0x30, 0x05, 0x40, -0x57, 0x04, 0x5D, 0x01, 0xF4, 0x41, 0xD0, 0x07, 0x40, 0x10, 0x00, 0x5D, 0x01, -0x74, 0x01, 0x10, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA0, 0x36, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x2D, 0x40, 0x30, 0x00, -0x81, 0x00, 0x04, 0x0F, 0xD4, 0x1C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x07, -0x10, 0x1C, 0x40, 0x30, 0x20, 0xC1, 0x12, 0x00, 0x03, 0x0C, 0x0C, 0x40, 0x23, -0x00, 0xCD, 0x01, 0x34, 0x01, 0x90, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34, -0x03, 0x10, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x80, 0x30, 0x08, 0xC1, 0x00, 0x94, 0x03, 0x10, 0x02, 0x40, 0x38, 0x00, 0xA1, -0x02, 0xC4, 0x07, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xCD, 0x00, 0xB4, 0x05, 0x10, -0x2C, 0x40, 0x7A, 0x00, 0xF1, 0x01, 0x84, 0x0F, 0x10, 0x0E, 0x40, 0x3B, 0x00, -0xED, 0x10, 0xB4, 0x01, 0xD0, 0x03, 0x40, 0x28, 0x00, 0xAD, 0x02, 0xB4, 0x07, -0x10, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, -0x78, 0x40, 0xE3, 0x01, 0xCC, 0x04, 0x33, 0x12, 0x50, 0x60, 0x20, 0x23, 0x01, -0x8D, 0x07, 0xF0, 0x1A, 0xC2, 0x78, 0x00, 0xED, 0x01, 0xC8, 0x85, 0x30, 0x1E, -0xD0, 0x7C, 0x41, 0xE3, 0x01, 0x8D, 0x06, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, -0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xD0, 0x78, 0x00, 0xAD, 0x01, 0xFC, 0x07, 0x34, -0x1E, 0xC0, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5, -0x05, 0xDF, 0x02, 0x7C, 0x02, 0x70, 0x00, 0xC0, 0x37, 0x00, 0x1C, 0x00, 0x7C, -0x03, 0x30, 0x29, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0, -0x35, 0x02, 0xDF, 0x00, 0x3D, 0x00, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, -0xF3, 0x03, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x10, 0xF3, 0x01, 0xFC, 0x07, -0xF0, 0x3F, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xCC, 0x06, 0x30, 0x1A, 0xC0, 0x7D, -0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, -0x27, 0xF0, 0x1B, 0xD0, 0x6C, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, -0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x40, 0xF1, -0x00, 0x86, 0x03, 0x10, 0x02, 0x40, 0x38, 0x02, 0xE1, 0x04, 0xB4, 0x00, 0xD0, -0x8E, 0x40, 0x38, 0x00, 0xB1, 0x00, 0x84, 0x01, 0x10, 0x8A, 0x43, 0x38, 0x08, -0xED, 0x02, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23, -0xD0, 0x82, 0x40, 0x28, 0x00, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57, -0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x02, 0xE1, 0x00, -0x84, 0x20, 0x10, 0x00, 0x41, 0x20, 0x00, 0xA9, 0x40, 0xB4, 0x03, 0xD0, 0x08, -0x40, 0x38, 0x06, 0xA1, 0x00, 0x84, 0x60, 0x10, 0x0B, 0x40, 0x38, 0x04, 0xED, -0x00, 0x04, 0x00, 0x50, 0x2E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23, 0xD8, -0x0E, 0x40, 0x3A, 0x00, 0xA9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x23, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x0A, 0x44, -0x42, 0x10, 0x00, 0x48, 0x30, 0x00, 0x89, 0x00, 0x34, 0x07, 0xD0, 0xB9, 0x40, -0x70, 0x48, 0x91, 0x01, 0x04, 0x01, 0x10, 0x28, 0x40, 0x30, 0x00, 0xDD, 0x10, -0x04, 0x24, 0x10, 0x0C, 0x40, 0x33, 0x90, 0xCD, 0x02, 0x34, 0x02, 0xD0, 0x2D, -0x40, 0x32, 0x00, 0xCD, 0x03, 0x34, 0x83, 0xD2, 0x0C, 0x40, 0x5B, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x00, 0xD3, 0x03, 0x4D, 0x0B, -0x30, 0x10, 0xC0, 0x34, 0x50, 0x9B, 0x00, 0x7C, 0x47, 0xF0, 0x2D, 0xD0, 0x60, -0x00, 0xD3, 0x05, 0x4D, 0x0E, 0x34, 0x19, 0xD0, 0x7C, 0x00, 0xDF, 0x01, 0x4D, -0x22, 0x70, 0x0D, 0xC0, 0xB7, 0x02, 0xCF, 0x0A, 0x7C, 0x01, 0xF0, 0xF5, 0xD0, -0x66, 0x00, 0x9F, 0x09, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x77, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0x21, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00, -0xDF, 0x00, 0x7C, 0x40, 0xF1, 0x08, 0xC1, 0x37, 0x00, 0xDF, 0x01, 0x7C, 0x02, -0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x25, -0x02, 0x9F, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x40, 0xF3, 0x10, 0xDC, 0x04, 0x30, 0x03, -0xC0, 0xF8, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC1, 0xAC, 0x40, 0xF3, -0x00, 0x4C, 0x04, 0xF0, 0x0B, 0xE0, 0x3C, 0x00, 0xBF, 0x00, 0xCC, 0x00, 0xD0, -0x0F, 0xC0, 0x7F, 0x01, 0xB7, 0x01, 0xCC, 0x03, 0xF0, 0x3F, 0xC0, 0xEC, 0x00, -0xBF, 0x03, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x71, 0x40, -0x74, 0x00, 0x11, 0x40, 0x74, 0x03, 0xD0, 0x31, 0x41, 0x24, 0x50, 0xD1, 0x08, -0x44, 0x00, 0xD0, 0x99, 0x40, 0x34, 0x00, 0x9C, 0x03, 0x44, 0x0C, 0xD0, 0x0D, -0x48, 0x37, 0x00, 0x9D, 0x09, 0x44, 0x07, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x8D, -0x00, 0x45, 0x03, 0xD0, 0x0D, 0x40, 0x17, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0xA0, 0x66, 0x00, 0xD1, 0x08, 0x74, 0x23, 0x90, 0x11, 0x40, 0x34, -0x80, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, -0x12, 0xD0, 0x09, 0x40, 0x36, 0x00, 0x5D, 0x01, 0x44, 0x06, 0xD1, 0x0D, 0x40, -0x37, 0x00, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x05, 0x41, 0x24, 0x00, 0xDD, 0x00, -0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x00, 0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0x90, 0x00, 0x42, 0x30, 0xC0, -0xC1, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x50, 0x30, 0x00, 0x81, 0x00, 0x04, 0x00, -0xD0, 0x08, 0x48, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD8, 0x0C, 0x42, 0x33, -0x00, 0xCD, 0x80, 0x35, 0x03, 0xD0, 0x0C, 0x70, 0x20, 0x00, 0xDD, 0x00, 0x04, -0x03, 0xD0, 0x0C, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x2E, 0x00, 0xF3, 0x00, 0x1C, 0x00, 0xB0, 0x01, 0xD0, 0x34, 0x00, 0x93, -0x00, 0x7C, 0x03, 0xF2, 0x0B, 0xC0, 0x34, 0x00, 0x93, 0x80, 0x4C, 0x80, 0xF0, -0x09, 0xD0, 0x34, 0x00, 0x9F, 0x00, 0x4D, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x20, -0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xD0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03, -0xF0, 0x0D, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, -0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, -0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x40, 0xFC, 0x00, 0xF0, 0x0B, -0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0xFF, -0x00, 0xCC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC8, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F, -0x00, 0xBF, 0x0C, 0xCC, 0x12, 0xF0, 0x1F, 0xC0, 0xBE, 0x09, 0xBF, 0xC0, 0x9D, -0x40, 0xB0, 0x8F, 0xC0, 0x2F, 0x01, 0xB3, 0x10, 0xDC, 0xE2, 0x30, 0x1F, 0xC0, -0x3F, 0x01, 0xF3, 0x02, 0xCC, 0x02, 0x33, 0x16, 0xC4, 0x3C, 0x00, 0xEF, 0x01, -0xCC, 0x33, 0x30, 0x1F, 0xC0, 0x5A, 0x00, 0xFB, 0x01, 0xAC, 0x27, 0xB0, 0x0B, -0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x07, 0x00, -0x1D, 0x0E, 0x44, 0x12, 0xD0, 0x4D, 0x40, 0x3C, 0x03, 0x1D, 0x03, 0x44, 0x0F, -0x10, 0x2F, 0x40, 0x27, 0x05, 0xD1, 0x06, 0x44, 0x12, 0x10, 0x1D, 0x48, 0xBF, -0x00, 0xF1, 0x06, 0x44, 0x2C, 0x10, 0x05, 0x41, 0xBC, 0x02, 0xDD, 0x01, 0xD4, -0x0B, 0x10, 0x1D, 0x40, 0x74, 0x00, 0xD1, 0x01, 0x44, 0x03, 0x10, 0x01, 0x40, -0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0xA3, 0x05, 0x8D, -0x01, 0x06, 0x62, 0xD0, 0x09, 0x41, 0x30, 0x20, 0x8D, 0x08, 0x15, 0x03, 0x92, -0xCC, 0x40, 0x43, 0x03, 0xC5, 0x10, 0x34, 0x10, 0x12, 0x0C, 0x42, 0xB2, 0x25, -0xC1, 0x8C, 0x04, 0x04, 0x50, 0x01, 0x50, 0x30, 0x0C, 0x5D, 0x00, 0x24, 0x33, -0x10, 0x0C, 0x40, 0x06, 0x00, 0xD9, 0xA0, 0x64, 0x12, 0x90, 0x08, 0x40, 0x4F, -0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x01, -0x44, 0x06, 0xD0, 0x19, 0x50, 0x34, 0x00, 0x9D, 0x03, 0x55, 0x0F, 0x10, 0x0D, -0x42, 0x67, 0x00, 0xD5, 0x00, 0x64, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD1, -0x00, 0x44, 0x04, 0x40, 0x05, 0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x03, 0x10, -0x0D, 0x40, 0x74, 0x00, 0x59, 0x01, 0x44, 0x03, 0x18, 0x11, 0x41, 0x0F, 0xA0, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x04, 0x1F, 0x01, 0x4C, -0x14, 0xF0, 0x5C, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x5D, 0x0F, 0xB0, 0x0D, 0xC0, -0x47, 0x00, 0xD7, 0x00, 0x7C, 0x06, 0x30, 0x0D, 0xE0, 0x37, 0x00, 0xD1, 0x20, -0x4C, 0x06, 0x60, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x6E, 0x03, 0x30, 0x0C, -0xC0, 0x76, 0x00, 0xDB, 0x05, 0x2C, 0x03, 0xB0, 0x19, 0x44, 0x23, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x05, 0x00, 0x1F, 0x10, 0xFC, 0x02, -0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x3F, 0x40, 0xAC, 0x03, 0xF2, 0x0F, 0xC0, 0x07, -0x0C, 0xEB, 0x05, 0x1C, 0x02, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0x3C, -0x00, 0xB2, 0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x89, 0x9C, 0x03, 0xF0, 0x5F, 0xC8, -0x3F, 0x40, 0xF7, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x1F, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xA5, 0x80, 0x93, 0x00, 0x4C, 0x00, 0xF0, -0x09, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x6C, 0x0B, 0x3C, 0x0D, 0xC0, 0x04, 0x00, -0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x32, 0x00, 0xDB, 0x00, 0x4C, 0x02, -0x31, 0x0D, 0xE0, 0x34, 0x10, 0x93, 0x02, 0x4C, 0x03, 0x34, 0x4D, 0xC0, 0x74, -0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x10, 0x9B, 0x06, 0x44, 0x02, 0xD0, 0x09, -0x40, 0x3F, 0x00, 0x81, 0x0B, 0x68, 0x07, 0xB0, 0x1F, 0xC0, 0xE4, 0x00, 0xD0, -0x00, 0x74, 0x02, 0x10, 0x0D, 0x48, 0x3F, 0x00, 0xFB, 0x10, 0x44, 0x02, 0x00, -0x0D, 0xC0, 0x3F, 0x00, 0x81, 0x81, 0xC4, 0x2B, 0x10, 0x2D, 0x40, 0x70, 0x00, -0x05, 0x05, 0x6C, 0x2F, 0x10, 0x49, 0xC0, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0xA0, 0x02, 0x00, 0x91, 0x02, 0x24, 0x00, 0xD0, 0x08, 0x64, -0xF3, 0x00, 0x01, 0x03, 0x20, 0x07, 0x10, 0x5C, 0x48, 0xE4, 0x00, 0xC5, 0x00, -0x34, 0x00, 0x11, 0x0C, 0x40, 0x31, 0x02, 0xD5, 0x01, 0x04, 0x02, 0x50, 0x14, -0x40, 0x70, 0x01, 0xC1, 0x00, 0x24, 0x23, 0x90, 0x2C, 0x40, 0x10, 0x00, 0xC1, -0x01, 0x04, 0x07, 0x50, 0x60, 0x44, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x80, 0x58, 0x00, 0xE9, 0x01, 0xA4, 0x05, 0xD0, 0x1A, 0x60, 0x7B, -0x04, 0x61, 0x01, 0xE4, 0x07, 0x94, 0x1E, 0x40, 0x78, 0x00, 0xE5, 0x01, 0xB4, -0x07, 0x10, 0x1E, 0x00, 0xFB, 0x00, 0xED, 0x03, 0x84, 0x07, 0x58, 0x37, 0x41, -0x79, 0x04, 0xF1, 0x00, 0xA0, 0x07, 0x91, 0x0E, 0x40, 0x78, 0x00, 0xF5, 0x01, -0xE4, 0x27, 0x18, 0x12, 0x48, 0x3E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x10, 0x10, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x00, -0x43, 0x14, 0x2C, 0x43, 0x10, 0x8D, 0xC1, 0x10, 0x04, 0xC7, 0x00, 0x34, 0x21, -0x30, 0x0C, 0xC0, 0x37, 0x00, 0xD7, 0x88, 0x0C, 0x01, 0x70, 0x00, 0x40, 0x34, -0x00, 0xC3, 0x18, 0x64, 0x13, 0xB0, 0x8C, 0x40, 0x10, 0x00, 0xC3, 0x00, 0x0C, -0x42, 0x70, 0x09, 0xC0, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x98, 0x3D, 0x20, 0xF7, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40, 0xEF, -0x00, 0xFC, 0x23, 0xF5, 0x0F, 0xC4, 0x35, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0, -0x0F, 0xC0, 0xBF, 0x02, 0xF3, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC0, 0x3F, 0x00, -0xFF, 0x0C, 0xDC, 0x03, 0x70, 0x4E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFE, 0x83, -0x70, 0x07, 0xC8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, -0x37, 0x80, 0x5B, 0x00, 0x5C, 0x01, 0x34, 0x09, 0xC0, 0xB7, 0x04, 0xCF, 0x80, -0x5C, 0x03, 0xF8, 0x4D, 0xC9, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x01, 0xF0, 0x0D, -0xC0, 0x37, 0x03, 0xDF, 0x02, 0x7E, 0x03, 0xF0, 0x05, 0xC0, 0xB6, 0x02, 0xDF, -0x00, 0x5C, 0x5B, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0xCF, 0x20, 0x4C, 0x03, 0x22, -0x01, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x1D, -0x08, 0x63, 0x00, 0xB4, 0x01, 0x10, 0x0A, 0x40, 0xBB, 0x11, 0x6D, 0x00, 0x94, -0x03, 0x30, 0x6E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, -0x3B, 0x01, 0xED, 0x48, 0xB4, 0x03, 0xD0, 0x0F, 0x40, 0x38, 0x04, 0xAD, 0x00, -0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x80, 0xD4, 0x83, 0x10, 0x06, -0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, -0xE1, 0x01, 0xB4, 0x47, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x11, 0xD4, 0x47, -0x50, 0x1E, 0x48, 0x5B, 0x00, 0xED, 0x01, 0xA5, 0x05, 0xD0, 0x1E, 0x40, 0x7B, -0x00, 0xED, 0x09, 0xB4, 0x07, 0xD2, 0x1E, 0x55, 0x78, 0x00, 0xAD, 0x01, 0xB4, -0x07, 0xD0, 0x1B, 0x40, 0x7A, 0x00, 0xF5, 0x01, 0x84, 0x06, 0x14, 0x18, 0x40, -0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0xC1, -0x0D, 0x34, 0x07, 0x90, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x03, 0x14, 0x0B, 0x90, -0x0C, 0x40, 0xF3, 0x04, 0xCD, 0x08, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x37, 0x20, -0xCD, 0x00, 0x34, 0x27, 0xD0, 0x4C, 0x40, 0x30, 0x00, 0x8D, 0x04, 0x34, 0x03, -0xD0, 0x18, 0x40, 0x70, 0x08, 0xCD, 0x01, 0x14, 0x03, 0x10, 0xAD, 0x43, 0x5A, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x04, 0x73, 0x02, -0xFC, 0x01, 0x30, 0x27, 0xC0, 0x17, 0x10, 0x7F, 0x02, 0xDD, 0xA9, 0x74, 0x05, -0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xEC, 0x15, 0xF0, 0x05, 0x40, 0x17, 0x80, 0x5F, -0x00, 0xFC, 0x09, 0xF0, 0x36, 0xC0, 0x14, 0x00, 0x7F, 0x02, 0x7C, 0x01, 0xF9, -0x15, 0xC2, 0x1E, 0x04, 0x67, 0x81, 0x44, 0x01, 0x10, 0x27, 0xC0, 0x5C, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x47, 0x40, 0x1F, 0x00, 0x7C, -0x40, 0x70, 0x41, 0xC0, 0x83, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0x74, 0x01, 0xC0, -0x07, 0x02, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC2, 0x87, 0x00, 0x1F, 0x00, -0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x7C, 0x00, 0xF0, 0x81, -0xC0, 0x07, 0x10, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x80, 0x93, 0x05, 0x3C, 0x02, -0x30, 0x09, 0xC0, 0x67, 0x02, 0x83, 0x00, 0x4C, 0x02, 0xB0, 0x28, 0xC0, 0x64, -0x01, 0x9E, 0x00, 0x78, 0x02, 0x30, 0x09, 0xC0, 0xA7, 0x40, 0x9B, 0x01, 0x7C, -0x42, 0xF0, 0x59, 0xC0, 0x20, 0x01, 0x93, 0x42, 0x7C, 0x82, 0xF0, 0x39, 0xC0, -0x27, 0x04, 0x97, 0x08, 0x6C, 0x16, 0x30, 0x89, 0xC0, 0x40, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, -0x09, 0xC0, 0xA7, 0x04, 0x91, 0x86, 0x0C, 0x02, 0xB0, 0x09, 0x40, 0x64, 0x00, -0x9D, 0x00, 0x7C, 0x02, 0x10, 0x09, 0x40, 0xE7, 0x00, 0x91, 0x01, 0x74, 0x02, -0xD0, 0x49, 0xC0, 0xE6, 0x04, 0x91, 0x20, 0x74, 0x0E, 0xD0, 0x29, 0x40, 0x23, -0x40, 0x9B, 0x41, 0x44, 0x46, 0x14, 0x39, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x09, -0x60, 0x27, 0x00, 0x91, 0x00, 0x65, 0x22, 0x94, 0x09, 0x58, 0x26, 0x00, 0x9D, -0x00, 0x36, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x02, 0xD0, -0x09, 0x60, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x67, 0x00, -0x95, 0x00, 0x04, 0x02, 0x12, 0x29, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x20, 0x81, 0x81, 0x05, 0x34, 0x12, 0x10, 0x08, 0x40, -0x21, 0x09, 0x81, 0x04, 0x44, 0x12, 0x90, 0x58, 0x40, 0x62, 0x01, 0x8D, 0x04, -0x14, 0x12, 0x10, 0x08, 0x40, 0x23, 0x01, 0xC1, 0x04, 0x34, 0x12, 0xD0, 0x09, -0x68, 0x22, 0x01, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x99, -0x00, 0x05, 0x22, 0x10, 0x48, 0x50, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1D, 0xB0, 0x86, 0x02, 0x11, 0x0A, 0x3C, 0x28, 0x30, 0xA1, 0x40, 0x87, -0x02, 0x13, 0x40, 0x6C, 0x00, 0xB4, 0xA1, 0xC8, 0x86, 0x02, 0x0F, 0x0A, 0x74, -0x28, 0x34, 0x01, 0x84, 0x97, 0x02, 0x1B, 0x0A, 0x7C, 0x00, 0xD0, 0xA1, 0xC0, -0x84, 0x42, 0x13, 0x40, 0x7C, 0x29, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, -0x4C, 0x08, 0x30, 0xA1, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0x98, 0x2F, 0x4A, 0xBF, 0x08, 0xFC, 0x22, 0xD4, 0x0B, 0xC0, 0x27, 0x62, -0xBF, 0x88, 0xBC, 0x22, 0xF4, 0x89, 0xC0, 0x2D, 0x02, 0xBF, 0x08, 0xFC, 0x22, -0xF0, 0x09, 0xC4, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x27, -0x02, 0xBF, 0x40, 0x7C, 0x22, 0xD0, 0x0A, 0xC0, 0x2F, 0x80, 0xBF, 0x00, 0xDE, -0x92, 0xF0, 0x8B, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x27, 0x01, 0xB3, 0x14, 0x7C, 0x32, 0x30, 0x09, 0xD0, 0x2C, 0x40, 0xA3, -0x00, 0x9C, 0x12, 0x30, 0x4B, 0xC1, 0x2C, 0x03, 0x9F, 0x25, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x2D, 0x01, 0xBF, 0x14, 0x4C, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x40, -0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAB, 0x00, 0x8C, 0x02, -0xF0, 0x0B, 0xC0, 0x76, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, -0x17, 0x0D, 0x11, 0x44, 0x74, 0xB0, 0x10, 0x00, 0x41, 0x04, 0x04, 0x11, 0x08, -0x44, 0x00, 0x90, 0x41, 0x40, 0x04, 0x03, 0x1D, 0x1A, 0x74, 0x40, 0xD0, 0x01, -0x40, 0x07, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01, 0x43, 0x07, 0x04, 0x11, -0x00, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x40, 0x45, 0x00, 0xD2, -0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, -0x03, 0x81, 0x34, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x02, 0x81, 0x00, 0x54, -0x27, 0x90, 0x48, 0x41, 0x20, 0x01, 0x8D, 0x04, 0x34, 0x22, 0xD0, 0x08, 0x40, -0x21, 0x03, 0x8D, 0xB4, 0x04, 0x82, 0x50, 0x48, 0x40, 0x23, 0x02, 0xC5, 0x00, -0x34, 0x32, 0xD0, 0x08, 0x40, 0x27, 0x80, 0x89, 0x00, 0x24, 0x82, 0xD0, 0x0C, -0x40, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x40, -0x91, 0x06, 0x74, 0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02, -0x90, 0x09, 0x50, 0x24, 0x01, 0x9D, 0x08, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, -0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0x95, 0x10, 0x74, -0x82, 0xD0, 0x8D, 0x44, 0x67, 0x88, 0x91, 0x08, 0x64, 0x82, 0xD0, 0x19, 0x40, -0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x93, -0x82, 0x7C, 0x1E, 0x31, 0x09, 0xC0, 0x24, 0x10, 0x93, 0x06, 0x5C, 0x0A, 0x34, -0x09, 0xC4, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x32, 0xF0, 0x09, 0xC0, 0x25, 0x00, -0x9F, 0x00, 0x4C, 0x1E, 0x70, 0xE9, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x74, 0x02, -0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x04, 0x6E, 0x26, 0xD2, 0x09, 0xC0, 0x16, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xE1, 0x00, 0x9F, 0x00, -0x7C, 0x16, 0xF6, 0x99, 0xC0, 0x23, 0x28, 0x9F, 0x20, 0x7C, 0x12, 0x70, 0x09, -0xC5, 0x27, 0x0C, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0xA0, 0x8F, -0x00, 0x7D, 0x12, 0xF0, 0x19, 0xC3, 0x27, 0x00, 0x9B, 0x02, 0x7C, 0x42, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5E, 0x06, 0xF2, 0x08, 0xC0, 0x59, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x7C, -0x00, 0x30, 0x01, 0xC0, 0x06, 0x01, 0x1F, 0x02, 0x6C, 0x00, 0xB0, 0x00, 0xC0, -0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x04, 0x13, 0x00, -0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x06, 0x41, 0x13, 0x00, 0x4C, 0x00, 0x31, 0x01, -0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0x70, 0x01, 0xC1, 0x50, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x7D, 0x02, 0x74, 0x01, -0x12, 0x05, 0xC0, 0x9C, 0x04, 0x6D, 0x21, 0x04, 0x81, 0x10, 0x57, 0x40, 0x5F, -0x01, 0x5D, 0x80, 0x74, 0x01, 0xD0, 0x05, 0x42, 0x1F, 0x20, 0x71, 0x08, 0x74, -0x01, 0xD0, 0x57, 0xC0, 0x1C, 0x01, 0x71, 0x00, 0xC4, 0x05, 0x10, 0x27, 0xC1, -0x9D, 0x04, 0x41, 0x05, 0xC4, 0xAD, 0x10, 0x07, 0x50, 0x40, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x13, 0x74, 0x03, 0x10, -0x0D, 0x42, 0x30, 0x10, 0xCD, 0x04, 0x24, 0x02, 0x90, 0x3C, 0x40, 0x73, 0x00, -0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0xF3, 0x00, 0xC1, 0x00, 0x34, 0x03, -0xD0, 0x0C, 0x40, 0x34, 0x80, 0x49, 0x50, 0x05, 0x07, 0x10, 0x18, 0x40, 0xD3, -0x01, 0xC5, 0x01, 0x04, 0x07, 0x50, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x88, 0x38, 0x02, 0xED, 0x02, 0x34, 0x03, 0x14, 0x4E, -0x40, 0x38, 0x00, 0xED, 0x02, 0xC4, 0x03, 0x10, 0x0E, 0x42, 0x3B, 0x08, 0xED, -0x0C, 0xB6, 0x03, 0xD0, 0x0E, 0x40, 0xF3, 0x00, 0xE1, 0x10, 0xB4, 0x03, 0xD0, -0x1E, 0x40, 0x38, 0x80, 0x69, 0x01, 0x84, 0x45, 0x12, 0x0A, 0x40, 0x19, 0x00, -0xB1, 0x00, 0xC4, 0x45, 0x10, 0x0A, 0x42, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x47, 0x30, 0x5E, 0xC2, -0x78, 0x10, 0x6F, 0x01, 0xAC, 0x07, 0xB0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, -0xB4, 0x17, 0xF0, 0x1E, 0x80, 0x7B, 0x40, 0xE3, 0x01, 0xB4, 0x07, 0xF0, 0x17, -0xD0, 0x70, 0x00, 0xEB, 0x01, 0xCC, 0x07, 0x34, 0x1A, 0xC0, 0x5B, 0x00, 0xE7, -0x01, 0x8C, 0x07, 0x70, 0x17, 0xC0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA8, 0x35, 0x04, 0xDF, 0x00, 0x7C, 0x33, 0xF0, 0x8D, 0xD0, 0x15, -0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x37, 0x10, 0xDF, 0x06, 0x7C, -0x53, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0xF0, 0x05, 0xC0, -0x35, 0x00, 0xC7, 0x00, 0x7C, 0x01, 0xF0, 0x09, 0xC4, 0x13, 0x00, 0x97, 0x00, -0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xA0, 0x7F, 0x00, 0x7F, 0x21, 0xCC, 0x07, 0xF8, 0xAE, 0xC0, 0x5F, 0x08, -0xEF, 0x01, 0xCC, 0x07, 0x70, 0x9F, 0xC4, 0x5C, 0x02, 0xF3, 0x0B, 0xCC, 0x47, -0x31, 0x1F, 0x40, 0x5F, 0x20, 0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, -0x00, 0xFF, 0x01, 0xFC, 0x07, 0x31, 0x9B, 0xC0, 0x7F, 0x00, 0xEF, 0x01, 0xCF, -0x36, 0x30, 0xDF, 0xD0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x88, 0x39, 0x00, 0x7D, 0x10, 0x84, 0x23, 0xD8, 0x4E, 0x04, 0xB8, 0x00, 0xAD, -0x04, 0x81, 0x03, 0x10, 0xAF, 0x40, 0x1C, 0x02, 0xF1, 0x20, 0xD5, 0x03, 0x14, -0x0E, 0x40, 0x1A, 0x01, 0x6D, 0x08, 0x85, 0x03, 0xD0, 0x8E, 0x00, 0x39, 0x02, -0xED, 0x00, 0xA4, 0x11, 0x10, 0x8A, 0x40, 0xBB, 0x01, 0xED, 0x04, 0xDC, 0x20, -0x10, 0xCA, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x39, 0x00, 0x6D, 0x00, 0x85, 0x03, 0xD0, 0x8F, 0x40, 0x19, 0x00, 0x6D, 0x40, -0xC0, 0x03, 0x50, 0x0E, 0x42, 0x18, 0x64, 0xE1, 0x00, 0x80, 0x43, 0x10, 0x0E, -0x40, 0x3A, 0x08, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x07, 0x40, 0x18, 0x00, 0xED, -0x00, 0x34, 0x03, 0x12, 0x0A, 0x48, 0x3B, 0x24, 0xFD, 0x20, 0x84, 0x52, 0x12, -0xCA, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x73, -0x12, 0x0D, 0x02, 0x04, 0x4B, 0xD0, 0x2C, 0x40, 0x04, 0x00, 0x0D, 0x08, 0x04, -0x6F, 0x10, 0x08, 0x40, 0x40, 0x00, 0xC1, 0x40, 0x04, 0x0F, 0x10, 0x0C, 0x40, -0x22, 0x00, 0x0D, 0x00, 0x04, 0x0F, 0xD2, 0x00, 0x40, 0x21, 0x00, 0xCD, 0x85, -0x24, 0x00, 0x10, 0x08, 0x40, 0x73, 0x11, 0xCD, 0x00, 0x14, 0x04, 0x10, 0x38, -0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x00, -0x9F, 0x00, 0xCC, 0x1F, 0xD0, 0x2F, 0x80, 0x25, 0x00, 0x8F, 0x20, 0x4C, 0x0F, -0x74, 0x01, 0xD2, 0xE4, 0x00, 0xF3, 0x00, 0xC4, 0x07, 0x30, 0x0D, 0xC0, 0x26, -0x00, 0x9F, 0x00, 0x4C, 0x0B, 0xF0, 0x39, 0xC1, 0x04, 0x00, 0x4F, 0x47, 0x74, -0x02, 0x34, 0x09, 0xC0, 0xF3, 0x00, 0xDF, 0x00, 0x44, 0x07, 0x34, 0x21, 0x80, -0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x21, 0x9F, -0x10, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xA5, 0x00, 0x9F, 0x10, 0x7D, 0x03, 0xF0, -0x09, 0xC0, 0xA7, 0x04, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x86, 0x00, -0x9F, 0x02, 0x7C, 0x23, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x5F, 0x40, 0x6C, 0x02, -0xF0, 0x29, 0xC0, 0xB7, 0x00, 0x9F, 0x90, 0x5C, 0x09, 0xF0, 0xC9, 0xC0, 0x37, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x80, 0x3F, 0x00, -0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x2F, 0x00, 0x33, 0x89, 0xCC, 0x07, 0x10, 0x03, -0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xF4, 0x43, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF, -0x00, 0xFC, 0x43, 0xC0, 0x0B, 0xC0, 0x2C, 0x00, 0xFF, 0x00, 0xDC, 0x02, 0xF0, -0x0B, 0xC0, 0x3F, 0x00, 0xB7, 0x00, 0xFC, 0x07, 0x34, 0x01, 0xC8, 0x07, 0x24, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x80, 0x9D, 0x07, 0x74, -0x83, 0xD0, 0x0D, 0x42, 0xE7, 0x20, 0x11, 0x87, 0x04, 0x07, 0xB0, 0x31, 0x40, -0xE7, 0x00, 0xDD, 0x20, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x46, 0x00, 0x99, 0x01, -0x74, 0x83, 0x91, 0x30, 0x40, 0xE5, 0x00, 0xDD, 0x01, 0x44, 0x06, 0xD0, 0x39, -0x40, 0x77, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x31, 0x44, 0x87, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x20, 0x9D, 0x01, 0x74, 0x03, -0xD0, 0x0D, 0x64, 0x47, 0x40, 0x91, 0x00, 0x44, 0x23, 0x50, 0x11, 0x40, 0x67, -0x04, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xC7, 0x00, 0x1D, 0x03, 0x74, -0x03, 0xD0, 0x19, 0x40, 0x47, 0x00, 0x9D, 0x01, 0x54, 0xC4, 0xD0, 0x1D, 0x40, -0x77, 0x00, 0xD5, 0x01, 0x34, 0x1A, 0x10, 0x31, 0x40, 0x07, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, -0x0C, 0x60, 0x23, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD4, 0x08, 0x40, 0x23, 0x20, -0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x09, 0x00, 0x34, 0x03, -0x90, 0x09, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x33, -0x00, 0xC1, 0x00, 0x34, 0x01, 0x10, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x3E, 0x00, 0x1D, 0x00, 0xFC, 0x03, 0xF0, 0x0F, -0xC0, 0x07, 0x08, 0x93, 0x00, 0x4D, 0x03, 0x70, 0x01, 0xC0, 0x07, 0x00, 0xFF, -0x00, 0xFC, 0x03, 0xF0, 0x0D, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, -0x09, 0xD0, 0x06, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, -0x97, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x60, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x2F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xA0, 0x0B, 0xC0, 0x2F, 0x00, 0xFE, 0x00, -0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0E, 0x00, 0xBA, 0x00, 0xFC, 0x03, 0xB0, 0x0A, -0xC0, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC2, 0x2F, 0x00, 0xBF, -0x00, 0xFC, 0x00, 0xF2, 0x0B, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA0, 0x2F, 0x40, 0x23, 0x10, 0xCD, 0x00, 0x30, 0x03, 0xC0, 0x4C, -0x40, 0x33, 0x81, 0xCC, 0x24, 0x30, 0x13, 0xD0, 0x2C, 0x05, 0xF3, 0x09, 0xDC, -0x00, 0x30, 0x4E, 0xC0, 0x2C, 0x00, 0x3F, 0x01, 0xCD, 0x04, 0xF1, 0x13, 0xC0, -0x4C, 0x08, 0x33, 0x01, 0xFC, 0x04, 0xB0, 0x13, 0xD4, 0x4C, 0x40, 0xF3, 0x00, -0xCD, 0x07, 0xF0, 0x4F, 0xC1, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x27, 0x00, 0x51, 0x92, 0x04, 0x08, 0x13, 0x09, 0x40, 0x04, 0x05, -0x11, 0x10, 0x44, 0x01, 0x10, 0x01, 0x41, 0xA4, 0x05, 0xC1, 0x04, 0x44, 0x2C, -0x10, 0x3F, 0xC0, 0x64, 0x02, 0x1D, 0x00, 0x64, 0x04, 0xD0, 0x05, 0xC0, 0x04, -0x20, 0x11, 0x01, 0x74, 0x04, 0x10, 0x01, 0x60, 0x04, 0x00, 0xC1, 0x00, 0x44, -0x07, 0xD1, 0x2D, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, -0xA0, 0x27, 0x00, 0x01, 0x05, 0x06, 0x0C, 0x10, 0x00, 0x40, 0x20, 0x01, 0x81, -0x00, 0x14, 0x02, 0x10, 0x48, 0x48, 0x21, 0x00, 0x81, 0x04, 0x34, 0x00, 0xD4, -0x8C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x01, 0xD0, 0x00, 0x42, 0x46, 0x20, -0x0D, 0x01, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC9, 0x00, 0x24, 0x03, -0xD0, 0x0C, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, -0x25, 0x02, 0x51, 0x44, 0x14, 0x04, 0x14, 0x1D, 0x40, 0x20, 0x00, 0x80, 0x00, -0x55, 0x03, 0x14, 0x09, 0x40, 0x64, 0x00, 0x51, 0x00, 0x64, 0x0C, 0xC0, 0x1D, -0x44, 0x76, 0x04, 0x8D, 0x00, 0x74, 0x89, 0xD0, 0x05, 0x50, 0x04, 0x00, 0x15, -0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0, -0x1C, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x43, -0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x31, 0xC2, 0x04, 0x00, 0x13, 0x01, 0x5C, -0x00, 0x30, 0x11, 0xC0, 0xE4, 0x04, 0xD3, 0x04, 0x7C, 0x0C, 0xF0, 0x35, 0xC0, -0xE4, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x12, 0x00, 0x57, 0x00, -0x3C, 0x01, 0xB0, 0x01, 0x40, 0x04, 0x00, 0xDB, 0x00, 0x4C, 0x03, 0xF0, 0x1D, -0xC0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x4D, 0x00, -0x7F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x12, 0x3F, 0x09, 0xEC, 0x01, -0xF0, 0x93, 0x80, 0x2F, 0x50, 0xFF, 0x00, 0x5C, 0x00, 0x30, 0x06, 0xC0, 0x25, -0x00, 0x3F, 0x08, 0xCC, 0x00, 0xF2, 0x07, 0xC4, 0x1F, 0x00, 0x7B, 0x00, 0xFC, -0x81, 0xF0, 0x83, 0xC0, 0x0F, 0x02, 0xE7, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xD4, -0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x40, 0x33, -0x00, 0x4C, 0x00, 0x32, 0x31, 0xC0, 0x64, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, -0x09, 0xC0, 0x24, 0x00, 0x53, 0x04, 0x6C, 0x88, 0xB0, 0x2D, 0xC0, 0x34, 0x11, -0x97, 0x05, 0x7C, 0x01, 0x30, 0x41, 0xC0, 0x17, 0x02, 0x5B, 0x10, 0x4C, 0x03, -0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x04, 0x4C, 0x03, 0xF0, 0x15, 0xC0, 0x08, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x20, 0x41, 0x01, -0x44, 0x14, 0x10, 0xBD, 0x40, 0x64, 0x00, 0x9D, 0x0B, 0x44, 0x2F, 0xD0, 0xA8, -0xC2, 0x26, 0x00, 0xD1, 0x82, 0x04, 0x00, 0x10, 0xAD, 0x40, 0xB4, 0x00, 0x91, -0x03, 0x70, 0x09, 0x11, 0x35, 0x40, 0x97, 0x02, 0x51, 0x13, 0x44, 0x43, 0x10, -0xB9, 0x40, 0x64, 0x00, 0x9D, 0x02, 0x45, 0x13, 0xD0, 0x15, 0x40, 0x6C, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x20, 0x02, 0x01, 0x1A, 0x20, -0x00, 0x14, 0x21, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x60, 0x2C, 0xD0, 0x14, 0x40, -0x34, 0x40, 0xD1, 0x02, 0x24, 0x00, 0xD0, 0x2C, 0x40, 0x00, 0x20, 0x45, 0x02, -0x30, 0x62, 0x10, 0x19, 0x40, 0x21, 0x00, 0x80, 0x41, 0x04, 0x04, 0x10, 0x04, -0x40, 0x10, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x08, 0x40, 0x1C, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00, 0x31, 0x01, 0xA5, 0x04, -0x10, 0x1B, 0x40, 0x58, 0x00, 0x6D, 0x01, 0xA4, 0x05, 0xD0, 0x16, 0x40, 0x6A, -0x00, 0xE1, 0x01, 0x84, 0x24, 0x50, 0x9E, 0x40, 0x58, 0x00, 0x61, 0x01, 0xB6, -0x06, 0x10, 0x1E, 0x40, 0x6F, 0x00, 0xB1, 0x81, 0xC4, 0x04, 0x10, 0x16, 0x40, -0x58, 0x00, 0xED, 0x09, 0x84, 0x07, 0xD0, 0x2F, 0x40, 0x74, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x24, 0x01, 0x03, 0x08, 0x24, 0x00, 0x30, -0x64, 0xC0, 0x30, 0x00, 0xDF, 0x00, 0x2C, 0x02, 0xF0, 0x0C, 0xC1, 0x14, 0x20, -0x83, 0x00, 0x2C, 0x20, 0xF2, 0x08, 0xD0, 0x10, 0x00, 0xC7, 0x00, 0x3C, 0x03, -0x30, 0x48, 0xC1, 0x23, 0x10, 0x83, 0x00, 0x0C, 0x02, 0x32, 0x0D, 0xD0, 0x30, -0x00, 0x8F, 0x00, 0x0D, 0x03, 0xF0, 0x8C, 0xC8, 0x48, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x0E, -0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xDD, 0x03, 0xF2, 0x8E, 0xC4, 0x2F, 0x20, 0xFF, -0x00, 0xFC, 0x20, 0xB0, 0x0F, 0xC2, 0x1F, 0x02, 0xFF, 0x08, 0xBC, 0x23, 0xF0, -0x0F, 0xC0, 0x2B, 0x00, 0xA7, 0x00, 0xBC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, -0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x4E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0xA0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x34, 0x05, 0xC0, -0x14, 0x00, 0x5F, 0x01, 0x4C, 0x00, 0xF0, 0x05, 0xC0, 0x34, 0x00, 0xCF, 0x00, -0x4C, 0x04, 0x30, 0x4C, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xD0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0xDF, -0x00, 0x0D, 0x03, 0x30, 0x0C, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x80, 0x0D, 0x10, 0x21, 0x00, 0xF4, 0x02, 0x10, 0x0E, 0x40, 0x18, -0x30, 0x6D, 0x00, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x28, 0x00, 0xED, 0x00, 0xAC, -0x00, 0x90, 0x0E, 0x43, 0x38, 0x48, 0x61, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x42, -0x38, 0x00, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x1B, 0x00, 0xFD, 0x00, -0x84, 0x03, 0x10, 0x0E, 0x60, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x79, 0x00, 0x21, 0x01, 0xB4, 0x04, 0x10, 0x1E, 0x40, 0x78, 0x00, -0xED, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xFD, 0x01, 0x04, 0x40, -0xD0, 0x1A, 0x40, 0x78, 0x00, 0xE9, 0x21, 0xB6, 0x07, 0xD0, 0x1A, 0x40, 0x78, -0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84, -0x07, 0x10, 0x17, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x28, 0x33, 0x02, 0x81, 0x00, 0x74, 0x27, 0x10, 0x7C, 0x40, 0x30, 0x00, 0xCD, -0x00, 0x44, 0x03, 0xD0, 0x0C, 0x62, 0x20, 0x01, 0xCD, 0x83, 0x24, 0x07, 0xD0, -0x2C, 0x40, 0x70, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x42, 0x34, 0x00, -0xC1, 0x40, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x09, 0x04, 0x03, -0x15, 0x04, 0x60, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, -0x19, 0x40, 0x73, 0x42, 0xFC, 0x05, 0x30, 0x57, 0xD0, 0x14, 0x00, 0x5F, 0x00, -0x4D, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x20, 0x7F, 0x05, 0xCC, 0x09, 0x74, 0x27, -0xC0, 0xDC, 0x03, 0x5B, 0x80, 0x3C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x00, 0x53, -0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x0C, 0x01, 0x30, -0x27, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85, -0x14, 0x0F, 0x24, 0x7C, 0x04, 0xF4, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x80, 0x7C, -0x00, 0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x10, 0x7C, 0x10, 0x30, 0x61, 0xD0, -0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xD1, 0x01, 0xC8, 0x07, 0x40, 0x1F, 0x00, -0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, -0x93, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0x30, 0x89, 0xC0, 0x24, 0x00, 0x93, 0x04, 0x0C, 0x0A, 0x30, 0x29, 0xC0, 0x22, -0x70, 0x93, 0x80, 0x7C, 0x06, 0x30, 0x09, 0xC0, 0x64, 0x02, 0x93, 0x05, 0x7C, -0x02, 0xF0, 0x49, 0xC0, 0x27, 0x02, 0x9F, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0, -0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x91, -0x28, 0x44, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, -0x39, 0x40, 0x24, 0x20, 0x81, 0x00, 0x6C, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00, -0x91, 0x02, 0x5C, 0x02, 0x10, 0x09, 0x40, 0xE4, 0x08, 0x91, 0x21, 0x74, 0x82, -0xD0, 0x29, 0x40, 0xE7, 0x00, 0x9D, 0x03, 0x45, 0x02, 0x14, 0x09, 0x40, 0x04, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x46, 0x91, 0x20, -0x44, 0x02, 0x12, 0x29, 0x40, 0x24, 0x01, 0xBD, 0x04, 0xF4, 0x02, 0x18, 0x0A, -0x40, 0x24, 0x00, 0x91, 0x80, 0x64, 0x02, 0x19, 0x0D, 0x40, 0x26, 0x00, 0x91, -0x00, 0xF4, 0x22, 0x1C, 0x0F, 0x40, 0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x06, 0xD0, -0x0B, 0x40, 0x2F, 0x00, 0x8D, 0x0A, 0x64, 0x02, 0x10, 0x18, 0x40, 0x62, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x24, 0x01, 0x81, 0x04, 0x04, -0x12, 0x10, 0x48, 0x50, 0x68, 0x00, 0xAD, 0x01, 0xB4, 0x02, 0x10, 0x1A, 0x42, -0x20, 0x01, 0x91, 0x00, 0x24, 0x12, 0x10, 0x48, 0x40, 0x32, 0x01, 0xA1, 0x01, -0xD4, 0x03, 0x10, 0x0A, 0x40, 0x28, 0x20, 0xA1, 0x01, 0xB4, 0x02, 0xD0, 0x1A, -0x40, 0x6B, 0x00, 0x8D, 0x04, 0x25, 0x02, 0x10, 0x58, 0x50, 0x42, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x53, 0x0A, 0x4D, 0x28, -0x34, 0xA0, 0x40, 0x84, 0x02, 0x0F, 0x0A, 0x7C, 0x29, 0x30, 0xA2, 0x40, 0x84, -0x02, 0x13, 0x0A, 0x6C, 0x00, 0x30, 0x05, 0xC0, 0x06, 0x00, 0x13, 0x0A, 0x7C, -0x00, 0x30, 0xA0, 0xD0, 0x80, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0, -0x8F, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA1, 0xC0, 0x76, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x02, 0xBF, 0x08, 0xFC, 0x22, 0xF0, -0x8B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x09, 0xD0, 0x2F, 0x42, -0xBF, 0x80, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x29, 0x82, 0x9F, 0x00, 0x5C, 0x02, -0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0xBF, 0x08, 0x5C, 0x02, 0xF0, 0x8B, 0xC0, 0x65, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xA3, 0x14, 0xFC, 0x32, 0xF0, 0x0B, -0xD0, 0x2C, 0x00, 0xB3, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x26, 0x19, 0xB3, -0x00, 0xCC, 0x06, 0x30, 0x1B, 0xC1, 0x6E, 0x04, 0xBF, 0x00, 0xFC, 0x02, 0x30, -0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x31, 0x0B, 0xC0, 0x2C, 0x02, -0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x8F, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x00, 0x17, 0x45, 0x11, 0x04, 0x74, 0x30, 0xD0, 0x20, 0x41, -0x14, 0x44, 0x51, 0x00, 0x74, 0x50, 0x10, 0x41, 0x50, 0x04, 0x02, 0x13, 0x00, -0x6C, 0x28, 0x14, 0x01, 0x40, 0x04, 0x00, 0x5D, 0x04, 0x74, 0x00, 0x10, 0x01, -0x41, 0x04, 0x04, 0x11, 0x00, 0x44, 0x00, 0x10, 0x45, 0x40, 0x14, 0x01, 0x1D, -0x12, 0x45, 0x00, 0xD0, 0x81, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x21, 0x43, 0x81, 0x14, 0x34, 0x12, 0xD0, 0xC8, 0x50, 0x20, -0x10, 0x81, 0x00, 0x74, 0x16, 0x14, 0x48, 0x41, 0x24, 0x00, 0x81, 0x00, 0x24, -0x02, 0x90, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x94, 0x74, 0x02, 0x98, 0x49, 0x40, -0x22, 0x00, 0x91, 0x00, 0x14, 0x02, 0x90, 0x48, 0x41, 0x22, 0x11, 0x8D, 0x0C, -0x04, 0x02, 0xD0, 0x18, 0x40, 0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x28, 0x25, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x49, 0x41, 0x20, 0x00, -0x91, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40, 0xA4, 0x00, 0x91, 0x00, 0x64, 0x62, -0x98, 0x19, 0x44, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x9C, 0x09, 0x50, 0x22, -0x00, 0x91, 0x00, 0x54, 0x02, 0x90, 0x08, 0x50, 0x26, 0x00, 0x9D, 0x08, 0x44, -0x02, 0xD0, 0x08, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x00, 0x25, 0x00, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x93, -0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x40, 0x93, 0x10, 0x6D, 0x0A, 0xB0, -0x79, 0xC0, 0x26, 0x10, 0x9F, 0x02, 0x3C, 0x02, 0xB0, 0x08, 0xC2, 0x26, 0x40, -0x83, 0x00, 0x5C, 0x42, 0xB4, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02, -0xF0, 0x19, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, -0xE5, 0x00, 0x9F, 0x10, 0x7C, 0xA6, 0xF0, 0x18, 0xD0, 0x27, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x25, 0x00, 0x97, 0x15, 0x7E, 0x06, 0x70, 0x09, -0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0x72, 0x09, 0xC1, 0x25, 0x00, 0x9F, -0x00, 0x6D, 0x02, 0x70, 0x09, 0xC0, 0x25, 0x04, 0x9F, 0x10, 0x7E, 0x02, 0xF0, -0x49, 0xD1, 0x5B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x81, -0x01, 0x13, 0x02, 0x4C, 0x20, 0x34, 0x81, 0xC0, 0x86, 0x44, 0x13, 0x12, 0x6D, -0x04, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x4C, 0x88, 0x30, 0x20, 0xC0, -0x04, 0x08, 0x1F, 0x02, 0x4D, 0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, -0x7C, 0x40, 0xF0, 0x21, 0xD0, 0x84, 0x40, 0x13, 0x08, 0x4C, 0x00, 0xF0, 0x01, -0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x1C, 0x00, -0x71, 0x82, 0x44, 0x05, 0x10, 0x17, 0xC0, 0x9C, 0x00, 0x71, 0x02, 0x84, 0x05, -0xD0, 0x16, 0x40, 0x10, 0x00, 0x7D, 0x00, 0x14, 0x01, 0x14, 0x37, 0x40, 0x9C, -0x00, 0x7D, 0x03, 0xC4, 0x11, 0xD0, 0x17, 0xC0, 0x1C, 0x00, 0x71, 0x00, 0xB0, -0x4D, 0xD0, 0x07, 0x40, 0x1C, 0x00, 0x71, 0x01, 0x45, 0x01, 0xD0, 0x17, 0x41, -0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0x81, -0x02, 0x24, 0x07, 0x10, 0x0C, 0x40, 0xB0, 0x00, 0xC1, 0x02, 0x04, 0x27, 0xD0, -0x08, 0x40, 0x30, 0x00, 0x5D, 0x00, 0x04, 0x03, 0x90, 0xB8, 0x51, 0xB0, 0x21, -0xCD, 0x05, 0x00, 0x07, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x13, 0x34, 0x0B, -0xD8, 0x0C, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02, 0xD0, 0x2C, 0x40, 0x50, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x28, 0x00, 0x31, 0x01, -0xA4, 0x06, 0x10, 0x06, 0x40, 0x38, 0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0E, -0x42, 0x38, 0x21, 0xED, 0x00, 0x94, 0x03, 0x90, 0x08, 0x40, 0x18, 0x04, 0xED, -0x03, 0x84, 0x01, 0xD1, 0x2F, 0x50, 0x38, 0x00, 0x21, 0x10, 0xB4, 0x03, 0xD0, -0x0E, 0x40, 0x78, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x08, 0x40, 0x14, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x5C, 0x02, 0x63, 0x01, 0xEC, -0x07, 0x30, 0x1E, 0xD1, 0x7C, 0x00, 0xF3, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xD0, -0xF8, 0x21, 0x3F, 0x01, 0x84, 0x07, 0xB0, 0x16, 0xC0, 0x78, 0x00, 0xFF, 0x21, -0x8C, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x40, 0x23, 0x01, 0xBC, 0x07, 0xF0, 0x1F, -0xC0, 0x7C, 0x00, 0x73, 0x01, 0x84, 0x06, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x9D, 0x00, 0x1F, 0x80, 0x5D, 0x12, -0xF0, 0x07, 0xC0, 0x35, 0x08, 0x5F, 0x00, 0x7C, 0x03, 0xF2, 0x00, 0xC0, 0x77, -0x00, 0x9F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, -0x03, 0xF0, 0x0C, 0xC0, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, -0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x23, 0x01, 0xCC, 0x3F, 0xF8, -0x8B, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xB0, 0x9B, 0xC0, 0x7F, 0x00, -0xE7, 0x01, 0x8C, 0x87, 0x24, 0x1E, 0xC0, 0x5D, 0x00, 0xF3, 0x01, 0xD4, 0x25, -0xB0, 0x1F, 0xD8, 0x7C, 0x00, 0x32, 0x01, 0xFC, 0x05, 0xF0, 0x1F, 0xC0, 0x7C, -0x00, 0x73, 0x01, 0xCC, 0x06, 0xF0, 0x17, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x00, 0x21, 0x82, 0x84, 0x62, 0x30, 0x47, -0x40, 0x3C, 0x00, 0xE1, 0x00, 0xBC, 0x02, 0x10, 0xCE, 0x40, 0x3B, 0x00, 0xEB, -0x00, 0xAC, 0x13, 0x30, 0x0E, 0x40, 0x98, 0x40, 0xE1, 0x08, 0x84, 0x01, 0x14, -0x4B, 0xC1, 0x3C, 0x00, 0x21, 0x08, 0xB4, 0x08, 0xD0, 0x2E, 0x40, 0x3C, 0x00, -0xE1, 0x00, 0x84, 0x02, 0xD0, 0x82, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x61, 0x00, 0x04, 0x13, 0x50, 0x8A, 0x50, -0x38, 0x00, 0xE9, 0x00, 0xF4, 0x03, 0x10, 0x0A, 0x60, 0x33, 0x00, 0xB5, 0x00, -0xA4, 0x83, 0x80, 0x0F, 0x50, 0x3B, 0x00, 0x61, 0x00, 0x94, 0x00, 0x94, 0x0E, -0x60, 0x38, 0x00, 0x29, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, -0x00, 0x84, 0x02, 0xD0, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x28, 0x51, 0x00, 0x01, 0x06, 0x05, 0x0A, 0x12, 0xB5, 0x41, 0x30, -0x00, 0xC9, 0x00, 0x34, 0x02, 0x10, 0x04, 0x60, 0xF3, 0x40, 0x89, 0x03, 0x24, -0x23, 0x10, 0x1C, 0x40, 0x32, 0x00, 0xD1, 0x00, 0x04, 0x01, 0x90, 0x08, 0x40, -0x30, 0x00, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xD1, 0x00, -0x05, 0x02, 0xD0, 0x18, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0x65, 0x40, 0x13, 0x07, 0x4C, 0x0E, 0x70, 0x09, 0xC0, 0x34, 0x00, -0xDB, 0x00, 0x7C, 0x03, 0xB0, 0x08, 0xC2, 0x3F, 0x20, 0x07, 0x0D, 0x0C, 0x0A, -0xB0, 0x5D, 0xC0, 0x73, 0x04, 0xD3, 0x00, 0x5C, 0x02, 0xB0, 0x0D, 0xC0, 0x34, -0x00, 0x0B, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x93, 0x05, 0x4C, -0x03, 0xF0, 0x0C, 0xC1, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x08, 0x27, 0x02, 0x3F, 0x00, 0x7C, 0x02, 0x70, 0x21, 0xC0, 0x27, 0x20, 0x97, -0x00, 0x5C, 0x07, 0xF0, 0x29, 0xC0, 0x37, 0x06, 0x97, 0x00, 0x7C, 0x42, 0xF0, -0x0D, 0xC0, 0x35, 0x20, 0x9F, 0x00, 0x7C, 0x00, 0x72, 0x25, 0xC0, 0xA5, 0x00, -0x13, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, -0x0F, 0x60, 0x73, 0x00, 0xAC, 0x42, 0xB0, 0x03, 0xC0, 0x1C, 0x00, 0xFF, 0x00, -0xFC, 0x03, 0x30, 0x4B, 0xC0, 0x3E, 0x00, 0x33, 0x05, 0xCC, 0x07, 0x30, 0x4F, -0x40, 0x37, 0x00, 0xF3, 0x00, 0xEC, 0x02, 0xE0, 0x3F, 0xC0, 0x1C, 0x00, 0x31, -0x00, 0xCC, 0x01, 0xF0, 0x07, 0x80, 0x5C, 0x00, 0x53, 0x00, 0xCC, 0x07, 0xF0, -0x3F, 0xE0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, -0x00, 0x11, 0x22, 0x44, 0x06, 0x10, 0x31, 0x40, 0x14, 0x00, 0x5D, 0x01, 0x34, -0x07, 0x10, 0x59, 0x42, 0x30, 0x40, 0x91, 0x40, 0x54, 0x03, 0x10, 0x7D, 0x40, -0xF7, 0x00, 0x9B, 0x01, 0x44, 0x06, 0xD0, 0x05, 0x50, 0x34, 0x00, 0x11, 0x07, -0x4C, 0x0C, 0xD0, 0x3D, 0x40, 0xD4, 0x02, 0xD1, 0x00, 0x44, 0x02, 0xD0, 0x39, -0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC2, 0x00, -0x01, 0x00, 0x64, 0x13, 0x90, 0x19, 0x41, 0x76, 0x00, 0xDD, 0x88, 0x74, 0x07, -0x14, 0x09, 0x48, 0x34, 0x00, 0x99, 0x40, 0x46, 0x12, 0x10, 0x0D, 0x48, 0x67, -0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x2C, 0x40, 0xB2, 0x01, 0x15, 0x01, 0x64, -0x05, 0xD0, 0x8D, 0x40, 0x31, 0x04, 0x51, 0x00, 0x44, 0x13, 0xD0, 0x2D, 0x40, -0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x01, -0x00, 0x04, 0x02, 0x10, 0x00, 0x50, 0x62, 0x00, 0x8D, 0x00, 0x34, 0x07, 0x14, -0x09, 0x42, 0x34, 0x00, 0x91, 0x00, 0x14, 0x02, 0x10, 0x0C, 0x60, 0x23, 0x40, -0xC9, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x22, 0x80, 0x05, 0x80, 0x04, 0x00, -0xD0, 0x08, 0x40, 0x21, 0x00, 0xC1, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x40, -0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0E, 0x00, 0x53, 0x00, -0xEC, 0x03, 0xB2, 0x03, 0xD0, 0x36, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0x14, 0x09, -0xD0, 0x36, 0x00, 0x92, 0x00, 0x4C, 0x03, 0x34, 0x0D, 0x40, 0x27, 0x10, 0x43, -0x00, 0x6C, 0x00, 0xF0, 0x0D, 0xD0, 0x16, 0x00, 0x17, 0x00, 0x6C, 0x01, 0xF0, -0x04, 0xD0, 0x35, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x00, 0xC0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0B, 0x00, 0x3F, 0x00, 0xFC, -0x02, 0xF1, 0x03, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF4, 0x0B, 0xC0, -0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, -0xB4, 0x00, 0xF0, 0x0F, 0xC0, 0x3D, 0x00, 0x3B, 0x00, 0xFC, 0x00, 0xF0, 0x0F, -0xC0, 0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x17, 0x60, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x02, -0xF0, 0x1F, 0xC8, 0x3F, 0x01, 0xBF, 0x22, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0xBF, -0x05, 0xEF, 0x09, 0xEC, 0x10, 0xB0, 0x3F, 0xC0, 0xBD, 0x00, 0xB3, 0x04, 0xCC, -0x82, 0x32, 0x2F, 0xC4, 0x2F, 0x40, 0xF2, 0x01, 0xCC, 0x13, 0xF0, 0x12, 0x44, -0x7A, 0x20, 0x33, 0xCC, 0xEC, 0x06, 0x90, 0x1F, 0x40, 0x0E, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x26, 0xD0, -0x1D, 0x40, 0xBF, 0x05, 0x1D, 0x02, 0x74, 0x38, 0x10, 0xC1, 0x40, 0xBF, 0x00, -0xDD, 0x00, 0x64, 0x2C, 0x04, 0x4D, 0x40, 0xBF, 0x08, 0x11, 0x14, 0x74, 0x40, -0x10, 0x6F, 0x40, 0xE7, 0x00, 0xD5, 0x01, 0xC4, 0x0F, 0xD0, 0x19, 0x40, 0x74, -0x00, 0x01, 0x22, 0x44, 0x06, 0x12, 0x1D, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xCD, 0x00, 0x34, 0x80, 0xD8, 0x0C, -0x40, 0xB3, 0x00, 0x8D, 0x26, 0x34, 0x02, 0x10, 0x00, 0x41, 0x33, 0x11, 0xCD, -0x80, 0x24, 0x02, 0x00, 0x0C, 0x40, 0x31, 0x83, 0x81, 0x8C, 0x04, 0xB2, 0x12, -0x2C, 0x60, 0x03, 0x42, 0xD5, 0x00, 0x14, 0x23, 0xD0, 0x08, 0x40, 0x33, 0x00, -0x45, 0x26, 0x64, 0x01, 0x90, 0x0C, 0x40, 0x4E, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x28, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x04, 0xD0, 0x0D, 0x44, -0x37, 0x00, 0x9D, 0x01, 0x74, 0x04, 0x10, 0x11, 0x44, 0x37, 0x00, 0xDD, 0x00, -0x66, 0x84, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91, 0x01, 0x74, 0x06, 0x18, 0x0D, -0x40, 0x47, 0x00, 0x55, 0x11, 0x54, 0x03, 0xD0, 0x19, 0x43, 0x37, 0x80, 0x11, -0x18, 0x44, 0x0E, 0x10, 0x0D, 0x42, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x20, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x1E, 0xF0, 0x0D, 0xC0, 0x37, -0x00, 0x9F, 0x87, 0x7C, 0xC4, 0x30, 0x19, 0xC2, 0x37, 0x18, 0xDF, 0x00, 0x6C, -0x04, 0x30, 0x0D, 0xC4, 0x35, 0x08, 0x13, 0x01, 0x4C, 0x1E, 0x34, 0x0D, 0xC2, -0x67, 0x40, 0xD7, 0x01, 0x5C, 0x03, 0xF0, 0x19, 0xC0, 0x37, 0x00, 0x95, 0x02, -0x2C, 0x0E, 0xB0, 0x0D, 0xC0, 0x22, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC0, 0x3F, 0x90, -0x3F, 0x90, 0xBC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x03, 0x9C, 0x40, -0x70, 0x0F, 0xC0, 0x37, 0x40, 0x3F, 0x40, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2F, -0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x0B, 0xC0, 0x3C, 0x0C, 0x2F, 0x01, 0xFC, -0x02, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x93, -0x02, 0x7C, 0x0A, 0x30, 0x01, 0xC0, 0x34, 0x40, 0xD3, 0x04, 0x4E, 0x02, 0xF1, -0x0D, 0xC0, 0x30, 0x00, 0x13, 0x08, 0x7C, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00, -0xD3, 0x22, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0x34, 0x00, 0x13, 0x02, 0x4C, 0x0D, -0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, -0x34, 0x00, 0xDD, 0x00, 0x74, 0x12, 0xD1, 0x0D, 0x00, 0x3F, 0x00, 0x91, 0x80, -0x74, 0x00, 0x10, 0x01, 0x40, 0x3C, 0x24, 0xDB, 0x02, 0x66, 0x4A, 0xD0, 0x0D, -0x48, 0xBC, 0x42, 0x1B, 0x8B, 0x74, 0x02, 0xF0, 0x3F, 0xC1, 0x62, 0x01, 0x8A, -0x04, 0xF0, 0x03, 0xB1, 0xA8, 0x40, 0x30, 0x00, 0x1B, 0x0E, 0x44, 0x0F, 0xD0, -0x0C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, -0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x34, -0x02, 0x10, 0x08, 0x40, 0xF0, 0x09, 0xD1, 0x81, 0x24, 0x0E, 0xD0, 0x0C, 0x48, -0x70, 0x00, 0x89, 0x03, 0x74, 0x00, 0xD0, 0x6C, 0x42, 0x02, 0x01, 0xC5, 0x30, -0x20, 0x07, 0x00, 0xBC, 0x40, 0x30, 0x00, 0x00, 0x00, 0x04, 0x03, 0xD0, 0x0C, -0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00, -0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x61, 0x11, 0xB4, 0x07, -0x10, 0x16, 0x40, 0x78, 0x00, 0xE1, 0x01, 0xA4, 0x25, 0xD0, 0x1E, 0x40, 0x78, -0x00, 0x61, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4, -0x07, 0x90, 0x0F, 0x40, 0x78, 0x04, 0xE9, 0x01, 0x84, 0x0E, 0xD0, 0x1E, 0x40, -0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, -0x00, 0x3C, 0x01, 0xD0, 0x8C, 0xC0, 0x37, 0x00, 0x43, 0x00, 0x7C, 0x03, 0x10, -0x8D, 0xD0, 0x34, 0x22, 0xC1, 0x90, 0x04, 0x2B, 0xD8, 0x0D, 0xD0, 0x30, 0x06, -0xC9, 0x00, 0x3C, 0x01, 0xD0, 0x4D, 0xC0, 0x12, 0x00, 0xC3, 0x04, 0x2C, 0x53, -0x30, 0x8C, 0x80, 0x30, 0x00, 0xC3, 0xE4, 0x0C, 0x83, 0xF0, 0x0C, 0xC0, 0x4B, -0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, -0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF4, 0x8F, -0xC0, 0x3F, 0x02, 0xFF, 0x00, 0x5D, 0xA1, 0xF8, 0x0F, 0xC0, 0xBF, 0x00, 0xFF, -0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1B, 0x02, 0xFB, 0x00, 0xB0, 0x4B, 0xF0, -0xCF, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x80, 0xDF, 0x00, 0x7C, -0x01, 0x70, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x05, 0x30, 0x0D, 0xC2, -0xB5, 0x02, 0xCF, 0x00, 0x5D, 0x03, 0x38, 0x1D, 0xC0, 0x35, 0x01, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x6D, 0xC0, 0x10, 0x00, 0xC3, 0x00, 0x6C, 0x13, 0xF0, 0x09, -0xC0, 0x37, 0xA0, 0xDF, 0x00, 0x4C, 0x03, 0xD0, 0x0C, 0xC0, 0x42, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03, -0xD0, 0x0E, 0x00, 0x3B, 0x13, 0x6C, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B, -0x04, 0xED, 0x00, 0x94, 0x03, 0x41, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, -0x01, 0xD0, 0x8F, 0xC0, 0x3A, 0x00, 0xE5, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x42, -0x3B, 0x80, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4C, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79, 0x88, 0xE5, 0x21, 0xB4, 0x47, 0xD0, -0x1E, 0x44, 0x7B, 0x12, 0xEC, 0x01, 0x34, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x01, -0xED, 0x21, 0x14, 0x07, 0x01, 0x1E, 0x4C, 0x79, 0x02, 0xED, 0x01, 0xB4, 0x07, -0xD8, 0x5F, 0x40, 0x78, 0x00, 0xF5, 0x11, 0xB4, 0x17, 0xD0, 0x3A, 0x40, 0x7B, -0x00, 0xED, 0x21, 0x84, 0x47, 0xD0, 0x1E, 0x48, 0x12, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x0F, 0xD0, 0x0C, -0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x10, 0x9C, 0x40, 0x33, 0x00, 0x8D, -0xA0, 0x15, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x10, 0xDD, 0x03, 0x34, 0x07, 0xD0, -0x0C, 0x40, 0xF2, 0x00, 0xC5, 0x01, 0x14, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x80, -0xDD, 0x0D, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x17, 0xA8, 0x15, 0x08, 0x5F, 0x00, 0xFC, 0x01, 0xF0, 0x05, 0xC0, -0x17, 0x00, 0x7F, 0x0E, 0xF4, 0x01, 0xB0, 0xA7, 0xC2, 0x15, 0x08, 0x4F, 0x05, -0xDC, 0x1D, 0x35, 0x05, 0xC4, 0x15, 0x00, 0x7F, 0x85, 0xFC, 0xED, 0xF0, 0x05, -0xC0, 0x1C, 0x81, 0x77, 0x01, 0x7C, 0x01, 0xF1, 0x06, 0xC0, 0x17, 0x08, 0x7D, -0x02, 0xCD, 0x05, 0xF0, 0x04, 0xC0, 0x5E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x02, 0x78, 0x04, 0x74, 0x01, 0x00, 0x07, 0x00, 0x1E, 0x00, 0x7D, -0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x06, 0x7C, 0x00, 0xC0, 0x00, 0xC0, -0x87, 0x81, 0x1F, 0x10, 0x64, 0x08, 0xF2, 0x21, 0xC1, 0x87, 0x20, 0x1F, 0x02, -0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x49, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xE0, 0x27, 0x00, -0x83, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x26, 0x02, 0x9F, 0x04, 0x0C, 0x02, -0x34, 0x09, 0xC0, 0x27, 0x01, 0x9C, 0x08, 0x0C, 0x02, 0x30, 0x59, 0xC0, 0xA0, -0x20, 0x93, 0x00, 0x5C, 0x86, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x00, 0x4C, -0x06, 0xF0, 0x09, 0xD0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x40, 0x27, 0x00, 0x91, -0x00, 0x45, 0x02, 0xD0, 0x09, 0xD0, 0xA4, 0x00, 0x9D, 0x02, 0x6C, 0x42, 0x50, -0x09, 0x40, 0x27, 0x21, 0x9D, 0x02, 0x45, 0x02, 0x14, 0x29, 0x50, 0xE4, 0x40, -0x81, 0x13, 0x44, 0x86, 0xD0, 0x89, 0x40, 0x64, 0x08, 0x9D, 0x02, 0x44, 0x1A, -0xD0, 0x19, 0x40, 0x04, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, -0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08, -0x44, 0x02, 0xD9, 0x0C, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x65, 0x22, 0x92, 0x09, -0x44, 0x27, 0x00, 0xDD, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x34, 0x04, 0x91, -0xA4, 0x54, 0x2A, 0xD1, 0x29, 0x50, 0xA6, 0x00, 0x9D, 0x0A, 0x64, 0x22, 0xD0, -0x89, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, -0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x40, 0x23, 0x31, 0x81, 0x04, 0x04, -0x12, 0xD8, 0x48, 0x4C, 0x20, 0x01, 0x8D, 0x01, 0x24, 0x12, 0x90, 0x08, 0x40, -0x23, 0x21, 0x8D, 0x24, 0x16, 0x12, 0x50, 0x4C, 0x04, 0x20, 0x01, 0x90, 0x20, -0x00, 0x12, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x08, 0x24, 0x02, 0xD0, 0x08, -0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, -0x1F, 0x00, 0x74, 0x00, 0x30, 0x01, 0x40, 0x87, 0x0A, 0x53, 0x0A, 0x4C, 0x28, -0xF0, 0xA1, 0xC2, 0x94, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA0, 0xC0, 0x87, -0x02, 0x1F, 0x0A, 0x5C, 0x28, 0x70, 0xA1, 0x80, 0x04, 0x10, 0x12, 0x00, 0x5C, -0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1D, 0x36, 0x6D, 0x00, 0xF0, 0x01, 0xC0, -0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, -0x00, 0xFC, 0x23, 0xF0, 0x09, 0xC0, 0x27, 0x42, 0xBF, 0x08, 0xFC, 0x22, 0xF0, -0x8B, 0x40, 0x27, 0x02, 0xBF, 0x20, 0xFD, 0x22, 0x70, 0x09, 0xC0, 0x27, 0x02, -0xBF, 0x08, 0xE8, 0x22, 0xB0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0x7C, 0x22, -0xF3, 0x0B, 0xC0, 0x25, 0x00, 0xBF, 0x04, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x77, -0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x20, -0xFC, 0x16, 0x30, 0x09, 0xC0, 0xE7, 0x20, 0xBF, 0x21, 0x6C, 0x13, 0xF0, 0xD9, -0xC6, 0xEF, 0x08, 0xB3, 0x02, 0xCC, 0x16, 0xF0, 0x09, 0xC0, 0x6F, 0x04, 0xB3, -0x07, 0x4C, 0x1E, 0xF0, 0x5B, 0xC0, 0x68, 0x00, 0xB3, 0x00, 0xFC, 0x12, 0x34, -0x0B, 0xC2, 0x2F, 0x20, 0xBF, 0x00, 0xC4, 0x02, 0xB4, 0x0B, 0xC0, 0x77, 0x80, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74, -0x28, 0x10, 0x01, 0x4C, 0x47, 0x08, 0x1C, 0x17, 0x45, 0x51, 0xD0, 0xF5, 0x40, -0xC7, 0x40, 0x11, 0x05, 0x54, 0x08, 0x70, 0x51, 0x41, 0x47, 0x40, 0x11, 0x03, -0x45, 0x0D, 0xD0, 0x71, 0x51, 0x84, 0x40, 0x15, 0x00, 0x74, 0x00, 0x11, 0x01, -0x40, 0x07, 0x00, 0x1D, 0x20, 0x44, 0x01, 0x10, 0x01, 0x40, 0x62, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03, -0x10, 0x08, 0x40, 0xA3, 0x01, 0x8D, 0x02, 0x04, 0xB2, 0xD0, 0x08, 0x40, 0xA3, -0x01, 0x81, 0x00, 0x25, 0x0E, 0xC1, 0x08, 0x40, 0x21, 0x04, 0x81, 0x07, 0x24, -0x32, 0x50, 0x88, 0x40, 0xA2, 0x20, 0x81, 0x40, 0x34, 0x22, 0x50, 0x08, 0x40, -0x23, 0x00, 0x8D, 0x00, 0x46, 0x03, 0xD1, 0x08, 0x40, 0x4B, 0x80, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x22, 0x10, -0x09, 0x40, 0x27, 0x00, 0x9D, 0x14, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x37, 0x00, -0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x80, 0x91, 0x40, 0x64, 0x12, -0xD8, 0x09, 0x60, 0x26, 0x01, 0x95, 0x02, 0x64, 0x02, 0x58, 0x0D, 0x40, 0x27, -0x00, 0xDD, 0x04, 0x44, 0x02, 0x50, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x0A, 0x34, 0x09, -0xC0, 0x27, 0x08, 0x9F, 0x42, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x27, 0x20, 0x91, -0x08, 0x6D, 0x0A, 0xF0, 0x09, 0xC0, 0x25, 0x20, 0x93, 0x00, 0x6C, 0x06, 0x70, -0x09, 0x42, 0xA6, 0xA1, 0x93, 0x22, 0x74, 0x02, 0x78, 0x09, 0xC1, 0x27, 0x00, -0x9F, 0x06, 0x4D, 0x02, 0xF4, 0x09, 0xC0, 0x17, 0x80, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x00, 0x25, 0x08, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x80, 0x7C, 0x22, 0xF0, 0x99, 0xC0, 0x27, 0x00, 0x9F, 0x11, -0x5C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x8F, 0x13, 0x5C, 0x06, 0xF0, 0x09, -0xC0, 0x65, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC1, 0x27, 0x00, 0x9F, -0x01, 0x7E, 0x22, 0xB4, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF8, 0x01, 0xC0, 0x07, -0x80, 0x13, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x47, 0x80, 0x1F, 0x00, 0x4C, -0x00, 0x70, 0x01, 0xC0, 0x47, 0x10, 0x1F, 0x00, 0x7C, 0x08, 0x34, 0x11, 0xC0, -0x87, 0x04, 0x13, 0x26, 0x2C, 0x10, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x04, -0x7C, 0x48, 0x30, 0x81, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x20, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0xC0, -0x70, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x00, 0x5F, 0x80, 0x6F, 0x46, 0xC5, 0x05, -0x70, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x81, 0x74, 0x01, 0x30, 0x47, 0x40, 0x1B, -0x00, 0x71, 0x03, 0xCC, 0x09, 0x60, 0x37, 0x40, 0x1C, 0xA0, 0x7D, 0x02, 0xB4, -0x09, 0x10, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x10, 0xD1, -0x03, 0x34, 0x03, 0xD2, 0x0C, 0x48, 0x77, 0x0A, 0xCD, 0x03, 0x04, 0x07, 0xD3, -0x0C, 0x44, 0x37, 0x00, 0xCD, 0x08, 0x36, 0x03, 0x10, 0x1D, 0x40, 0xB1, 0x60, -0x01, 0x02, 0x04, 0x23, 0xD0, 0x3C, 0x40, 0x81, 0x04, 0xDD, 0x80, 0x34, 0x0B, -0x04, 0x1C, 0x60, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, -0x38, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x02, -0xB6, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x80, 0x85, 0x08, 0x50, 0x0E, -0x60, 0x9B, 0x00, 0x6D, 0x40, 0x36, 0x07, 0x18, 0x0E, 0x40, 0x3B, 0x40, 0x21, -0x10, 0x86, 0x03, 0x50, 0x17, 0x49, 0x08, 0x00, 0xAD, 0x02, 0xB6, 0x03, 0x10, -0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, -0x00, 0xEF, 0x01, 0xBC, 0x06, 0xD0, 0x1E, 0xC2, 0x71, 0x02, 0x61, 0x01, 0xBC, -0x3F, 0xF0, 0xFE, 0xC0, 0x5B, 0x00, 0xED, 0x01, 0x8D, 0x05, 0x78, 0x3E, 0x41, -0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC2, 0x69, 0x00, 0x63, 0xA0, -0x8C, 0x07, 0xD1, 0x12, 0xC0, 0x49, 0x00, 0xED, 0x81, 0xBC, 0x06, 0x38, 0x1E, -0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0x5F, 0x00, 0x7C, 0x03, -0xC0, 0x0D, 0x40, 0x17, 0x00, 0xCF, 0x00, 0x7C, 0x00, 0xF1, 0x2D, 0xC0, 0x37, -0x20, 0x5F, 0x80, 0x7C, 0xB3, 0xC0, 0x0D, 0xC8, 0x27, 0x00, 0x4F, 0x00, 0x7C, -0x03, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x9D, 0x00, 0x3C, 0x00, 0xF1, 0x0D, 0xC8, -0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF, -0x01, 0xFC, 0x13, 0xF8, 0x8F, 0xC0, 0x7F, 0x04, 0xF7, 0x09, 0xCC, 0x87, 0xF0, -0x1F, 0xC0, 0x7C, 0x00, 0xEB, 0x01, 0xEC, 0x07, 0xF9, 0x9F, 0xC0, 0x7F, 0x00, -0xFF, 0x09, 0xCC, 0x0F, 0xB1, 0x1F, 0xC0, 0x3B, 0x00, 0x33, 0x01, 0xEE, 0x27, -0x30, 0x17, 0xC0, 0x4F, 0x00, 0x7F, 0x81, 0xCC, 0x05, 0xC0, 0x9A, 0xC0, 0x1A, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xED, 0x08, -0xB4, 0x23, 0xD0, 0x0E, 0x48, 0x3B, 0x01, 0xED, 0x00, 0x84, 0x03, 0xD1, 0x0E, -0x4E, 0x38, 0x40, 0xE1, 0x00, 0x84, 0x00, 0x78, 0x0E, 0x40, 0x1B, 0x08, 0xFD, -0x00, 0x84, 0x13, 0x10, 0x0E, 0x42, 0x3B, 0x03, 0xA1, 0x80, 0xBC, 0x03, 0x14, -0x06, 0x40, 0x0B, 0x08, 0x2D, 0x98, 0x84, 0x20, 0x90, 0x0A, 0x40, 0x54, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4, -0x0B, 0xD0, 0x8E, 0x40, 0x3B, 0x28, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x40, -0x1A, 0x00, 0xE1, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x44, 0x1B, 0x00, 0xED, 0x90, -0xA4, 0xC3, 0x18, 0x86, 0x40, 0xAB, 0x0A, 0x61, 0x08, 0xA4, 0x01, 0x54, 0x06, -0x40, 0x0B, 0x00, 0x6D, 0x00, 0x84, 0x40, 0xD0, 0x0E, 0x40, 0x22, 0x01, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, -0xD0, 0x0C, 0x00, 0x33, 0x10, 0x9D, 0x0B, 0x24, 0x2F, 0xD0, 0x1C, 0x5A, 0x02, -0x00, 0xC1, 0x40, 0x05, 0x01, 0x50, 0x0C, 0x40, 0x07, 0x00, 0x8D, 0x02, 0x24, -0x07, 0x1A, 0x08, 0x40, 0x63, 0xC0, 0x41, 0x00, 0x14, 0x01, 0x50, 0x24, 0x40, -0x13, 0x20, 0x0D, 0x03, 0x05, 0x0C, 0x90, 0x0C, 0x40, 0x08, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x42, 0xD0, -0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00, 0xEC, 0x03, 0xF0, 0x1F, 0xC0, 0x26, 0x00, -0xC1, 0x00, 0x4C, 0x23, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0xEC, 0x0F, -0x14, 0x01, 0xE2, 0x77, 0x04, 0x13, 0x02, 0x64, 0x03, 0x50, 0xA5, 0x40, 0x07, -0x00, 0xDF, 0x03, 0x4C, 0x0F, 0xD0, 0x0D, 0xC2, 0x56, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF1, 0x0D, -0x40, 0x37, 0x20, 0x9F, 0x10, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0xA1, 0x10, 0x97, -0x01, 0x7D, 0x00, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x5C, 0x43, 0x72, -0x21, 0xE0, 0xA7, 0x80, 0x1F, 0x28, 0x74, 0x03, 0xA0, 0x05, 0xC0, 0x07, 0x00, -0x9D, 0x04, 0x7C, 0x0B, 0xB0, 0x0D, 0xC0, 0xB7, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x20, 0xFC, 0x02, 0xB0, 0x0F, 0xE0, -0x3B, 0xA0, 0x1B, 0x00, 0xCE, 0x43, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xFB, 0x00, -0xAC, 0x01, 0xB0, 0x0F, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0xCC, 0x03, 0xF0, 0x0A, -0xC0, 0x28, 0x10, 0x73, 0x59, 0x8C, 0x03, 0x32, 0x47, 0xC0, 0x0C, 0x00, 0xED, -0x02, 0xCC, 0x47, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x37, -0x98, 0x11, 0x01, 0x44, 0x03, 0x10, 0x0D, 0x42, 0x64, 0x08, 0xD1, 0x01, 0x6C, -0x04, 0xB0, 0x0D, 0xC2, 0xE7, 0x04, 0x11, 0x01, 0x44, 0x03, 0xD0, 0x39, 0x44, -0x64, 0x01, 0x41, 0x01, 0x6C, 0x07, 0x10, 0x24, 0x40, 0x84, 0x02, 0x1D, 0x00, -0x05, 0x01, 0x10, 0x0D, 0x4E, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x48, 0x37, 0x20, -0x11, 0x01, 0x04, 0x03, 0x10, 0x0D, 0x60, 0x44, 0x00, 0xD1, 0x11, 0x64, 0x07, -0x92, 0x0D, 0x42, 0x67, 0x80, 0x11, 0x01, 0x64, 0x83, 0x50, 0x11, 0x41, 0x56, -0x00, 0x19, 0x00, 0x46, 0x07, 0x10, 0x05, 0x40, 0x04, 0x04, 0x5D, 0x00, 0x44, -0x1B, 0x14, 0x09, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0x81, -0x01, 0x04, 0x03, 0x14, 0x0C, 0x60, 0x20, 0x20, 0xC1, 0x00, 0x24, 0x00, 0x92, -0x0C, 0x60, 0x01, 0x90, 0x01, 0x01, 0x24, 0x03, 0xD0, 0x00, 0x42, 0x22, 0x00, -0xCD, 0x00, 0x24, 0x03, 0x14, 0x04, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x04, 0x02, -0x10, 0x08, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0x40, 0x3F, 0x00, 0x11, 0x20, -0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0xDB, 0x00, 0x6D, 0x01, 0xB1, 0x0F, -0x40, 0x27, 0x18, 0x93, 0x00, 0xAC, 0x03, 0x70, 0x01, 0xC0, 0x26, 0x00, 0x5B, -0x00, 0x4C, 0x01, 0x30, 0x05, 0xE0, 0x04, 0x00, 0x0F, 0x00, 0x4C, 0x03, 0x30, -0x0D, 0xC2, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F, -0x00, 0xFF, 0x00, 0xFC, 0x03, 0x78, 0x0F, 0xC0, 0x3F, 0x10, 0xB7, 0x00, 0xFC, -0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0x7F, 0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0, -0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0x73, 0x00, -0xBC, 0x00, 0xF0, 0x07, 0x00, 0x0F, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, -0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00, -0x33, 0x00, 0xCC, 0x03, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0x8C, 0x06, -0xB0, 0x03, 0xC0, 0x68, 0x02, 0x3F, 0x01, 0x8C, 0x04, 0x70, 0x1B, 0xC0, 0x3F, -0x00, 0x33, 0x0C, 0xCC, 0x04, 0xB0, 0x2B, 0x10, 0x4C, 0x00, 0xF3, 0x01, 0xCC, -0x02, 0x30, 0x0B, 0xD0, 0x4C, 0x00, 0xB3, 0x00, 0xCC, 0x07, 0xF0, 0x0F, 0xC0, -0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x14, 0x11, -0x00, 0xC4, 0x03, 0x11, 0x49, 0x40, 0x6F, 0x00, 0x91, 0x0B, 0x44, 0x84, 0x50, -0x01, 0x40, 0x24, 0x21, 0x1D, 0x21, 0x44, 0x84, 0x10, 0x19, 0x40, 0x3F, 0x04, -0x11, 0x02, 0x44, 0x04, 0x10, 0x2F, 0x42, 0x24, 0x10, 0xD1, 0x20, 0x44, 0x02, -0x10, 0x0C, 0x41, 0x44, 0x00, 0x8B, 0x00, 0x54, 0x07, 0xD0, 0x1D, 0x40, 0x0C, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x21, 0x00, 0x00, -0x04, 0x03, 0x10, 0x08, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x00, -0x40, 0x20, 0x10, 0x1D, 0x00, 0x05, 0x00, 0x52, 0x08, 0x42, 0x33, 0x82, 0x81, -0x02, 0x04, 0x00, 0x12, 0x68, 0x60, 0x00, 0x00, 0xD1, 0x40, 0x04, 0x06, 0x50, -0x58, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x4E, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x08, 0x51, 0x01, 0x44, -0x03, 0x10, 0x09, 0x40, 0x67, 0x40, 0xD1, 0x00, 0x45, 0x00, 0x50, 0x11, 0x50, -0x34, 0x00, 0x1D, 0x01, 0x44, 0x44, 0x11, 0x19, 0x41, 0x37, 0x00, 0x91, 0x00, -0x40, 0x04, 0x18, 0x0C, 0x60, 0x40, 0x40, 0xD1, 0x04, 0x44, 0x06, 0x50, 0x41, -0x40, 0x44, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x0E, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x73, 0x00, 0x13, 0x13, 0x4D, 0x03, -0x34, 0x01, 0xC0, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x39, 0xC8, 0x24, -0x10, 0x0F, 0x03, 0x4C, 0x0C, 0x70, 0x19, 0xC8, 0x37, 0x40, 0x13, 0x04, 0x4C, -0x18, 0x34, 0x09, 0xC0, 0xE4, 0x00, 0xC3, 0x00, 0x4D, 0x06, 0x70, 0x1D, 0xC0, -0xC4, 0x00, 0x93, 0x01, 0x6C, 0x03, 0xF0, 0x4D, 0xD0, 0x02, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0xFD, 0x40, 0x2F, 0x00, 0xBC, 0x03, 0xF1, -0x93, 0xC0, 0x37, 0x00, 0xAF, 0x02, 0xFC, 0x02, 0x70, 0x0D, 0xC0, 0x2F, 0x00, -0x3F, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC8, 0x3F, 0x20, 0x3F, 0x23, 0xFC, 0x00, -0x70, 0x9D, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB4, 0x1F, 0xC0, 0x0F, -0x00, 0xAF, 0x09, 0xDC, 0x03, 0xF0, 0x01, 0xC0, 0x1D, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x53, 0x00, 0x6D, 0x03, 0x32, 0x09, -0xD0, 0x24, 0x00, 0xD3, 0x80, 0x4C, 0x03, 0x34, 0x6D, 0xC0, 0x24, 0x00, 0x13, -0x42, 0x7C, 0x10, 0x30, 0x29, 0xD1, 0x30, 0x00, 0x83, 0x00, 0x4C, 0x18, 0x30, -0x09, 0xC0, 0x84, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xB0, 0x11, 0xC0, 0x04, 0x00, -0xDB, 0x00, 0x4D, 0x03, 0xF0, 0x0C, 0xC0, 0xA8, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0xC4, 0x43, 0x10, 0x09, 0x40, -0x10, 0x00, 0xD1, 0x00, 0x04, 0x46, 0x10, 0x2D, 0x50, 0x34, 0x00, 0x13, 0x82, -0x34, 0x08, 0x10, 0x79, 0x40, 0x7C, 0x04, 0xB5, 0x20, 0x2C, 0x0C, 0xB2, 0xAD, -0x40, 0xC4, 0x06, 0xD1, 0x01, 0x74, 0x2A, 0x10, 0x08, 0x40, 0x40, 0x00, 0xDB, -0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x20, 0x30, 0x40, 0x81, 0x21, 0x04, 0x03, 0x14, 0x08, 0x08, 0x20, -0x89, 0x81, 0x00, 0x06, 0x06, 0x10, 0x01, 0x40, 0x20, 0x00, 0x08, 0x03, 0x34, -0x0C, 0x18, 0x08, 0x40, 0x70, 0x00, 0x09, 0x00, 0x14, 0x2C, 0x94, 0x8C, 0x40, -0x02, 0x00, 0xC1, 0x41, 0x34, 0x02, 0x90, 0x0C, 0x40, 0x52, 0x40, 0xC9, 0x00, -0x05, 0x03, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x7C, 0x40, 0xF1, 0x19, 0x04, 0x07, 0x10, 0x18, 0x40, 0x68, 0x00, -0xB1, 0x81, 0xC6, 0x04, 0x10, 0x96, 0x40, 0x6C, 0x40, 0x21, 0x21, 0xB4, 0x44, -0x18, 0x16, 0x62, 0x78, 0x10, 0x0D, 0x01, 0xB4, 0x04, 0x94, 0x1E, 0x40, 0x6A, -0x00, 0xE1, 0x50, 0x36, 0x06, 0x10, 0x3E, 0x50, 0x4E, 0x04, 0xE9, 0x01, 0x86, -0x07, 0xD0, 0x16, 0x60, 0x3C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x18, 0x30, 0x00, 0x83, 0x08, 0x0D, 0x03, 0x10, 0x08, 0xC0, 0x20, 0x40, 0xC3, -0x00, 0x0D, 0x22, 0x30, 0x04, 0x48, 0x20, 0xB2, 0x09, 0x52, 0x3C, 0x20, 0x34, -0x88, 0xC0, 0x30, 0x00, 0x0B, 0x00, 0x1C, 0x00, 0x90, 0x0C, 0xC0, 0x86, 0x00, -0xC3, 0x00, 0x3C, 0x02, 0xB0, 0x00, 0xC0, 0x92, 0x10, 0xCB, 0x04, 0x0C, 0x03, -0xF0, 0x0C, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, -0x3D, 0x00, 0xEF, 0x68, 0xFE, 0x0B, 0xF0, 0x0F, 0xC0, 0xBF, 0x00, 0xFF, 0x00, -0xFC, 0x00, 0xF0, 0x07, 0xC0, 0x3F, 0x20, 0xBF, 0x00, 0xFC, 0x20, 0xF0, 0x8E, -0xC0, 0x3B, 0x00, 0xB7, 0x80, 0xAD, 0x22, 0xF0, 0x8F, 0xC0, 0x2D, 0x40, 0xFF, -0x04, 0xFC, 0x02, 0xE0, 0x0B, 0xE0, 0x09, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0, -0x07, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, -0x00, 0xD7, 0x60, 0x4C, 0x0B, 0x34, 0x01, 0xC0, 0x6F, 0x00, 0x97, 0x00, 0x7C, -0x03, 0xF0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x00, 0xF0, 0x01, 0xC0, -0x37, 0x81, 0x12, 0x08, 0x0C, 0x00, 0x31, 0x4D, 0xC0, 0x24, 0x00, 0xD3, 0x00, -0x4C, 0x02, 0xB0, 0x1D, 0xD0, 0x54, 0x00, 0xD3, 0xA0, 0x4C, 0x83, 0xF0, 0x0D, -0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x00, -0xE1, 0x00, 0x06, 0x13, 0x10, 0x02, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x02, -0xD0, 0x0E, 0x42, 0x28, 0x20, 0xA8, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3F, -0x05, 0x31, 0x00, 0x84, 0x00, 0xD4, 0x0F, 0x51, 0x2C, 0x00, 0xE1, 0x00, 0x04, -0x02, 0x14, 0x0C, 0x40, 0x08, 0x40, 0xF1, 0x00, 0x94, 0x03, 0xD0, 0x0A, 0x44, -0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xC5, -0x01, 0x84, 0x27, 0x00, 0x1E, 0x40, 0x63, 0x00, 0xED, 0x01, 0xB4, 0x47, 0xD0, -0x3C, 0x40, 0x68, 0x08, 0xAC, 0x11, 0x84, 0x05, 0xD0, 0x1A, 0x40, 0x7B, 0x43, -0x29, 0x05, 0xA5, 0x04, 0x98, 0x1E, 0x40, 0x68, 0x80, 0xE1, 0x01, 0x84, 0x07, -0x10, 0x12, 0x60, 0x5C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x07, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x10, 0xD1, 0x00, -0x04, 0x03, 0x10, 0x0C, 0x40, 0x53, 0x22, 0xC9, 0x00, 0x34, 0x0A, 0xD0, 0x15, -0x40, 0x30, 0x00, 0xC9, 0x82, 0x04, 0x6B, 0xD0, 0x2C, 0x40, 0x33, 0x00, 0xD9, -0x01, 0x24, 0x03, 0xD0, 0x0C, 0x50, 0xF0, 0x81, 0x91, 0x01, 0x04, 0x07, 0x10, -0x08, 0x60, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x03, 0xD0, 0x98, 0x40, 0x4B, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x77, 0x8A, 0x4D, -0x81, 0x30, 0x76, 0xC0, 0x9F, 0x00, 0x5F, 0x01, 0xFC, 0x0D, 0xF1, 0xB7, 0xC0, -0x14, 0x20, 0x7F, 0x4B, 0xCC, 0x0D, 0xF0, 0x26, 0xC0, 0x17, 0x10, 0x7B, 0x01, -0xAC, 0x05, 0x34, 0x05, 0xC2, 0x9C, 0x04, 0x53, 0x01, 0xCC, 0x09, 0x30, 0x07, -0xC1, 0x1C, 0x00, 0x53, 0x00, 0x4D, 0x01, 0xF2, 0x27, 0xC2, 0x5F, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x10, 0x1F, 0x00, 0x3C, 0x00, -0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x08, 0x7C, 0x10, 0xF0, 0x21, 0xC0, 0x07, -0x00, 0x1B, 0x02, 0x7D, 0x08, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x17, 0x08, 0x5C, -0x28, 0x70, 0x20, 0xD0, 0x07, 0x40, 0x1F, 0x08, 0x7D, 0x60, 0x70, 0x11, 0xC0, -0x47, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC1, 0x4B, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x26, 0x30, -0x09, 0xC0, 0x24, 0x04, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x24, 0x00, -0x9F, 0x04, 0x7C, 0x82, 0xB0, 0x09, 0xC4, 0x26, 0x40, 0x93, 0x04, 0x4C, 0x12, -0x34, 0x19, 0xC0, 0x24, 0x01, 0x93, 0x08, 0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x00, 0x91, 0x00, 0x44, 0x02, 0x11, 0x09, -0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0xA9, 0x41, 0x24, 0x00, 0x9D, -0x00, 0x34, 0x0A, 0x10, 0x69, 0x40, 0x24, 0x00, 0x91, 0x01, 0x44, 0x16, 0x10, -0x19, 0xD0, 0x22, 0x00, 0x91, 0x02, 0x45, 0x02, 0x10, 0x09, 0x40, 0x27, 0x20, -0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x20, 0x44, 0x02, 0x11, 0x09, 0x40, -0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x25, 0x00, 0x9D, 0x00, -0x74, 0x06, 0x90, 0x09, 0x40, 0x22, 0x02, 0x91, 0x00, 0x64, 0x02, 0x14, 0x49, -0x48, 0x24, 0x00, 0x91, 0x02, 0x64, 0x22, 0x18, 0x19, 0x40, 0x27, 0x00, 0x8D, -0x00, 0x65, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x20, 0x24, 0x00, 0x81, 0x04, 0x24, 0x12, 0x10, 0x49, 0x40, 0x61, -0x91, 0x8D, 0x04, 0x34, 0x02, 0xC0, 0x48, 0x40, 0x21, 0x00, 0x8D, 0x20, 0x74, -0x02, 0x00, 0x08, 0x42, 0x20, 0x89, 0x81, 0x44, 0x26, 0x02, 0x18, 0x48, 0x40, -0x26, 0x40, 0x81, 0x00, 0x24, 0x12, 0x14, 0x58, 0x40, 0x23, 0x00, 0x8D, 0x04, -0x24, 0x02, 0xD0, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB8, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x28, 0x34, 0xA1, 0xD0, 0x05, 0x00, -0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x85, 0x02, 0x5F, 0x00, 0x74, 0x01, -0xB1, 0x01, 0xC8, 0x96, 0x42, 0x13, 0x0A, 0x6D, 0x00, 0x30, 0xA5, 0x40, 0x84, -0x0A, 0x03, 0x4A, 0x6C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x6D, -0x00, 0xF0, 0x01, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB8, 0x2F, 0x10, 0xBF, 0x08, 0x5D, 0x22, 0xF0, 0x8B, 0xC0, 0x3E, 0x02, 0xBF, -0x08, 0xF4, 0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2, -0x0B, 0x00, 0x27, 0x02, 0xBF, 0x88, 0xDC, 0x82, 0xF2, 0x8B, 0xC0, 0x3F, 0x00, -0xBF, 0x00, 0xDC, 0x22, 0xD0, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08, 0x7C, 0x02, -0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8, -0x3B, 0x00, 0xF2, 0x14, 0xCC, 0x32, 0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00, -0xCC, 0x02, 0xF0, 0x4B, 0xC1, 0x24, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B, -0xC0, 0xED, 0x00, 0xB3, 0x03, 0xCC, 0x02, 0x30, 0x3B, 0xC0, 0x2C, 0x00, 0xBF, -0x88, 0xFC, 0x12, 0x30, 0x4A, 0xC1, 0x2C, 0x00, 0xB3, 0x00, 0x4D, 0x02, 0xF0, -0x09, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, -0x05, 0x01, 0x04, 0x04, 0x30, 0x11, 0x21, 0x43, 0x04, 0x08, 0x11, 0x08, 0x44, -0x00, 0xD0, 0x41, 0x50, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, -0xC4, 0x08, 0x41, 0x43, 0x44, 0x01, 0x10, 0x30, 0x40, 0x00, 0x04, 0x1D, 0x00, -0x5C, 0x51, 0x10, 0x41, 0x42, 0x04, 0x08, 0x0B, 0x12, 0x54, 0x00, 0xD0, 0x81, -0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x01, -0x81, 0x94, 0x05, 0x92, 0x90, 0xCC, 0x40, 0x20, 0x02, 0x91, 0x20, 0x04, 0x02, -0xD0, 0x48, 0x41, 0x20, 0x00, 0x81, 0x01, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA1, -0x09, 0x81, 0x06, 0x04, 0x82, 0x10, 0x68, 0x48, 0x20, 0x00, 0x8D, 0x00, 0x34, -0x32, 0x10, 0x48, 0x51, 0x20, 0x00, 0x89, 0x0C, 0x04, 0x02, 0xD0, 0x08, 0x40, -0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x4A, 0x91, -0x10, 0x44, 0x02, 0x90, 0x39, 0x40, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02, 0xD0, -0x09, 0x40, 0x24, 0x00, 0x91, 0x40, 0x74, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00, -0x91, 0x00, 0x45, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x14, 0x02, -0x10, 0x69, 0x40, 0x24, 0x20, 0x89, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x60, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x21, 0x00, 0x93, 0x00, -0x4C, 0x02, 0xB0, 0x29, 0xD0, 0xA4, 0x02, 0x83, 0x00, 0x4D, 0x02, 0xF0, 0x09, -0xC9, 0x24, 0x40, 0x93, 0x03, 0x7C, 0x4E, 0x34, 0x48, 0xC0, 0x25, 0x40, 0x93, -0x0B, 0x4C, 0x06, 0x24, 0x09, 0xD0, 0x64, 0x02, 0x9F, 0x00, 0x7C, 0x0E, 0x34, -0x09, 0xC0, 0xA4, 0x24, 0x9B, 0x01, 0x4D, 0x02, 0xF0, 0x09, 0xD0, 0x14, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x10, 0x9F, 0x04, 0x3C, -0x42, 0x70, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xF1, 0x48, 0xC0, -0xE7, 0x00, 0x9F, 0x02, 0x7C, 0x06, 0xF1, 0x09, 0xC8, 0x23, 0x40, 0x9F, 0x01, -0x7C, 0x06, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x7C, 0x12, 0xF0, 0x19, -0xC1, 0x27, 0x00, 0x9F, 0x04, 0x7D, 0x02, 0xF0, 0x08, 0xC0, 0x5B, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x80, 0x4C, 0x00, -0x30, 0x00, 0xC0, 0x83, 0x40, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04, -0x00, 0x1F, 0x10, 0x7E, 0x08, 0xF2, 0x01, 0xD1, 0x06, 0x01, 0x03, 0x82, 0x4C, -0x40, 0x31, 0x01, 0xC1, 0xC6, 0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x20, 0xC0, -0x84, 0x00, 0x1F, 0x00, 0x4D, 0x00, 0xF0, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x01, 0xC5, 0x09, 0x10, -0x05, 0xC0, 0x5D, 0x00, 0x51, 0x00, 0x74, 0x01, 0xD0, 0x17, 0x60, 0x14, 0x00, -0x7D, 0x03, 0xB4, 0x01, 0xD0, 0x27, 0x44, 0x5C, 0x00, 0x5B, 0x11, 0xAC, 0x15, -0xB1, 0x57, 0xC0, 0x1E, 0x40, 0x70, 0x00, 0xC4, 0x11, 0x14, 0x37, 0x40, 0x10, -0x00, 0x5D, 0x11, 0x44, 0x01, 0xD0, 0x05, 0x50, 0x50, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0xD1, 0x00, 0x24, 0x07, 0x11, 0x0C, -0x40, 0x31, 0x04, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x1C, 0x48, 0x34, 0x00, 0xCD, -0x02, 0x34, 0x02, 0xD8, 0x2C, 0x60, 0x32, 0x90, 0xC9, 0x21, 0x04, 0x87, 0x58, -0x0C, 0x42, 0x30, 0x00, 0xC0, 0x04, 0x04, 0x03, 0x10, 0x3C, 0x40, 0x20, 0x00, -0xCD, 0x00, 0x04, 0x83, 0xD0, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x80, 0x3C, 0x20, 0xA1, 0x10, 0xA5, 0x1A, 0x10, 0x0E, 0x40, -0x31, 0x04, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x04, 0x41, 0x38, 0x01, 0x6D, 0x02, -0xB6, 0x40, 0xD8, 0x03, 0x40, 0xAA, 0x82, 0xE9, 0x00, 0xA4, 0x00, 0xD0, 0x0E, -0x40, 0x7A, 0x00, 0xE1, 0x01, 0x84, 0x03, 0x10, 0x0F, 0x41, 0x28, 0x00, 0xED, -0x00, 0x85, 0x03, 0xD0, 0x0E, 0x40, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x18, 0x78, 0x00, 0xE3, 0x01, 0xAC, 0x16, 0x34, 0x1E, 0xC0, 0x79, -0x00, 0xE3, 0x01, 0xBC, 0x06, 0xD0, 0x16, 0x40, 0xF8, 0x01, 0x2D, 0x01, 0xB4, -0x05, 0xF0, 0x16, 0xD0, 0x72, 0x00, 0xAB, 0x01, 0x8C, 0x04, 0x74, 0x9E, 0xC0, -0x78, 0x00, 0xF3, 0x81, 0xCC, 0x07, 0x34, 0x1E, 0xC0, 0x68, 0x00, 0xAF, 0x01, -0x84, 0x07, 0xF0, 0x1C, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xB8, 0x35, 0x40, 0x9F, 0x14, 0x5C, 0x22, 0xF0, 0x0D, 0xC0, 0x35, 0x00, -0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xD0, 0x77, 0x00, 0x5F, 0x00, 0x6C, 0x00, -0xF0, 0x00, 0xD0, 0x25, 0x20, 0x9F, 0x02, 0x3C, 0x00, 0xB1, 0x09, 0xD0, 0x37, -0x00, 0xDF, 0x00, 0x7D, 0x03, 0xE0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7D, -0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x20, 0x7D, 0x00, 0xFF, 0x21, 0x8C, 0x06, 0x38, 0x8F, 0xC0, 0x6D, 0x00, 0xF3, -0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xD0, 0x7C, 0x00, 0x3F, 0x01, 0xFC, 0x06, 0xF0, -0x13, 0xC0, 0x5F, 0x20, 0xF7, 0x23, 0xCC, 0x04, 0x31, 0x9F, 0xC0, 0x7C, 0x08, -0xF3, 0x01, 0x8C, 0x07, 0x31, 0x0B, 0xC0, 0x6F, 0x00, 0xEF, 0x03, 0xCC, 0x07, -0xF2, 0x1F, 0xC2, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, -0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x38, 0x0F, 0x40, 0x08, 0x40, 0xE1, 0x00, -0xBC, 0x02, 0xD0, 0x26, 0x40, 0x38, 0x02, 0x6D, 0x10, 0xB4, 0xA0, 0xD0, 0x82, -0x40, 0x0F, 0x10, 0xE1, 0x04, 0x94, 0x10, 0x10, 0xE6, 0x41, 0x3C, 0x00, 0xF1, -0x10, 0x84, 0x83, 0x14, 0x8A, 0x40, 0x2B, 0x04, 0xED, 0x08, 0x84, 0x03, 0xD0, -0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, -0x00, 0xED, 0x00, 0x84, 0x02, 0x90, 0x8E, 0x40, 0x29, 0x00, 0xE1, 0x00, 0xB4, -0x42, 0xD0, 0x06, 0x40, 0x38, 0x04, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40, -0x2B, 0x02, 0xED, 0x80, 0xC4, 0x00, 0x10, 0x04, 0x40, 0x38, 0x04, 0x61, 0x00, -0xF4, 0x03, 0x10, 0x8A, 0x41, 0x2B, 0x02, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x2C, -0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x31, 0x00, -0xCD, 0x00, 0x44, 0x02, 0x10, 0x1C, 0x40, 0x00, 0x04, 0xC1, 0x49, 0x34, 0x02, -0xD0, 0x25, 0x40, 0x70, 0x00, 0x4D, 0x01, 0x34, 0x00, 0xD2, 0x10, 0x40, 0x23, -0x00, 0xC9, 0x0A, 0x14, 0xC8, 0x14, 0x04, 0x50, 0xF0, 0x00, 0x41, 0x00, 0x34, -0x0B, 0x10, 0x18, 0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, -0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xDF, -0x07, 0xCC, 0x02, 0xB0, 0x4D, 0xC0, 0xE5, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xF0, -0x05, 0xD0, 0x3C, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x3F, 0x00, -0xDF, 0x23, 0x0D, 0x08, 0x30, 0x11, 0xC0, 0xF4, 0x08, 0xD3, 0x00, 0x7C, 0x23, -0x30, 0x0D, 0xC0, 0xB7, 0x00, 0x9F, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x74, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x10, 0x9F, 0x00, -0x7E, 0x02, 0x70, 0x0D, 0xC2, 0x63, 0x10, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0xC5, -0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x37, 0x00, 0xD7, -0x10, 0x7C, 0x0C, 0xF0, 0x00, 0xC0, 0x37, 0x04, 0xDF, 0x00, 0x44, 0x0B, 0xF0, -0x0C, 0xC1, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC2, 0x07, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xEF, 0x10, 0xCC, -0x06, 0x30, 0x0F, 0xC0, 0x04, 0x00, 0xF3, 0x00, 0xFE, 0x52, 0x30, 0x05, 0xC0, -0x3C, 0x00, 0x37, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x7B, 0x00, 0x93, 0x00, -0xCC, 0x00, 0xB0, 0x03, 0x40, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x83, 0x32, 0x8F, -0xC2, 0xBC, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xF0, 0x0E, 0xC0, 0x04, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x9D, 0x20, 0x44, 0x0A, -0x10, 0x0C, 0x50, 0xC4, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x50, 0x15, 0x50, 0x35, -0x00, 0x5D, 0x07, 0x74, 0x0C, 0xD0, 0x11, 0xC0, 0x35, 0x02, 0x81, 0x00, 0x44, -0x4C, 0x11, 0x31, 0xC0, 0x36, 0x00, 0xD1, 0x02, 0x44, 0x43, 0x10, 0x21, 0x42, -0x24, 0x00, 0x9D, 0x09, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x04, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66, 0x00, 0xDD, 0x00, 0x44, 0x28, 0x10, -0x19, 0x40, 0xE6, 0x00, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x11, 0x40, 0x36, 0x00, -0x1D, 0x01, 0x74, 0x44, 0xD0, 0x31, 0x40, 0x17, 0x40, 0xD1, 0x00, 0x44, 0x84, -0x10, 0x11, 0x02, 0xD3, 0x00, 0xC1, 0x11, 0x06, 0x04, 0x10, 0x29, 0x40, 0x36, -0x00, 0xDD, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x06, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0x10, 0x09, -0x40, 0x02, 0x40, 0xC1, 0x00, 0x34, 0x82, 0x50, 0x00, 0x40, 0x33, 0x08, 0x4D, -0x40, 0x36, 0x00, 0xD0, 0x00, 0x40, 0x11, 0x80, 0xD1, 0x00, 0x44, 0x00, 0x10, -0x00, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x06, 0x02, 0x10, 0x08, 0x50, 0x22, 0x00, -0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x98, 0x26, 0x00, 0xEF, 0x00, 0x4C, 0x00, 0x34, 0x09, 0xC0, -0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0x70, 0x05, 0xC0, 0x36, 0x00, 0x17, 0x00, -0x74, 0x00, 0xF2, 0x01, 0xC2, 0x27, 0x20, 0xF3, 0x20, 0x4C, 0x00, 0xB0, 0x03, -0xD0, 0x07, 0x00, 0x93, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x36, 0x00, 0xBF, -0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x06, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x0D, -0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x07, 0xC0, 0x3D, 0x00, 0x7F, 0x00, 0xFC, -0x00, 0xD0, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBD, 0x00, 0xF4, 0x03, 0xC2, -0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0x00, -0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0x30, 0x1F, 0xC8, 0x7F, 0x0A, -0xFF, 0x01, 0xCC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0xFC, 0x27, -0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xCC, 0x27, 0x30, 0x9F, 0xC0, 0x78, -0x00, 0xFF, 0x09, 0xCC, 0x07, 0xB0, 0x13, 0xC0, 0x7E, 0x00, 0xEF, 0x01, 0xFC, -0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x11, 0x40, 0x07, 0x01, 0x1D, -0x01, 0x44, 0x00, 0x90, 0x11, 0x40, 0x04, 0x01, 0x11, 0x00, 0x74, 0x10, 0xD0, -0x01, 0x40, 0x47, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x01, 0x48, 0x44, 0x00, -0x1D, 0x00, 0x44, 0x87, 0x51, 0x11, 0x40, 0x74, 0x00, 0x9D, 0x01, 0x74, 0x13, -0x10, 0x1D, 0x40, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, -0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, -0x04, 0x03, 0xD0, 0x0D, 0x48, 0x34, 0x14, 0xC1, 0x20, 0x34, 0x03, 0xD0, 0x4C, -0x40, 0x37, 0x00, 0xD9, 0x00, 0x64, 0x03, 0x10, 0x0D, 0x40, 0x31, 0x00, 0xCD, -0x04, 0x24, 0x03, 0x10, 0x01, 0x48, 0x32, 0x80, 0x8D, 0x00, 0x34, 0x43, 0x19, -0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, -0x00, 0xDD, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, -0x00, 0x90, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x80, 0xD0, 0x01, 0x40, -0x07, 0x00, 0x19, 0x00, 0x64, 0x00, 0x11, 0x01, 0x42, 0x05, 0x08, 0x1D, 0x20, -0x64, 0x07, 0x50, 0x11, 0x41, 0x34, 0x80, 0x1D, 0x01, 0x34, 0x03, 0x18, 0x0D, -0x42, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x18, 0xCF, 0x00, 0x4C, 0x03, -0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, -0x00, 0xCB, 0x00, 0x6C, 0x03, 0x30, 0x0C, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x6D, -0x07, 0x30, 0x10, 0xC2, 0x36, 0x00, 0x9F, 0x13, 0x7C, 0x03, 0x30, 0x0D, 0xC2, -0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, -0x00, 0xFC, 0x40, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, -0x03, 0xD2, 0x0F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00, -0x37, 0x00, 0xDC, 0x00, 0xF6, 0x03, 0xC0, 0x0E, 0x20, 0x3F, 0x00, 0xDC, 0x03, -0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x36, 0x00, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D, -0xC2, 0x34, 0x04, 0xDF, 0x01, 0x4C, 0x43, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDB, -0x01, 0x4C, 0x13, 0xF0, 0x8D, 0x80, 0x34, 0x02, 0xD3, 0x18, 0x4C, 0x0E, 0xF0, -0x01, 0xC0, 0x37, 0x00, 0x93, 0x02, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0x2B, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, -0x00, 0x11, 0x01, 0x40, 0x84, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x10, 0x40, -0x80, 0x00, 0x1D, 0x80, 0x44, 0x9C, 0xD0, 0x51, 0x40, 0xC7, 0x0A, 0x1D, 0x00, -0x04, 0x48, 0xD0, 0x21, 0x40, 0x44, 0x20, 0x11, 0xA0, 0x2C, 0x02, 0xD0, 0xA5, -0x40, 0x77, 0x04, 0x91, 0x00, 0x68, 0x07, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x74, 0x0F, -0x10, 0x1C, 0x40, 0x32, 0x02, 0xCD, 0x00, 0x04, 0x43, 0xD0, 0x8C, 0x40, 0xF0, -0x08, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x73, 0x02, 0xCD, 0x00, 0x04, -0x0F, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x00, 0x24, 0x03, 0xD0, 0x04, 0x48, -0x73, 0x00, 0x88, 0x00, 0x04, 0x27, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x64, 0x10, -0x12, 0x40, 0xC8, 0x00, 0x3D, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x50, 0x48, 0x04, -0x2D, 0x03, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x02, 0x3D, 0x01, 0x84, 0x04, -0xD0, 0x33, 0x40, 0x4C, 0x00, 0x31, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x40, 0x3B, -0x00, 0xB9, 0x01, 0xA4, 0x07, 0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x0C, -0xC0, 0x32, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xDF, -0x00, 0x0C, 0x03, 0xF0, 0x0C, 0x40, 0x33, 0x00, 0xCF, 0x04, 0x0C, 0x23, 0xF2, -0x0D, 0x40, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x0B, 0xF0, 0x00, 0xC0, 0x33, 0x02, -0x8B, 0x80, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x82, 0x80, -0x0F, 0x02, 0x2F, 0x00, 0xFC, 0x00, 0xF1, 0x02, 0xC0, 0x0F, 0x08, 0x3F, 0x00, -0x7C, 0x00, 0xF0, 0x83, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0x7C, 0x00, 0xF0, 0x03, -0xD0, 0x0F, 0x00, 0x2F, 0x09, 0xFC, 0x03, 0xF0, 0x83, 0xC4, 0x3B, 0x01, 0xB7, -0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x77, -0x40, 0xD3, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x37, 0x08, 0xDF, 0x00, 0x7C, -0x07, 0x30, 0x1D, 0xD0, 0x70, 0x00, 0xC3, 0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, -0x37, 0x20, 0xDF, 0x40, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x00, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x48, 0x0F, 0x00, -0x21, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xF4, 0x00, -0x13, 0x03, 0x40, 0x08, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x0B, -0x00, 0x2D, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x38, 0x00, 0xA9, 0x00, 0xB4, -0x03, 0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE1, -0x01, 0xB4, 0x07, 0x10, 0x1E, 0x00, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x54, -0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, -0xED, 0x01, 0xB4, 0x07, 0xD0, 0x12, 0x40, 0x78, 0x80, 0xAD, 0x11, 0xB4, 0x07, -0xD0, 0x1E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, -0x33, 0x00, 0xCD, 0x00, 0x34, 0x80, 0x50, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00, -0x34, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, -0x40, 0x00, 0x00, 0x05, 0x00, 0x16, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, -0x00, 0x34, 0x07, 0xD0, 0x6C, 0x40, 0x30, 0x80, 0x89, 0x01, 0x34, 0x03, 0xD0, -0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, -0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C, -0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, -0x14, 0x00, 0x51, 0x00, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, -0xBC, 0x95, 0xF0, 0x27, 0xD0, 0x14, 0x00, 0x6F, 0x02, 0x7C, 0x01, 0xD0, 0x05, -0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, -0x1F, 0x00, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F, -0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0x7C, -0x40, 0xE0, 0x21, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x74, 0x00, 0xF0, 0x01, 0xC0, -0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, -0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x27, 0x01, -0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, -0x70, 0x49, 0xC0, 0xE5, 0x00, 0x9F, 0x00, 0x4C, 0x16, 0xF0, 0x09, 0xC0, 0x43, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, -0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x2E, 0xD0, 0x09, -0x46, 0xA7, 0x00, 0x9D, 0x03, 0x74, 0x2A, 0xD0, 0x29, 0x40, 0x67, 0x80, 0x9D, -0x00, 0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x43, 0x74, 0xA2, 0x30, -0x38, 0x40, 0x24, 0x01, 0x9D, 0x80, 0x6C, 0x0E, 0xD1, 0x09, 0x40, 0x07, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, -0x12, 0xD0, 0x4B, 0x40, 0x6F, 0x00, 0xBD, 0x01, 0xF4, 0x02, 0xD0, 0x1B, 0x40, -0x6F, 0x00, 0xBD, 0x08, 0xF4, 0x02, 0xD0, 0x8B, 0x40, 0x2F, 0x18, 0xBD, 0x01, -0xF4, 0x02, 0xD0, 0x1B, 0x41, 0x6F, 0x00, 0xBD, 0x04, 0x64, 0x02, 0x58, 0x09, -0x40, 0x25, 0x08, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0xB4, 0x06, -0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x06, 0xD2, 0x0A, 0x40, 0x6B, -0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x1A, 0x48, 0x6B, 0x20, 0xAD, 0xC0, 0xB4, -0x06, 0xD0, 0x0A, 0x48, 0x2B, 0x00, 0xAD, 0x01, 0x74, 0x02, 0x10, 0x09, 0x40, -0x20, 0x00, 0x9D, 0x00, 0x25, 0x22, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0, -0x01, 0xC2, 0x87, 0x02, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22, -0x1F, 0x2A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x28, -0xF0, 0xA1, 0x40, 0x07, 0x00, 0x3F, 0x0A, 0x6C, 0x00, 0x72, 0x05, 0xC0, 0x05, -0x00, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xC8, 0x77, 0xE0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x09, -0xCA, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, -0x00, 0x74, 0x82, 0xF1, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xF8, 0x02, 0x72, 0x0B, 0xC0, 0x27, 0x00, -0xBF, 0x00, 0x7C, 0x12, 0xF8, 0x09, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0B, 0xC6, -0xAC, 0x18, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x0B, 0xC0, 0xAF, 0x20, 0xBF, 0x02, -0xCC, 0x0A, 0xF0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xFC, 0x0A, 0x30, 0x2B, -0xC0, 0x2C, 0x20, 0xBF, 0x48, 0xBC, 0x02, 0x30, 0x0F, 0xC0, 0x2F, 0x20, 0x9F, -0x00, 0xF4, 0x02, 0x30, 0x09, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x40, 0x44, -0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x48, 0x47, 0x01, 0x1D, 0x81, 0x44, -0x94, 0x90, 0x11, 0x52, 0x04, 0x00, 0x11, 0x00, 0x74, 0x04, 0x10, 0x51, 0x40, -0x04, 0x00, 0x1D, 0x05, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, -0x64, 0x00, 0x14, 0x01, 0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x21, 0x01, -0x8D, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x23, 0x01, 0xC5, 0x04, 0x15, 0x03, -0xD0, 0x4D, 0x41, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x14, 0x32, -0x20, 0x8D, 0x00, 0x76, 0x82, 0x50, 0x08, 0x48, 0x23, 0x10, 0x8D, 0x00, 0x34, -0x02, 0x10, 0x08, 0x40, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D, -0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0, -0x0D, 0x40, 0x24, 0x00, 0x91, 0xC0, 0x74, 0x02, 0x12, 0x09, 0x00, 0x24, 0x00, -0x9D, 0x00, 0x74, 0x12, 0x54, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x24, 0x02, -0x10, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C, 0x02, 0xF0, 0x09, -0xC0, 0x24, 0x40, 0x95, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x26, 0x00, 0x9F, -0x00, 0x7C, 0x4E, 0x70, 0x69, 0xC0, 0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x10, -0x09, 0x40, 0x17, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xB0, 0x09, 0xC0, -0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x25, 0x20, 0x9F, 0x00, -0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x04, 0x9F, 0x04, 0x6C, 0x02, 0xF0, 0x09, -0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, -0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7E, 0x00, -0x34, 0x01, 0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47, -0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x41, 0xC2, 0x04, 0x00, 0x13, 0x00, 0x7C, -0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0, -0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D, -0x00, 0xF4, 0x01, 0xD0, 0x04, 0x40, 0x9F, 0x04, 0x5D, 0x01, 0xF4, 0x21, 0x10, -0x05, 0x00, 0xDF, 0x02, 0x71, 0x88, 0xF0, 0x01, 0xD0, 0x86, 0xC0, 0x19, 0x01, -0x5D, 0x11, 0xF4, 0x09, 0x10, 0x37, 0x48, 0x14, 0x20, 0x7B, 0x91, 0x74, 0x01, -0x10, 0xB7, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0xF4, 0x45, 0xD0, 0x05, 0x40, 0x43, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, -0x34, 0x43, 0xD0, 0x08, 0x40, 0xF3, 0x00, 0x8D, 0x08, 0x34, 0x03, 0x10, 0x08, -0x40, 0xF3, 0x20, 0xD0, 0x02, 0x34, 0x13, 0xD0, 0x2C, 0x40, 0x53, 0x00, 0x8D, -0x40, 0x76, 0x43, 0x14, 0x3D, 0x40, 0x20, 0x00, 0xC1, 0x04, 0x74, 0x02, 0x50, -0x30, 0x48, 0x43, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4, -0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x07, 0x10, 0x0E, 0x40, -0x7B, 0x14, 0xE1, 0x40, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00, -0xB4, 0x03, 0x12, 0x2E, 0x50, 0x78, 0x00, 0xE9, 0x00, 0xF4, 0xC2, 0x00, 0x02, -0x41, 0x0B, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x13, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x07, -0xF0, 0x1E, 0xC2, 0x5B, 0x00, 0xEF, 0x01, 0xF4, 0x07, 0x30, 0x1E, 0xC8, 0x7F, -0x10, 0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xFC, -0x07, 0x30, 0x17, 0xC8, 0x78, 0x08, 0xE3, 0x21, 0xBC, 0x07, 0x70, 0x16, 0xC0, -0x4B, 0x00, 0xEF, 0x21, 0xBC, 0x05, 0xF0, 0x1E, 0xC0, 0x53, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x17, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40, 0x17, 0x00, -0xD7, 0x20, 0x7C, 0x01, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, -0xF3, 0x05, 0xC0, 0x32, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xE0, 0x05, 0xC0, 0x07, -0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF1, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x05, 0xF0, 0x1F, -0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, -0x21, 0xBC, 0x85, 0x30, 0x1F, 0xC0, 0x78, 0x02, 0xF3, 0x01, 0xFC, 0x05, 0xF0, -0x5F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x16, 0xF0, 0x17, 0xC4, 0x6D, 0x00, -0xFF, 0x09, 0xF4, 0x27, 0x30, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x09, 0xD0, 0x0E, 0x40, -0x3B, 0x00, 0xE1, 0x28, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x08, -0xB4, 0x03, 0x12, 0x0F, 0x40, 0x38, 0x06, 0xE1, 0x18, 0xB4, 0x43, 0xD0, 0x06, -0x41, 0x3B, 0x00, 0xED, 0x0A, 0xB4, 0x03, 0xD0, 0x07, 0x40, 0x28, 0x00, 0xED, -0x08, 0xF4, 0x0B, 0x14, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x8E, 0x40, 0x1F, -0x00, 0xE1, 0x00, 0xB4, 0x09, 0xD0, 0x8F, 0x40, 0x39, 0x02, 0x6D, 0x02, 0xF4, -0x09, 0x10, 0x26, 0x40, 0xBC, 0x08, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x4E, 0x40, -0x3B, 0x02, 0xED, 0x80, 0xB4, 0x93, 0xD0, 0x07, 0x40, 0x19, 0x00, 0xED, 0x40, -0xB4, 0x01, 0x12, 0x0E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x08, 0xD0, 0x0C, 0x41, 0x07, 0x01, -0xC1, 0x01, 0x34, 0x82, 0xD0, 0x2C, 0x4D, 0x65, 0x02, 0x8D, 0x88, 0x74, 0x24, -0x10, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x02, 0x34, 0x0C, 0xD0, 0x00, 0x40, 0x73, -0x04, 0x9D, 0x0F, 0x34, 0x02, 0xD0, 0x24, 0x40, 0x00, 0x20, 0xCD, 0x09, 0x74, -0x00, 0x10, 0x0C, 0x60, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x36, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xC3, -0x12, 0x3C, 0x14, 0xF0, 0x2D, 0xC0, 0x85, 0x00, 0x0F, 0x00, 0x7C, 0x02, 0x30, -0x51, 0x40, 0x74, 0x80, 0xD3, 0x09, 0x74, 0x26, 0xF0, 0x19, 0xC0, 0x33, 0x04, -0x1E, 0x00, 0x7C, 0x02, 0xF0, 0x14, 0xC0, 0x05, 0x00, 0xDF, 0x01, 0x7C, 0x02, -0x30, 0x0D, 0xC8, 0x77, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC8, 0xC7, 0x20, 0xDF, 0x04, -0x7C, 0x00, 0xF0, 0x1D, 0x00, 0x26, 0x01, 0x1D, 0x80, 0x7C, 0x0A, 0xF0, 0x01, -0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0x41, 0x37, 0x20, 0x9F, -0x00, 0x78, 0x02, 0xC0, 0x15, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, -0x0D, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, -0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2C, 0x00, 0xF3, 0x05, 0xEC, -0x00, 0xB0, 0x5F, 0xC0, 0x0F, 0x00, 0x33, 0x20, 0xCC, 0x02, 0x30, 0x03, 0xC0, -0x3F, 0x00, 0xFF, 0x04, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x20, 0x33, 0x20, -0xCC, 0x17, 0xF0, 0x17, 0xD1, 0x0C, 0x00, 0xFF, 0x10, 0xFC, 0x00, 0x10, 0x0F, -0xC2, 0x27, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, -0xDD, 0x00, 0x74, 0x06, 0xD1, 0x0C, 0x40, 0x44, 0x08, 0xD1, 0x01, 0x44, 0x04, -0x10, 0x1D, 0x40, 0x47, 0x01, 0x11, 0x01, 0x44, 0x06, 0x10, 0x31, 0x40, 0xF7, -0x04, 0xDD, 0x01, 0x74, 0x1E, 0xD0, 0x51, 0x40, 0x37, 0x20, 0x11, 0x03, 0x44, -0x03, 0xD0, 0xC5, 0x40, 0x44, 0x01, 0xDD, 0x00, 0x74, 0x2C, 0x10, 0x0D, 0x46, -0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, -0x00, 0x74, 0x06, 0xD0, 0x1D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x64, 0x0E, 0x10, -0x0D, 0x40, 0x47, 0x80, 0x91, 0x03, 0x44, 0x0C, 0x10, 0x19, 0x42, 0x77, 0x00, -0xDD, 0x00, 0x74, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x09, 0x11, 0x01, 0x44, 0x02, -0xD0, 0x05, 0x40, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x82, 0x40, 0x0D, 0x40, 0x07, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0xCD, 0x00, -0x34, 0x02, 0xD0, 0x0D, 0x40, 0x20, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x0C, -0x40, 0x23, 0x60, 0x91, 0x00, 0x04, 0x02, 0x16, 0x08, 0x40, 0x33, 0x20, 0xCD, -0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x37, 0x08, 0x81, 0x20, 0x05, 0x02, 0xD0, -0x04, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x50, 0x0C, 0x40, 0x43, 0x20, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x36, 0x00, 0xDF, 0x00, 0x7C, -0x00, 0xF0, 0x0D, 0xC2, 0x24, 0x00, 0xD3, 0x00, 0x6C, 0x00, 0x30, 0x0D, 0xC0, -0x07, 0x00, 0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x13, 0x40, 0x4C, 0x03, 0xF0, 0x05, -0xC0, 0x04, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x74, 0x0D, 0xC0, 0x07, 0x40, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, -0xF0, 0x0F, 0xC8, 0x2B, 0x08, 0xFF, 0x20, 0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x2F, -0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x2F, 0x00, 0xFF, 0x00, 0xFC, -0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x17, 0x22, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x4F, 0x00, 0x33, 0x01, 0xCC, 0x24, 0x30, -0x13, 0xC0, 0x2C, 0x02, 0xF3, 0x00, 0x8C, 0x07, 0x30, 0xCF, 0xC0, 0x2C, 0x40, -0x33, 0x08, 0xCC, 0x23, 0x72, 0xC7, 0xC0, 0xCE, 0x00, 0x33, 0x04, 0xDC, 0x00, -0x30, 0x13, 0xC0, 0xCF, 0x00, 0x3F, 0x01, 0xED, 0x04, 0x30, 0x13, 0xC0, 0x4C, -0x00, 0x33, 0x01, 0xCC, 0x04, 0x30, 0x13, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x21, 0x11, 0x00, 0x44, 0x00, 0x10, 0x04, -0x40, 0x24, 0x09, 0xF1, 0x00, 0x44, 0x03, 0x30, 0x21, 0x40, 0xB0, 0x05, 0x01, -0x26, 0x05, 0x3B, 0x30, 0xE1, 0x40, 0x05, 0x21, 0x51, 0x0B, 0x44, 0x18, 0x15, -0x41, 0xC0, 0x23, 0x00, 0x1D, 0x00, 0x44, 0x82, 0x10, 0x01, 0x42, 0x44, 0x00, -0x11, 0x80, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0xA0, 0x03, 0x04, 0x11, 0x01, 0x04, 0x12, 0x10, 0x00, 0x40, -0x00, 0x00, 0xC1, 0x00, 0x64, 0x53, 0x90, 0x3C, 0x48, 0x24, 0x02, 0x01, 0x06, -0x25, 0x83, 0xD0, 0x05, 0x40, 0x00, 0x00, 0x09, 0x00, 0x34, 0x48, 0x90, 0x00, -0x41, 0x03, 0x01, 0x89, 0x00, 0x44, 0x00, 0x90, 0x01, 0x40, 0x46, 0x00, 0x89, -0x00, 0x24, 0x02, 0x10, 0x08, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA8, 0x05, 0x00, 0x11, 0x40, 0x04, 0x02, 0x10, 0x05, 0x40, 0x04, -0x12, 0xC1, 0x00, 0x64, 0x03, 0x14, 0x09, 0x40, 0x34, 0x02, 0x11, 0x01, 0x64, -0x07, 0x10, 0x01, 0x40, 0x45, 0x04, 0x59, 0x20, 0x64, 0x44, 0x92, 0x11, 0x42, -0x27, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x98, 0x11, 0x00, 0x06, 0x00, 0x89, 0x00, -0x24, 0x02, 0x10, 0x08, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA0, 0x37, 0x40, 0x43, 0x00, 0x4C, 0x04, 0x30, 0x21, 0xC1, 0x64, 0x00, -0xD3, 0x00, 0x2D, 0x03, 0xB0, 0x0D, 0xC4, 0xC0, 0x40, 0x13, 0x00, 0x6C, 0x07, -0xF2, 0x0D, 0xC0, 0x84, 0x40, 0x5B, 0x81, 0x7C, 0x0C, 0xB1, 0x51, 0xE0, 0x07, -0x00, 0x1F, 0x00, 0x4C, 0x01, 0xB0, 0x08, 0xC0, 0x12, 0x18, 0x1B, 0x01, 0x6C, -0x04, 0x30, 0x11, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0x88, 0x3D, 0x20, 0x7F, 0x00, 0xFC, 0x24, 0xF0, 0x07, 0xC0, 0x73, 0x00, 0xFF, -0x00, 0xDC, 0x02, 0xF0, 0x26, 0xC0, 0x0F, 0x30, 0x3F, 0x20, 0x9C, 0x03, 0xF0, -0x05, 0xC0, 0x0D, 0x00, 0x77, 0x03, 0xDC, 0x00, 0x72, 0x03, 0xC0, 0x2D, 0x02, -0x3F, 0x08, 0xDC, 0x03, 0x74, 0x0B, 0xC0, 0x1D, 0x18, 0x36, 0x49, 0xDC, 0x24, -0xF0, 0x93, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, -0x75, 0x00, 0x53, 0x10, 0x4C, 0x06, 0x32, 0x01, 0xCA, 0x24, 0x00, 0xD3, 0x00, -0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0x13, 0x02, 0x6C, 0x02, 0x30, 0x0D, -0xC1, 0x86, 0x00, 0x4F, 0x50, 0xCC, 0x18, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x93, -0x05, 0x7C, 0x01, 0xF0, 0x09, 0xC0, 0x14, 0x04, 0x93, 0x11, 0x4C, 0x46, 0x30, -0x59, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74, -0x00, 0x51, 0x80, 0x44, 0x06, 0x12, 0x05, 0x40, 0x34, 0x09, 0xF1, 0x00, 0x44, -0x0B, 0x10, 0xBD, 0x40, 0xA4, 0x02, 0x35, 0x00, 0x44, 0x00, 0x10, 0x7C, 0x40, -0x04, 0x06, 0x5D, 0x11, 0x2C, 0x08, 0x10, 0x11, 0x00, 0x67, 0x08, 0x9B, 0x23, -0x34, 0x2B, 0xD0, 0xA9, 0x40, 0x94, 0x04, 0x91, 0x03, 0x44, 0x0E, 0x10, 0x39, -0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x04, 0x00, -0x89, 0x00, 0x04, 0x01, 0x10, 0x09, 0x40, 0x60, 0x00, 0xC1, 0x01, 0x04, 0x4B, -0x14, 0x3C, 0x40, 0xA0, 0x00, 0x11, 0x00, 0x24, 0x03, 0x18, 0x24, 0x40, 0x06, -0x08, 0x8D, 0x02, 0x14, 0x00, 0x11, 0x10, 0x48, 0x53, 0x02, 0x45, 0x00, 0x34, -0x00, 0xD0, 0x04, 0x40, 0x61, 0x00, 0x41, 0x02, 0x04, 0x09, 0x10, 0x04, 0x02, -0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0xB9, -0x09, 0x84, 0x0D, 0x10, 0x1E, 0x42, 0xF8, 0x00, 0xE1, 0x01, 0xC4, 0x87, 0x14, -0x1C, 0x41, 0x68, 0x02, 0xA5, 0x01, 0x84, 0x07, 0x10, 0x92, 0x50, 0x48, 0x20, -0xAD, 0x21, 0x36, 0x84, 0x18, 0x12, 0x40, 0x7B, 0x00, 0x6D, 0x01, 0xB4, 0x06, -0xD0, 0x97, 0x40, 0x6D, 0x00, 0x61, 0x09, 0x84, 0x25, 0x10, 0x16, 0x40, 0x10, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x00, 0x40, 0x8B, 0x08, -0x4C, 0x13, 0x30, 0x08, 0xC0, 0x00, 0x42, 0xD3, 0x10, 0x0C, 0x03, 0x30, 0x0C, -0x40, 0x20, 0x02, 0x83, 0x00, 0x2C, 0x03, 0x12, 0x04, 0xC2, 0x02, 0x00, 0x8F, -0x08, 0x1C, 0x12, 0x30, 0x00, 0xE5, 0x13, 0x00, 0xC7, 0x00, 0x3C, 0x20, 0xF0, -0x04, 0xC0, 0x21, 0x00, 0xD3, 0x08, 0x4C, 0x23, 0x30, 0x0D, 0xC0, 0x48, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0xA7, 0x08, 0xFC, -0x03, 0xF0, 0x0F, 0xC8, 0x1F, 0x00, 0xFF, 0x80, 0xFD, 0x03, 0xF0, 0x0F, 0xC0, -0x3F, 0x0A, 0xBE, 0x80, 0xFC, 0x03, 0xF4, 0x03, 0xC2, 0x0F, 0x02, 0xEF, 0x20, -0xEC, 0x02, 0xF0, 0x83, 0xC0, 0x3F, 0x02, 0xFB, 0x00, 0xFC, 0x02, 0xF1, 0x06, -0xC0, 0x2A, 0x02, 0xFF, 0x08, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0B, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xCF, 0x00, 0x5C, 0x05, -0x30, 0x09, 0xC0, 0x24, 0x00, 0xDF, 0x0D, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, -0x00, 0x13, 0x00, 0xCD, 0x03, 0x34, 0x0D, 0xD8, 0x05, 0x10, 0x13, 0x00, 0x7C, -0x02, 0x70, 0x01, 0xC4, 0x13, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, -0x34, 0x00, 0x5F, 0x00, 0x4E, 0x01, 0x30, 0x15, 0xC0, 0x54, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x80, 0x84, 0x01, 0x10, -0x0E, 0x40, 0x38, 0x00, 0xCD, 0x10, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x2B, 0x10, -0x81, 0x04, 0x84, 0x03, 0x10, 0x04, 0xC0, 0x0A, 0x00, 0x21, 0x00, 0xB4, 0x02, -0x11, 0x06, 0x48, 0x3B, 0x00, 0x61, 0x00, 0xB4, 0x03, 0xD2, 0x0F, 0x40, 0x38, -0x20, 0x6D, 0x00, 0x84, 0x01, 0x10, 0x06, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x94, 0x07, 0x10, 0x1A, -0x50, 0x68, 0x00, 0xED, 0x05, 0x84, 0x47, 0xD8, 0x1E, 0x40, 0x6F, 0x00, 0xA1, -0x1D, 0x85, 0x07, 0x10, 0x1E, 0x40, 0xC9, 0x18, 0xE1, 0x01, 0xF4, 0x0E, 0x50, -0x12, 0x40, 0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x05, 0xD0, 0x1E, 0x42, 0x78, 0x00, -0xED, 0x01, 0x84, 0x87, 0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x28, 0x73, 0x02, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0C, 0x40, -0xB0, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0D, 0x40, 0xA3, 0x01, 0xC1, 0x40, -0x04, 0x09, 0x10, 0x8D, 0x40, 0x76, 0x00, 0xC1, 0x03, 0x34, 0x0F, 0x10, 0x88, -0x42, 0x33, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, -0x00, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x17, 0xA0, 0x95, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x34, 0x05, 0xC0, 0x1C, -0x01, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x07, 0xC0, 0xDF, 0x44, 0x73, 0x00, 0xCC, -0x31, 0x30, 0x17, 0xC2, 0x9D, 0x40, 0x73, 0x07, 0xFC, 0x29, 0x72, 0x16, 0xC0, -0x17, 0x50, 0x53, 0x20, 0x7C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x10, 0x5F, 0x00, -0x4D, 0x01, 0x34, 0x05, 0xD0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x08, 0x05, 0x04, 0x1D, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC8, 0x03, 0x04, -0x1F, 0x40, 0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1F, 0x20, 0x7C, 0x00, -0xF2, 0x11, 0xD0, 0x07, 0x04, 0x0F, 0x12, 0x3C, 0x08, 0xF1, 0x41, 0xC0, 0x07, -0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x11, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x7C, -0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x02, 0x90, -0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x83, 0x00, 0x4C, 0x02, 0x30, -0x09, 0xC0, 0x64, 0x00, 0x93, 0x05, 0x4C, 0x06, 0x10, 0x09, 0xC8, 0x24, 0x00, -0x93, 0x00, 0x64, 0x0A, 0x30, 0x09, 0xC0, 0xE4, 0x10, 0x9F, 0x02, 0x4D, 0x0A, -0x30, 0x59, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0xA6, 0x10, 0x9D, 0x00, 0x45, 0x0A, 0xD0, 0x08, 0xC0, 0x66, 0x00, 0x91, 0x01, -0x34, 0x1A, 0x12, 0x09, 0x48, 0xA4, 0x02, 0x95, 0x00, 0x44, 0x02, 0x12, 0x99, -0x51, 0x24, 0x08, 0x91, 0x25, 0x44, 0xA6, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91, -0x02, 0x04, 0x0A, 0x10, 0x29, 0x50, 0x64, 0x08, 0x9D, 0x42, 0x44, 0x0A, 0x10, -0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, -0x80, 0xBD, 0x00, 0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x24, 0x40, 0x95, 0x08, 0x74, -0x22, 0x14, 0x09, 0x48, 0xB0, 0x00, 0xD9, 0x04, 0x24, 0x02, 0x14, 0x09, 0x40, -0x24, 0x42, 0xD1, 0x00, 0x45, 0x42, 0x50, 0x09, 0x52, 0x24, 0x40, 0xA1, 0x00, -0xF4, 0x02, 0x10, 0x2A, 0x42, 0x2C, 0x00, 0xAD, 0x00, 0xA4, 0x02, 0x10, 0x0B, -0x42, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x68, 0x00, -0xED, 0x00, 0x84, 0x06, 0xD0, 0x0B, 0x40, 0x22, 0x01, 0x85, 0x04, 0x74, 0x02, -0x10, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x25, 0x12, 0x10, 0x48, 0x40, 0x60, -0x20, 0x81, 0x84, 0x05, 0x12, 0x14, 0x08, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xD4, -0x02, 0x10, 0x0A, 0x42, 0x68, 0x80, 0xAD, 0x01, 0xA4, 0x06, 0x10, 0x1A, 0x40, -0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x1F, -0x0A, 0x0D, 0x28, 0xF0, 0xA2, 0xC0, 0x94, 0x02, 0x17, 0x0A, 0x7C, 0x28, 0x30, -0xA5, 0xD0, 0x84, 0x02, 0x1B, 0x0A, 0x2C, 0x28, 0x31, 0xA1, 0xD0, 0x80, 0x22, -0x13, 0x00, 0x4C, 0x28, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x29, -0x30, 0xA1, 0xC0, 0x04, 0x00, 0x0F, 0x0A, 0x2C, 0x28, 0x32, 0xA2, 0xC0, 0x77, -0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x9B, 0x08, 0xEC, 0x02, 0xF4, 0x8B, -0xC8, 0x2B, 0x02, 0xB7, 0x08, 0xDC, 0x23, 0xF0, 0x8B, 0xC2, 0x2F, 0x00, 0xBF, -0x68, 0xBC, 0x22, 0xF0, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x6C, 0x02, 0xF4, -0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xF3, 0x28, 0xDC, -0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x42, 0xB3, 0x04, 0xCC, 0x02, 0x30, 0xCF, 0xC0, -0x2B, 0x00, 0xA3, 0x05, 0x4D, 0x16, 0x32, 0x9B, 0xC0, 0xAF, 0x10, 0xB3, 0x05, -0xDC, 0x36, 0x30, 0x0B, 0xC4, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x8B, -0xC0, 0x3C, 0x18, 0xBF, 0x40, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x63, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x01, 0x04, 0x44, 0x41, -0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x14, 0x44, 0x10, 0x10, 0xC0, 0x40, 0x87, -0x44, 0x11, 0x17, 0x44, 0x5C, 0x14, 0x31, 0x44, 0x47, 0x00, 0x11, 0x22, 0x44, -0x04, 0x10, 0x55, 0x41, 0x44, 0x05, 0x51, 0x14, 0x74, 0x10, 0xD0, 0x41, 0x50, -0x04, 0x00, 0x5D, 0x10, 0x74, 0x01, 0xD0, 0x45, 0x41, 0x73, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x45, 0x81, 0x04, 0x14, 0x12, 0xD0, -0x08, 0x40, 0x23, 0x00, 0x81, 0x0C, 0x24, 0x52, 0x10, 0x48, 0x44, 0x23, 0x03, -0x81, 0x08, 0x04, 0x22, 0x10, 0x68, 0x40, 0x27, 0x01, 0x89, 0x08, 0x34, 0x1A, -0x14, 0x09, 0x50, 0x24, 0x00, 0x89, 0x24, 0x34, 0x52, 0xD1, 0x48, 0x40, 0x20, -0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x28, 0x21, 0x00, 0x91, 0x00, 0x44, 0x02, 0xD2, 0x09, -0x40, 0x27, 0x00, 0x91, 0x00, 0x65, 0x02, 0x14, 0x29, 0x40, 0xA7, 0x01, 0x91, -0x11, 0x44, 0x12, 0x10, 0x09, 0x40, 0x67, 0x00, 0x99, 0x06, 0x64, 0x0A, 0x10, -0x19, 0x40, 0x24, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, -0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x0A, 0xF0, 0x09, 0xC0, -0xA7, 0x01, 0x93, 0x00, 0x6D, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x01, -0x4C, 0x0A, 0x30, 0x69, 0xC0, 0x23, 0x24, 0x9B, 0x00, 0x7C, 0x06, 0x32, 0x18, -0xC0, 0x24, 0x00, 0x9A, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x80, 0x9F, -0x02, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x16, 0x08, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x23, -0x00, 0x8F, 0x00, 0x5C, 0x4E, 0xF0, 0x09, 0xC0, 0x27, 0x44, 0x8F, 0x40, 0x7C, -0x02, 0xF2, 0x09, 0xC2, 0x27, 0x40, 0x87, 0x01, 0x54, 0xCA, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x08, 0x05, 0x04, 0x1F, 0x04, 0x4C, 0x08, 0xB4, 0x01, 0xD0, 0x04, 0x01, -0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x02, 0x4C, 0x08, -0x30, 0x21, 0xC0, 0x84, 0x00, 0x13, 0x01, 0x0C, 0x00, 0xB4, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x06, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x02, 0x4D, -0x48, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0xDC, 0x00, 0x6D, 0x00, 0xC4, 0x05, 0x30, 0x05, 0x40, 0x1C, 0x00, 0x51, -0x00, 0xC5, 0x05, 0x10, 0x07, 0x48, 0x1C, 0x00, 0x51, 0x20, 0x44, 0x01, 0x50, -0x67, 0x40, 0x1C, 0x48, 0x71, 0x10, 0xEC, 0x09, 0x10, 0x15, 0x40, 0x13, 0x00, -0x7D, 0x83, 0xC4, 0x01, 0x00, 0x17, 0x40, 0x1F, 0x00, 0x7D, 0x00, 0xC4, 0x09, -0x10, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, -0xF2, 0x02, 0x8D, 0x02, 0x04, 0x07, 0x50, 0x0C, 0x40, 0xB0, 0x40, 0xC5, 0x00, -0x44, 0x0F, 0x10, 0x8C, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x45, 0x03, 0x18, 0x6C, -0x44, 0x30, 0x20, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x18, 0x40, 0x33, 0x08, 0xCD, -0x03, 0x04, 0x05, 0x10, 0x89, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x05, 0x0B, 0x10, -0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, -0x10, 0x2D, 0x04, 0x84, 0x47, 0x50, 0xDF, 0x42, 0x08, 0x04, 0xE5, 0x00, 0x84, -0x41, 0x10, 0x1E, 0x40, 0x2C, 0x00, 0xF1, 0x00, 0x84, 0x13, 0x50, 0x1E, 0x50, -0x3C, 0x05, 0x41, 0x20, 0xA4, 0x0B, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0xED, 0x03, -0x84, 0x0D, 0x11, 0x02, 0x40, 0x0B, 0x00, 0xED, 0x01, 0x84, 0x07, 0x10, 0x1E, -0x44, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00, -0xAF, 0x07, 0xCD, 0x07, 0x70, 0x1E, 0xC0, 0x40, 0x40, 0x87, 0x89, 0x8C, 0x04, -0x34, 0x1E, 0x10, 0x78, 0x40, 0xE3, 0x31, 0xCC, 0x0F, 0x34, 0x1E, 0xC0, 0xE8, -0x00, 0x63, 0x01, 0x0C, 0x04, 0x34, 0x1A, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0xCC, -0x06, 0x34, 0x12, 0xC0, 0x4B, 0x00, 0xFD, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, -0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x1F, -0x20, 0x7C, 0x03, 0x30, 0x2C, 0xC0, 0x07, 0x00, 0xDB, 0x04, 0x3C, 0x00, 0xF2, -0x05, 0xC0, 0x37, 0x00, 0xDF, 0x06, 0x7C, 0x5B, 0xB0, 0x88, 0xC0, 0x13, 0x00, -0x5F, 0x20, 0x7C, 0x00, 0xF0, 0x0F, 0xC0, 0xB7, 0x0D, 0xDF, 0x00, 0xFC, 0x80, -0xF0, 0x09, 0xC0, 0x07, 0x00, 0xDF, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xC2, 0x43, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x2F, 0x01, -0xDC, 0x13, 0xF0, 0x3F, 0xC0, 0x4C, 0x10, 0xF7, 0x01, 0xDC, 0x04, 0x30, 0x1F, -0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x31, 0x1B, 0xD0, 0x6D, 0x00, 0x73, -0x01, 0x9D, 0x04, 0xB2, 0x4F, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x05, 0x30, -0x1F, 0xC0, 0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x08, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x27, 0x00, 0x84, -0x0A, 0xD0, 0x8F, 0x41, 0x0C, 0x00, 0xE1, 0x00, 0xEC, 0x00, 0x12, 0x4A, 0x40, -0x08, 0x02, 0xE0, 0x00, 0x84, 0x13, 0xA1, 0x0B, 0x40, 0x38, 0x00, 0x61, 0x08, -0x84, 0x02, 0x50, 0x0F, 0x40, 0x3C, 0x02, 0xA7, 0x00, 0xC4, 0x21, 0x12, 0x07, -0x40, 0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40, 0x57, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0x94, 0x23, -0xD0, 0x0E, 0x40, 0x08, 0x00, 0x85, 0x00, 0x94, 0x40, 0x10, 0x0E, 0x40, 0x3C, -0x00, 0xE1, 0x08, 0x84, 0x03, 0x80, 0x02, 0x40, 0x29, 0x02, 0x21, 0x00, 0xD4, -0x00, 0x14, 0x2E, 0x40, 0x38, 0x00, 0x61, 0x00, 0x94, 0x02, 0x10, 0x06, 0x40, -0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x05, 0x00, 0x04, 0x02, 0xD0, -0x1C, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x00, 0x12, 0x31, 0x40, 0x30, 0x00, -0xC1, 0x00, 0x05, 0x83, 0x90, 0x10, 0x40, 0x10, 0x04, 0x41, 0x61, 0x04, 0x04, -0x54, 0x9C, 0x44, 0x30, 0x08, 0x95, 0x00, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x00, -0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xFF, 0x00, 0x5C, 0x03, 0xF0, 0x1F, -0xD0, 0x24, 0x00, 0xD7, 0x00, 0x1C, 0x04, 0x30, 0x8D, 0xD5, 0x60, 0x00, 0xD3, -0x0A, 0xCC, 0x0B, 0xB0, 0x83, 0xD1, 0x39, 0x48, 0x13, 0x10, 0x5D, 0x02, 0x30, -0x0D, 0xC4, 0xA4, 0x00, 0xD3, 0x00, 0x5C, 0x09, 0x30, 0x0D, 0xC0, 0x00, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x07, 0x02, 0xDF, 0x20, 0x5C, 0x08, 0xF4, 0x2D, 0xC0, 0xE7, 0x40, 0xDF, 0x08, -0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1F, 0x20, 0x7C, 0xA2, 0x74, 0x0D, -0xC0, 0x37, 0x01, 0xD7, 0x40, 0x7C, 0x11, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x08, 0x1F, 0x00, 0xB3, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x0B, -0x00, 0xB2, 0x00, 0xCC, 0x00, 0x30, 0x1F, 0xC0, 0x2C, 0x40, 0x97, 0x00, 0x7C, -0x43, 0x32, 0x53, 0xD0, 0x2E, 0x00, 0x13, 0x00, 0xFC, 0x20, 0x20, 0x1F, 0xC0, -0x2F, 0x00, 0xFD, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0C, 0x10, 0x72, 0x00, -0xFC, 0x27, 0xF0, 0x07, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x81, 0x00, 0x06, 0x08, 0x11, 0x00, 0x45, 0x0B, 0xD0, 0x0D, 0xC8, 0x45, 0x00, -0xD1, 0x00, 0x44, 0x04, 0x10, 0xBD, 0x41, 0x64, 0x20, 0x91, 0x08, 0x34, 0x03, -0x12, 0x09, 0x40, 0x15, 0x00, 0x11, 0x01, 0x7C, 0x00, 0x50, 0x1D, 0x40, 0x77, -0x00, 0xDD, 0x09, 0x44, 0x04, 0xD0, 0x3D, 0x48, 0xC4, 0x04, 0xD1, 0x00, 0x74, -0x05, 0xD0, 0xBD, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0xA0, 0x76, 0x00, 0x41, 0x08, 0x44, 0x23, 0xD0, 0x0D, 0x40, 0x47, 0x00, 0xC5, -0x00, 0x44, 0x0C, 0x10, 0x0D, 0x40, 0xE5, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x12, -0x00, 0x41, 0x26, 0x00, 0x11, 0x23, 0x34, 0x00, 0xD8, 0x4D, 0x40, 0x27, 0x01, -0xDD, 0x00, 0x64, 0x44, 0xD0, 0x6C, 0x40, 0x44, 0x80, 0xD5, 0x01, 0x74, 0x03, -0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x70, 0x00, 0x41, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0xC5, 0x00, -0x04, 0x80, 0x14, 0x0C, 0x50, 0x21, 0x00, 0xC1, 0x00, 0x74, 0x83, 0x18, 0x08, -0x50, 0x31, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x00, 0x80, 0x85, 0x01, 0x34, 0x02, 0xD0, -0x0C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x36, -0x00, 0x93, 0x80, 0x4C, 0x81, 0xF0, 0x0F, 0xC0, 0x07, 0x20, 0xB7, 0x00, 0x4D, -0x00, 0x30, 0x0C, 0x44, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x03, 0x31, 0x01, 0xC4, -0x22, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC2, 0x2F, 0x00, 0x4F, 0x40, -0x6C, 0x00, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x57, 0x00, 0x7C, 0x03, 0xF0, 0x05, -0xC4, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, -0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFB, 0x40, 0xFC, 0x00, -0xF0, 0x0F, 0xC0, 0x2A, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x1F, -0x40, 0x3F, 0x00, 0xD8, 0x00, 0x72, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, -0x00, 0xF0, 0x0F, 0xC8, 0x0F, 0x08, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, -0x01, 0xFC, 0x13, 0x32, 0x8B, 0xC2, 0x2C, 0x09, 0xFF, 0x01, 0xFC, 0x63, 0x30, -0x4B, 0xC2, 0x7C, 0x00, 0xBF, 0x04, 0xCC, 0x82, 0x30, 0x2F, 0xC1, 0x7C, 0x00, -0xF3, 0x01, 0xFC, 0x43, 0x30, 0x4F, 0x50, 0x28, 0x00, 0xF3, 0x01, 0xFE, 0x07, -0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF9, 0x01, 0xFC, 0x03, 0xF0, 0x1F, 0xC0, 0x0F, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x01, -0xF4, 0x63, 0x10, 0x81, 0x46, 0xE4, 0x0A, 0xDD, 0x41, 0xF4, 0x0B, 0x50, 0x91, -0x42, 0x74, 0x00, 0x9C, 0x22, 0x44, 0x08, 0x10, 0x2F, 0xC4, 0x34, 0x08, 0xD5, -0x21, 0xF4, 0x0F, 0x41, 0x9F, 0x40, 0xC4, 0x02, 0xD1, 0x01, 0x74, 0x07, 0x10, -0x15, 0x40, 0x74, 0x00, 0xD9, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x0F, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x28, 0xCD, 0x80, 0x34, -0x13, 0x00, 0x08, 0x48, 0x40, 0x20, 0xCD, 0x80, 0x30, 0x03, 0x12, 0x10, 0x40, -0x30, 0x10, 0x0D, 0x1C, 0x04, 0x76, 0x10, 0x4C, 0x40, 0x33, 0x05, 0xC1, 0x40, -0x34, 0x83, 0x80, 0x0C, 0x40, 0x20, 0x08, 0xC1, 0x80, 0x34, 0x03, 0x90, 0x0D, -0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x03, -0x11, 0x11, 0x40, 0x64, 0x00, 0xDD, 0x40, 0x64, 0x03, 0x10, 0x11, 0x40, 0x34, -0x20, 0x09, 0x03, 0x04, 0x06, 0x10, 0x0D, 0x44, 0x35, 0x00, 0xD1, 0x00, 0x74, -0x03, 0x90, 0x0D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x40, -0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x00, 0x0F, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x74, 0x03, 0x30, -0x31, 0xC0, 0x44, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x32, 0x19, 0xC0, 0x34, 0x08, -0x9F, 0x01, 0x4C, 0x04, 0x30, 0x0D, 0xC6, 0x37, 0x00, 0xD1, 0x80, 0x7C, 0x83, -0xA0, 0x0D, 0xC0, 0x64, 0x00, 0xD3, 0x00, 0x74, 0x03, 0xB0, 0x3D, 0xC1, 0x36, -0x00, 0xDF, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x83, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x02, -0xC0, 0x07, 0x00, 0xFF, 0x40, 0xFC, 0x03, 0xF0, 0x00, 0x40, 0x3F, 0x00, 0x9F, -0x20, 0x7C, 0x80, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0x72, -0x0F, 0x40, 0x0B, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0xB0, 0x0F, 0x40, 0x3D, 0x00, -0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0xA9, 0xC0, -0x04, 0x00, 0xD3, 0x60, 0x2C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x00, 0x9B, 0x20, -0x4C, 0x00, 0x30, 0x8C, 0xC0, 0x34, 0x00, 0xD2, 0x00, 0x3C, 0x03, 0x30, 0x0C, -0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x23, 0xF1, 0x2D, 0xC0, 0x37, 0x10, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0x10, 0x31, 0x40, 0x24, -0x00, 0xD1, 0x00, 0xF4, 0x0B, 0x10, 0x09, 0x44, 0x34, 0x00, 0x9D, 0x00, 0x44, -0x02, 0x12, 0xAF, 0x40, 0x74, 0x20, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x0F, 0x40, -0x27, 0x00, 0xD1, 0x80, 0x34, 0x0F, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0xDD, 0x00, -0xF4, 0x03, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x14, 0x08, 0x41, 0x20, 0x00, -0xC1, 0x00, 0x34, 0x0B, 0x10, 0x08, 0x40, 0x30, 0x00, 0x0D, 0x00, 0x04, 0x02, -0x10, 0x2C, 0x40, 0x34, 0x02, 0xC1, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03, -0x00, 0xC5, 0x20, 0x34, 0x4F, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, -0x03, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x80, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x27, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1, -0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x01, 0x84, 0x05, 0x10, -0x1E, 0x40, 0xF8, 0x00, 0xE1, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x5B, 0x00, -0xE1, 0x01, 0xB0, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, -0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, -0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x2D, 0xC0, 0x10, 0x08, 0xC3, 0x08, -0x7C, 0x03, 0x30, 0x44, 0xC0, 0x30, 0x02, 0x4F, 0x00, 0x0C, 0x03, 0x30, 0x8D, -0xE0, 0x34, 0x00, 0xC3, 0x08, 0x7C, 0x23, 0x30, 0x0C, 0xC0, 0x13, 0x00, 0xC7, -0x00, 0x3C, 0x03, 0xF1, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0, -0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x35, -0x10, 0xDF, 0x00, 0x7C, 0x0B, 0xC0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x74, -0x03, 0xF0, 0x05, 0xC0, 0x37, 0x20, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0, -0x37, 0x00, 0xDF, 0x08, 0x7C, 0x83, 0xB4, 0x0D, 0xC1, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, -0xDF, 0x00, 0x7C, 0xB3, 0x30, 0x15, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x4B, -0xF0, 0x0D, 0xC8, 0x37, 0x28, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0xAD, 0xC0, 0x37, -0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x1D, 0xC4, 0x34, 0x10, 0xD3, 0x00, 0x7C, -0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, -0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0, -0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD3, 0x4E, 0x40, 0x3B, 0x00, -0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x4E, 0x41, 0x18, 0x08, 0xE1, 0x80, 0xB4, 0x03, -0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x4F, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01, -0xB0, 0x17, 0x10, 0x1C, 0x51, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x27, 0xD0, 0x1E, -0x40, 0x7B, 0x00, 0x6D, 0x21, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, -0x01, 0xB4, 0x07, 0xD0, 0x1C, 0x40, 0x70, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0, -0x1E, 0x41, 0x7B, 0x80, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x13, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x74, -0x83, 0x10, 0x3C, 0x45, 0xF0, 0x02, 0xCD, 0x00, 0x34, 0x03, 0xD8, 0xBC, 0x40, -0x33, 0x00, 0xDD, 0x01, 0x34, 0x2B, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00, -0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x7C, -0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x60, 0x5B, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0xC0, 0x7C, 0x01, -0x30, 0x17, 0xC0, 0xDC, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x17, 0xC0, 0x17, -0x00, 0x7F, 0x05, 0xFC, 0x25, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, -0x01, 0xF0, 0x05, 0xC0, 0x58, 0x01, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0, -0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5F, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF4, -0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x06, 0x10, -0x1F, 0x41, 0x7C, 0x00, 0xE0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, -0xF0, 0x01, 0xD0, 0xC7, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x59, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, -0x00, 0x4C, 0x02, 0xF0, 0x99, 0xC0, 0x64, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x19, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x76, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, -0x44, 0x02, 0xD0, 0x69, 0xC0, 0xA4, 0x01, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, -0x40, 0xA7, 0x12, 0x91, 0x40, 0x0C, 0x9A, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D, -0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, -0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x20, 0x44, -0x82, 0xD0, 0x09, 0x40, 0x24, 0x0A, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, -0xA7, 0x00, 0x95, 0x00, 0x44, 0x02, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, -0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x58, 0x40, 0x23, 0x01, -0x8D, 0x40, 0x34, 0x16, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x8D, 0x44, 0x04, 0x12, -0xD0, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0xD8, 0x48, 0x40, 0x23, -0x01, 0x91, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, -0x12, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB0, 0x06, 0x00, 0x1F, 0x00, 0x3C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F, -0x00, 0x74, 0x28, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x4D, 0x28, 0xF1, -0xA1, 0x40, 0x84, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, -0x17, 0x00, 0x4D, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, -0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF4, 0x8B, 0xC0, 0x2F, 0x0A, 0x9F, 0x00, -0x7C, 0x22, 0xF0, 0x8B, 0xC0, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x22, 0xF0, 0x89, -0xD0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F, -0x00, 0x5C, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, -0x09, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, -0x00, 0x9F, 0x00, 0x7C, 0x1E, 0xF0, 0xDB, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0xFC, -0x36, 0x34, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x07, 0x4C, 0x1E, 0xF1, 0x7B, 0xD0, -0xAC, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x6F, 0x01, 0x9B, 0x00, -0xFC, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, -0x1D, 0x00, 0x74, 0x3C, 0xD0, 0xF5, 0x42, 0x87, 0x02, 0x1D, 0x00, 0x74, 0x3C, -0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x05, 0x44, 0x1D, 0xD0, 0x71, 0x40, 0x44, -0x01, 0x1D, 0x00, 0x74, 0x08, 0xD0, 0x21, 0x40, 0x97, 0x02, 0x11, 0x00, 0x74, -0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x20, 0xD0, 0x01, 0x40, -0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, -0x00, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x10, -0x28, 0x40, 0x23, 0x00, 0x8D, 0x06, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00, -0x8D, 0x00, 0x34, 0x0A, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34, 0x02, -0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x4B, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, -0x74, 0x02, 0xD0, 0x49, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x69, -0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x24, 0x00, 0x9D, -0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x80, 0x74, 0x82, 0xD0, -0x89, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x16, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x39, 0xC0, -0x27, 0x00, 0x9F, 0x08, 0x4C, 0x06, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x23, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x19, -0x41, 0x27, 0x20, 0x9D, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0x80, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x19, 0xC0, 0x27, -0x00, 0x8F, 0x00, 0x7D, 0x16, 0xF1, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xCA, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x80, 0x5B, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, -0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x00, -0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00, -0xF0, 0x01, 0xC0, 0x87, 0x04, 0x17, 0x00, 0x7C, 0x40, 0xF2, 0x21, 0xC0, 0x04, -0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27, -0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x19, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x5D, -0x00, 0x74, 0x01, 0xD0, 0xC7, 0x40, 0x9F, 0x83, 0x5D, 0x00, 0x74, 0x01, 0xD0, -0x05, 0x40, 0x5F, 0x01, 0x51, 0x00, 0xF4, 0x01, 0x70, 0x05, 0x40, 0x14, 0x00, -0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C, 0x41, -0x33, 0x00, 0xCD, 0x00, 0x34, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, -0x34, 0x03, 0xD0, 0x2C, 0x40, 0xF3, 0x00, 0xCD, 0x40, 0x34, 0x03, 0xD0, 0x0C, -0x40, 0x53, 0x08, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, -0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x41, 0x3B, -0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x04, 0xB4, -0x13, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, -0x1B, 0x00, 0xE1, 0x40, 0xB4, 0x09, 0x50, 0x0F, 0x40, 0x38, 0x00, 0xED, 0x00, -0xB4, 0x03, 0xD0, 0x0E, 0x42, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x17, 0xF0, 0x1E, 0xC0, 0x7B, 0x08, -0xEF, 0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xC2, 0x7B, 0x00, 0xEF, 0x0D, 0xBC, 0x37, -0xF0, 0x16, 0xC0, 0x7B, 0x00, 0xED, 0x41, 0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x5B, -0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF0, 0x0E, 0xC4, 0x78, 0x00, 0xED, 0x01, 0xBC, -0x07, 0xF0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x08, 0x7C, 0x03, 0xF0, -0x05, 0xC4, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x13, 0x10, -0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC8, 0x37, 0x08, 0xDF, 0x00, 0x7C, 0x03, -0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, -0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x63, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0x09, -0xFC, 0x27, 0xF3, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xF8, 0x47, 0x30, 0x1F, -0x48, 0x5F, 0x02, 0xFE, 0x21, 0xFC, 0x07, 0xD0, 0x9F, 0x80, 0x5D, 0x00, 0xF3, -0x09, 0xFC, 0x27, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x09, 0xFC, 0x07, 0xF0, -0x1F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, -0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x41, 0x3B, 0x00, 0xED, 0x00, 0xB4, -0x01, 0xC0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x08, 0xB4, 0x03, 0x14, 0x8E, 0x40, -0x1A, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x42, 0x1C, 0x05, 0xE5, 0x08, -0xB4, 0x09, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x8E, -0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, -0xED, 0x00, 0xB4, 0x23, 0x58, 0x06, 0x40, 0x3B, 0x06, 0xED, 0x80, 0xB0, 0x03, -0xD1, 0x8E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B, -0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x44, 0x3D, 0x00, 0xE5, 0x40, 0xB4, -0x81, 0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0x40, 0xB4, 0x23, 0xD0, 0x0E, 0x40, -0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD, -0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x74, 0x00, 0x90, -0x1C, 0x40, 0x37, 0x10, 0xCD, 0x02, 0x74, 0x27, 0x10, 0x08, 0x08, 0x02, 0x00, -0xC9, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x40, 0x34, 0x01, -0xD1, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x0B, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, -0xFC, 0x03, 0x70, 0x19, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x2D, -0xC3, 0x37, 0x00, 0xFF, 0x44, 0xFC, 0x03, 0x31, 0x09, 0x80, 0x27, 0x10, 0xDE, -0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x45, 0x00, 0xD7, 0x40, 0x78, 0x01, 0xD0, -0x0D, 0xC1, 0x37, 0x10, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C, -0x03, 0xF0, 0x49, 0xC4, 0x37, 0x04, 0xDF, 0x20, 0x7C, 0x0A, 0xF0, 0x0D, 0xC8, -0x37, 0x10, 0xDF, 0x10, 0x7C, 0x43, 0xF0, 0x29, 0xC4, 0x26, 0x20, 0xDB, 0x80, -0x7C, 0x03, 0xF2, 0x0D, 0xC0, 0x87, 0x04, 0xDE, 0x00, 0x7C, 0x09, 0xF1, 0x4D, -0xC0, 0x37, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, -0xF0, 0x03, 0xC0, 0x3B, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x3F, -0x08, 0xF3, 0x00, 0x7C, 0x03, 0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBC, -0x03, 0x34, 0x0F, 0xC0, 0x5F, 0x02, 0xFF, 0x00, 0xFC, 0x05, 0xD0, 0x0F, 0xC4, -0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC4, 0x07, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, -0x79, 0x48, 0x37, 0x30, 0xD1, 0x00, 0x74, 0x1C, 0x10, 0x0D, 0x40, 0x37, 0x00, -0xD1, 0x00, 0x74, 0x03, 0x10, 0x31, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x74, 0x03, -0x10, 0x0D, 0x40, 0x17, 0x01, 0xDD, 0x40, 0x74, 0x8D, 0xD0, 0x0C, 0x48, 0x34, -0x00, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x48, 0x87, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19, -0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x40, 0xD1, -0x00, 0x74, 0x03, 0x10, 0x11, 0x48, 0x47, 0x20, 0xDD, 0x00, 0x74, 0x03, 0x90, -0x0D, 0x40, 0x17, 0x00, 0xDC, 0x00, 0x74, 0x11, 0xD0, 0x0D, 0x42, 0x35, 0x00, -0xDD, 0x40, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD2, 0x08, 0x40, -0x33, 0x00, 0xC1, 0x80, 0x34, 0x02, 0x15, 0x0C, 0x40, 0x37, 0x20, 0xC1, 0xC0, -0x34, 0x03, 0x14, 0x08, 0x44, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C, -0x40, 0x13, 0x00, 0xCD, 0x00, 0x34, 0x01, 0xD0, 0x0D, 0x44, 0x30, 0x00, 0xCD, -0x00, 0x34, 0x03, 0x10, 0x0C, 0x48, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0xF0, 0x01, 0xC4, 0x37, -0x40, 0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xF3, 0x00, 0xFC, -0x03, 0x30, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, -0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0D, 0xC0, 0x35, 0x80, 0xDF, 0x00, -0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x20, -0xFF, 0xC0, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x83, -0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xF8, 0x03, 0x70, 0x0F, 0xC0, 0x1F, -0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFC, -0x03, 0xF2, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA0, 0x7F, 0x00, 0xB3, 0x02, 0xCD, 0x27, 0x30, 0x0B, 0xC0, 0x0C, 0x05, 0x3F, -0x04, 0xFC, 0x07, 0x30, 0x47, 0xC8, 0x3F, 0x05, 0xFF, 0x04, 0xBC, 0xD3, 0x30, -0x9B, 0xC0, 0x2C, 0x01, 0x23, 0x89, 0xCC, 0x12, 0xF0, 0x03, 0xC8, 0x2C, 0x02, -0x33, 0x04, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x7C, 0x18, 0xB3, 0x00, 0xCC, 0x04, -0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, -0x37, 0x11, 0x91, 0x02, 0x44, 0x03, 0x10, 0x1B, 0x50, 0x84, 0x10, 0x1D, 0x0B, -0x74, 0x07, 0x14, 0xBD, 0x40, 0xF7, 0x00, 0xFD, 0x49, 0xF4, 0x0F, 0x12, 0x48, -0x50, 0xFC, 0x40, 0x11, 0x84, 0x44, 0x4A, 0xD0, 0x31, 0x44, 0xAC, 0x23, 0x13, -0x0A, 0x74, 0x03, 0xD1, 0x04, 0x40, 0x34, 0x00, 0xD1, 0x03, 0x45, 0x05, 0xD0, -0x1D, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, -0x04, 0x91, 0x8C, 0x34, 0x13, 0x14, 0x08, 0x40, 0x20, 0x00, 0x0D, 0x00, 0x34, -0x03, 0x10, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40, -0xA0, 0x00, 0x05, 0x00, 0x04, 0x0A, 0xD2, 0x21, 0x40, 0x20, 0x41, 0x81, 0x00, -0x34, 0x03, 0xD8, 0x08, 0x60, 0x32, 0x10, 0xC1, 0x82, 0x04, 0x00, 0xD0, 0x0C, -0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x40, -0x91, 0x01, 0x64, 0x03, 0x10, 0x89, 0x40, 0x64, 0x00, 0x1C, 0x11, 0x74, 0x03, -0x10, 0x1D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x14, 0x09, 0x40, 0x34, -0x00, 0x15, 0x01, 0x45, 0x42, 0xD0, 0x49, 0x40, 0x20, 0xC2, 0x91, 0x03, 0x74, -0x03, 0xD0, 0x0D, 0x50, 0x36, 0x40, 0xD1, 0x01, 0x46, 0x07, 0xD0, 0x0D, 0x40, -0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x83, -0x01, 0x6C, 0x03, 0x30, 0x08, 0xC0, 0x44, 0x20, 0x1E, 0x01, 0x7C, 0x03, 0x30, -0x3D, 0xC0, 0x37, 0x00, 0xDF, 0xC0, 0x7C, 0x03, 0x30, 0x99, 0xC0, 0x24, 0x02, -0x17, 0x81, 0x4C, 0x02, 0xF1, 0x00, 0xD0, 0x24, 0x00, 0x13, 0x01, 0x7C, 0x03, -0xF0, 0x0D, 0xE0, 0x36, 0x00, 0x93, 0x01, 0x4C, 0x04, 0xF2, 0x0D, 0xC2, 0x0B, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x00, -0xDC, 0x03, 0xF0, 0x19, 0xC0, 0x0F, 0x10, 0x3F, 0x00, 0xF4, 0x03, 0xF1, 0x0D, -0xC0, 0x7F, 0x12, 0xFF, 0x10, 0xBC, 0x03, 0xC0, 0x0B, 0xC0, 0x7F, 0x20, 0x3B, -0x00, 0xF8, 0x26, 0xE1, 0x03, 0xC0, 0x27, 0x00, 0x14, 0x00, 0xFC, 0x03, 0xF0, -0x5F, 0xC0, 0xBD, 0x00, 0xEF, 0x00, 0xFC, 0x81, 0xF1, 0x0F, 0xC0, 0x1F, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x93, 0x04, 0x4C, -0x13, 0xF0, 0x09, 0xC4, 0x24, 0x00, 0x13, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x24, 0x00, 0xDF, 0x40, 0x4C, 0x03, 0xB0, 0x09, 0xC8, 0x20, 0x40, 0x13, 0x02, -0x6C, 0x0E, 0xB0, 0x03, 0xC0, 0x37, 0x00, 0x93, 0x06, 0x6C, 0x03, 0xD0, 0x08, -0xC0, 0x34, 0x80, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x0D, 0xC0, 0x0B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x30, 0x00, 0x91, 0x00, 0x44, 0x0B, -0xD0, 0x09, 0x50, 0x64, 0x08, 0x91, 0x00, 0x34, 0x2B, 0xD0, 0x0D, 0x40, 0xB4, -0x02, 0xFD, 0x06, 0xC5, 0x6F, 0x10, 0x49, 0x54, 0xB4, 0x03, 0x10, 0x24, 0x44, -0x06, 0x10, 0xB9, 0x45, 0x37, 0x00, 0x91, 0x83, 0x44, 0x03, 0xD1, 0xAD, 0x40, -0xB4, 0x02, 0xDD, 0x00, 0x74, 0x47, 0x10, 0x1D, 0x43, 0x4F, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x72, 0x00, 0xC1, 0x02, 0x44, 0x8B, 0xD0, -0x68, 0x40, 0x60, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x12, 0x20, -0xCD, 0x02, 0x04, 0x03, 0x90, 0x09, 0x48, 0xF0, 0x10, 0x11, 0x20, 0x04, 0x4A, -0x92, 0x10, 0x40, 0x23, 0x20, 0x09, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x36, -0x10, 0xC5, 0x08, 0x34, 0x04, 0x10, 0x0C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x40, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x9E, -0x40, 0x68, 0x04, 0x25, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x50, 0x58, 0x00, 0xCD, -0x89, 0x84, 0x07, 0x10, 0x9A, 0x40, 0x78, 0x00, 0x31, 0x29, 0x85, 0x04, 0x10, -0x12, 0x40, 0x6B, 0x08, 0xA9, 0x01, 0x84, 0x07, 0xD0, 0x16, 0x50, 0x7A, 0x80, -0xED, 0x41, 0xB4, 0x05, 0x10, 0x1E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x10, 0x30, 0x04, 0x53, 0x00, 0x0E, 0x03, 0xF0, 0x08, 0xD0, -0xA4, 0x40, 0x07, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xCF, 0x00, -0x0C, 0x03, 0xB0, 0x08, 0xC0, 0x30, 0x00, 0x03, 0x4A, 0x6C, 0x02, 0xB0, 0x00, -0xC0, 0x33, 0x41, 0xCB, 0x10, 0x2C, 0x23, 0xF0, 0x0C, 0xD0, 0x32, 0x02, 0xCF, -0x00, 0x3C, 0x00, 0x34, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xB8, 0x39, 0x00, 0xFF, 0x00, 0xFD, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, -0x10, 0x7B, 0x00, 0xFC, 0x03, 0xF8, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, -0x03, 0xF0, 0x0B, 0xC4, 0x3B, 0x00, 0x3F, 0x28, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, -0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x83, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF, 0x08, -0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x49, 0xD0, 0x2C, 0x00, -0x33, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x04, 0x5C, 0x4F, -0x30, 0x09, 0xC0, 0xB5, 0x00, 0x13, 0x00, 0x6C, 0x02, 0xF2, 0x01, 0xC0, 0xA7, -0x01, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, -0x00, 0xF0, 0x0D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x88, 0x39, 0x00, 0xAD, 0x40, 0xB4, 0x03, 0xD0, 0x8C, 0x44, 0x28, 0x00, 0x2B, -0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xCD, 0x0E, 0x04, 0x03, 0x10, -0x0E, 0x40, 0x30, 0x02, 0x61, 0x00, 0x86, 0x00, 0xD0, 0x02, 0x44, 0x23, 0x04, -0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x00, 0xB4, 0x01, -0xD0, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -0x79, 0x00, 0xAD, 0x01, 0xB4, 0x07, 0xD0, 0x1A, 0x40, 0x60, 0x00, 0xA1, 0x41, -0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x05, 0x94, 0x37, 0x10, 0x3B, -0x40, 0x79, 0x08, 0x29, 0x11, 0x84, 0x06, 0xD0, 0x12, 0x40, 0xFB, 0x00, 0xE1, -0x81, 0x94, 0x87, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x05, 0xD0, -0x1E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, -0x10, 0x8D, 0x09, 0x34, 0x03, 0xD0, 0x9C, 0x50, 0x70, 0x00, 0xC9, 0x06, 0x34, -0x03, 0xD0, 0x3C, 0x40, 0xB3, 0x04, 0xCD, 0x00, 0x04, 0x03, 0x14, 0x1C, 0x40, -0x30, 0xC0, 0x99, 0x06, 0x05, 0x01, 0xD1, 0x0C, 0x44, 0x73, 0x20, 0xC1, 0x03, -0x04, 0x03, 0xD1, 0x0D, 0x41, 0x63, 0x00, 0xCD, 0x06, 0x34, 0x07, 0xD0, 0x0C, -0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, -0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x58, 0x01, 0x73, 0x02, 0x7C, 0x01, -0xF0, 0x16, 0xC0, 0x9F, 0x10, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x04, 0xC4, 0x15, -0x00, 0x7B, 0x00, 0xCC, 0x45, 0xF1, 0x07, 0xC0, 0x17, 0x48, 0x73, 0x05, 0x5C, -0x01, 0xF0, 0x27, 0xC0, 0x57, 0x00, 0x7F, 0x02, 0xFC, 0x05, 0xF0, 0x05, 0xC0, -0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, -0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x00, 0xF0, -0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00, -0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00, -0xF0, 0x01, 0xC0, 0x07, 0x12, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x11, -0x4C, 0x22, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09, -0xC1, 0x20, 0x00, 0x83, 0x00, 0x6D, 0x0E, 0xF0, 0x59, 0xC0, 0x20, 0x00, 0x91, -0x40, 0x4C, 0x02, 0x10, 0x89, 0xC0, 0x24, 0x00, 0x83, 0x08, 0x4C, 0x02, 0xF0, -0x19, 0xC0, 0x64, 0x01, 0x90, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x02, 0x91, 0x01, 0x44, -0x06, 0xD0, 0x39, 0x41, 0x64, 0x10, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x50, -0x24, 0x40, 0x91, 0x40, 0x44, 0x02, 0xD0, 0x19, 0x44, 0xE4, 0x40, 0x91, 0x01, -0x04, 0x02, 0x15, 0x08, 0x40, 0x20, 0x00, 0x9B, 0x03, 0x44, 0x02, 0xD0, 0x19, -0x40, 0x20, 0x20, 0x91, 0x09, 0x34, 0x02, 0x10, 0x19, 0x40, 0x07, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x44, 0xC1, 0x04, 0x45, 0x02, -0xD0, 0x49, 0x40, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x34, -0x10, 0x99, 0x00, 0x65, 0x02, 0xC0, 0x09, 0x40, 0x24, 0x01, 0x95, 0x04, 0x44, -0x12, 0x51, 0x29, 0x50, 0x24, 0x20, 0x91, 0x00, 0x44, 0x02, 0xD0, 0x49, 0x50, -0x24, 0x40, 0xDD, 0x80, 0x74, 0x12, 0x10, 0x89, 0x40, 0x63, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x04, 0x04, 0x02, 0xD0, -0x48, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0, 0x49, 0x40, 0x20, 0x01, -0x89, 0x04, 0x04, 0x13, 0xD0, 0x08, 0x40, 0x60, 0x81, 0x85, 0x20, 0x46, 0x12, -0x50, 0x48, 0x40, 0x24, 0x01, 0xC9, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x24, -0x00, 0x8D, 0x04, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x29, 0xF0, 0x01, -0xC0, 0x84, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1B, -0x00, 0x6C, 0x00, 0xD2, 0xA1, 0xC0, 0x04, 0x20, 0x07, 0x2A, 0x4C, 0x28, 0x70, -0x01, 0xD0, 0x84, 0x42, 0x13, 0x0A, 0x4D, 0x28, 0xF0, 0xA1, 0xC0, 0x84, 0x02, -0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0, -0x2F, 0x42, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0, 0x2F, 0x02, 0x97, 0x08, -0x7C, 0x22, 0xF0, 0x0A, 0xD0, 0x2F, 0x22, 0xBB, 0x00, 0xFD, 0x22, 0xB0, 0x8B, -0xD0, 0x2F, 0x02, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x10, 0xB3, -0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB7, 0x0C, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C, -0x02, 0xB3, 0x04, 0x3C, 0x02, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0xCC, -0x16, 0x30, 0x0A, 0xC0, 0x6C, 0x28, 0xBF, 0x00, 0xCC, 0x1E, 0x30, 0x5B, 0xC0, -0x6F, 0x41, 0xB3, 0x05, 0xCC, 0x02, 0xF0, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, -0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x08, 0x07, 0x01, 0x11, 0x0C, 0x6C, 0x40, 0xD0, 0x01, 0x40, 0x04, 0x02, -0x11, 0x00, 0x74, 0x00, 0xD0, 0x81, 0x40, 0x84, 0x10, 0x3D, 0x02, 0x45, 0x08, -0xB0, 0x51, 0x40, 0x04, 0x00, 0x1D, 0x15, 0x45, 0x14, 0x10, 0x01, 0x40, 0xC3, -0x15, 0x11, 0x14, 0x44, 0x10, 0xD1, 0xC1, 0x40, 0x04, 0x04, 0x11, 0x00, 0x74, -0x00, 0xD0, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA0, 0x23, 0x05, 0x85, 0x04, 0x04, 0x12, 0xD0, 0x88, 0x40, 0x70, 0x60, 0x81, -0x08, 0xB4, 0x02, 0xD0, 0x1A, 0x50, 0x6A, 0x02, 0xAD, 0x02, 0x04, 0x22, 0x10, -0x08, 0x61, 0xA0, 0x00, 0x8D, 0x81, 0x04, 0x1A, 0x90, 0x38, 0x40, 0x23, 0x42, -0x81, 0x06, 0x04, 0x52, 0xD1, 0x58, 0x40, 0x20, 0x41, 0xC1, 0x08, 0x34, 0x06, -0xD0, 0x0C, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, -0x21, 0x00, 0x91, 0x10, 0x64, 0x02, 0xD0, 0x89, 0x10, 0x20, 0x01, 0x91, 0x04, -0x74, 0x02, 0xD0, 0x0B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0x44, 0x02, 0x90, 0x09, -0x60, 0x24, 0x00, 0x9D, 0x40, 0x44, 0x02, 0x90, 0x09, 0x40, 0x27, 0x20, 0x91, -0x04, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x30, 0x00, 0x91, 0x11, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, -0x00, 0x97, 0x00, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xD0, -0x24, 0x20, 0x9F, 0x02, 0x4C, 0x06, 0xB0, 0x29, 0xE0, 0x67, 0x02, 0x93, 0x04, -0x4D, 0x02, 0xF0, 0x19, 0xD0, 0x64, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF2, 0x09, -0xD0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x01, 0x7C, 0x02, -0xF0, 0x98, 0xC0, 0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x09, 0x7C, 0x0E, 0x70, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x39, 0xC0, 0xE7, 0x00, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x09, 0xC0, -0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x0F, -0x03, 0x4D, 0x04, 0xF0, 0x11, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, -0x11, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x2C, 0x00, 0xF8, 0x01, 0xC1, 0x06, 0x04, -0x13, 0x00, 0x0C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x02, 0x13, 0x02, 0x7C, 0x00, -0xF0, 0x41, 0xC0, 0x44, 0x02, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x53, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xDC, 0x00, 0x7D, 0x01, -0xC4, 0x15, 0x70, 0x16, 0x40, 0x9C, 0x00, 0x51, 0x01, 0x74, 0x01, 0x14, 0x05, -0x40, 0x57, 0x00, 0x41, 0x00, 0xC4, 0x41, 0xD0, 0x07, 0x40, 0x1C, 0x20, 0x51, -0x04, 0xC4, 0x09, 0xD1, 0x57, 0x40, 0x14, 0x10, 0x7B, 0x00, 0x74, 0x01, 0xD0, -0x37, 0x40, 0x1C, 0x00, 0x51, 0x00, 0x45, 0x01, 0xD0, 0x04, 0x40, 0x53, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x04, 0xCD, 0x01, 0x04, -0x03, 0x50, 0x1C, 0x40, 0xB1, 0x04, 0x81, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40, -0x73, 0x00, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x2D, 0x40, 0x72, 0x00, 0xD1, 0x40, -0x04, 0x2A, 0x58, 0x7C, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x34, 0x27, 0xD0, 0x0D, -0x40, 0x30, 0x00, 0x81, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x53, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xFD, 0x10, 0x84, 0x03, -0x50, 0x06, 0x41, 0x29, 0x01, 0xA1, 0x10, 0xB4, 0x05, 0x10, 0x0E, 0x40, 0x53, -0x04, 0x01, 0x00, 0x84, 0x00, 0xD0, 0x0B, 0x40, 0x4A, 0xC4, 0xA1, 0x00, 0x84, -0x05, 0xD0, 0x12, 0x40, 0x38, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40, -0x38, 0x00, 0xC1, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x17, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, -0x10, 0xC0, 0xFD, 0x40, 0xE3, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x40, -0xE3, 0x01, 0xAC, 0x04, 0xD0, 0x1A, 0xC0, 0x42, 0x00, 0xA3, 0x01, 0x8D, 0x02, -0x78, 0x10, 0xC0, 0x78, 0x04, 0xE3, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, -0x00, 0xE1, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xC0, 0x57, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0x70, 0x01, -0xD0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0x1F, -0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x05, 0x00, 0x8F, 0x02, 0xFC, 0x00, 0xF0, -0x01, 0xD0, 0xB7, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x50, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xA0, 0x6B, 0x00, 0xF3, 0x01, 0xCC, 0x23, 0xB4, 0x13, 0xC0, -0x6C, 0x20, 0xF3, 0x01, 0xCC, 0x07, 0xF0, 0x16, 0xC0, 0x6C, 0x00, 0xF3, 0x01, -0xBC, 0x04, 0x30, 0x1F, 0xD0, 0x4D, 0x00, 0xF3, 0x03, 0xCC, 0x24, 0xF0, 0x13, -0xC0, 0x7F, 0x08, 0xF3, 0x01, 0xDC, 0x06, 0x30, 0x1F, 0xC0, 0x7C, 0x10, 0xF3, -0x81, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x80, 0xB9, 0x00, 0x71, 0x02, 0x84, 0x03, 0x10, 0x02, 0x40, 0x28, -0x00, 0xE1, 0x00, 0xAC, 0x01, 0xC0, 0x06, 0xC0, 0x08, 0x00, 0x21, 0x00, 0x84, -0x08, 0x00, 0x4B, 0x40, 0x08, 0x01, 0xA5, 0x04, 0x94, 0x00, 0xD0, 0x02, 0xC0, -0x39, 0x00, 0xE5, 0x02, 0xC4, 0x02, 0x50, 0x0E, 0x40, 0x1C, 0x00, 0xE1, 0x14, -0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x09, 0x00, 0xE1, 0x00, 0x84, 0x22, 0x18, 0x02, 0x41, 0x38, 0x00, -0xA1, 0x10, 0x84, 0x03, 0xD0, 0x26, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x94, 0x00, -0x10, 0x0A, 0x45, 0x09, 0x20, 0xE1, 0x80, 0x84, 0x08, 0xD8, 0x02, 0x40, 0x33, -0x00, 0xE1, 0x00, 0x94, 0x02, 0x10, 0x0C, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xB4, -0x0B, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, -0x28, 0x13, 0x00, 0x41, 0x00, 0x44, 0x02, 0x14, 0x00, 0x40, 0x20, 0x02, 0x81, -0x01, 0x24, 0x01, 0xD0, 0x04, 0x40, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x14, -0x18, 0x40, 0x40, 0x0A, 0x81, 0x53, 0x14, 0x04, 0xD0, 0x30, 0x40, 0x31, 0x20, -0xC5, 0x02, 0x04, 0x02, 0x50, 0x2C, 0x40, 0x50, 0x00, 0xC1, 0x00, 0x34, 0x23, -0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, -0x21, 0x00, 0xD3, 0x02, 0x4C, 0x03, 0x34, 0x01, 0xD0, 0x1C, 0x50, 0x83, 0x03, -0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x74, 0x40, 0xD3, 0x00, 0x5C, 0x00, 0x30, 0x1D, -0xC8, 0x45, 0xE0, 0x93, 0x05, 0x0C, 0x12, 0xF0, 0x69, 0xC0, 0x37, 0x00, 0xD3, -0x02, 0x5C, 0x02, 0x31, 0x0D, 0xC4, 0x74, 0x24, 0xD3, 0x80, 0x7C, 0x07, 0xF0, -0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA7, -0x40, 0xDF, 0x42, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x97, 0x08, 0x9F, 0x10, 0x5C, -0x00, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x1F, 0x00, 0x5C, 0x08, 0xF0, 0x0D, 0xC0, -0x83, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x02, 0xF0, 0x75, 0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, -0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x21, -0xB3, 0x90, 0xCC, 0x03, 0x30, 0x00, 0xC0, 0x1C, 0x00, 0xDF, 0x00, 0xCC, 0x06, -0xF0, 0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x04, 0x30, 0x4B, 0xC8, 0x04, -0x00, 0xBD, 0x05, 0xFC, 0x02, 0x10, 0x03, 0xC1, 0x7B, 0x00, 0x33, 0x19, 0xCC, -0x02, 0xF0, 0x0A, 0xC0, 0x2C, 0x00, 0xF1, 0x10, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x40, 0x91, -0x02, 0x44, 0x07, 0x10, 0x11, 0x40, 0x94, 0x02, 0xDD, 0x00, 0x44, 0x00, 0xD0, -0x08, 0x40, 0x14, 0x00, 0x01, 0x00, 0x44, 0x00, 0x10, 0x49, 0x40, 0xC4, 0x00, -0x91, 0x00, 0x64, 0x04, 0x10, 0x11, 0x40, 0x37, 0x12, 0xD5, 0x03, 0x44, 0x06, -0xD0, 0x11, 0x50, 0xA4, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x07, -0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xC1, 0x01, -0x44, 0x07, 0x92, 0x11, 0x40, 0xA4, 0x00, 0xDD, 0x00, 0x44, 0x22, 0x50, 0x11, -0x40, 0x24, 0x00, 0xD1, 0x00, 0x44, 0x20, 0x14, 0x04, 0x40, 0x44, 0x04, 0x91, -0x00, 0x74, 0x04, 0xD0, 0x11, 0x44, 0x27, 0x00, 0xC1, 0x00, 0x44, 0x12, 0xD0, -0x4D, 0x51, 0x70, 0x00, 0xD5, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x48, 0x07, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x04, -0x07, 0x90, 0x10, 0x50, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0xD0, 0x00, 0x40, -0x00, 0x40, 0x01, 0x00, 0x06, 0x00, 0x50, 0x04, 0x40, 0x00, 0x00, 0x81, 0x00, -0x64, 0x00, 0xD0, 0x00, 0x00, 0x23, 0x40, 0xC5, 0x20, 0x04, 0x02, 0xD0, 0x0C, -0x48, 0x30, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x43, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x26, 0x00, 0xD3, 0x40, 0x4C, 0x03, -0xB4, 0x01, 0xC0, 0x30, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24, -0x20, 0xD3, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0xAB, 0x00, 0x7C, -0x00, 0xF4, 0x01, 0xC8, 0x2F, 0x40, 0x03, 0x00, 0x4D, 0x02, 0xF0, 0x0D, 0xC0, -0x34, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x80, 0x03, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0x70, -0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, -0x3F, 0x00, 0xFC, 0x00, 0x91, 0x03, 0xC0, 0x0F, 0x10, 0xBB, 0x00, 0xEC, 0x00, -0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, -0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA3, 0x80, 0xC0, 0x0E, 0x02, 0x3A, 0x08, 0xE8, 0x28, -0xB8, 0xA3, 0xC0, 0x8E, 0x02, 0x3A, 0x08, 0xEC, 0x28, 0xA0, 0x83, 0xE0, 0x8E, -0x82, 0x3B, 0x0A, 0xEC, 0x28, 0xA8, 0x83, 0xC0, 0x8E, 0x82, 0x3B, 0x0E, 0xE6, -0x28, 0xA0, 0x83, 0xE0, 0x8E, 0x82, 0x3B, 0x0A, 0xEC, 0x20, 0xB8, 0x83, 0xE0, -0x0E, 0x82, 0x3A, 0x0A, 0xEE, 0x20, 0xB0, 0x03, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x83, 0x22, 0x20, 0x8E, 0x80, 0x3B, 0x02, 0xCA, 0x08, 0xA8, -0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xE0, 0x8E, 0x00, -0x13, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xA0, 0x84, 0x00, 0x3B, 0x02, 0xEC, 0x08, -0x28, 0x23, 0xE0, 0x8A, 0x00, 0x39, 0x02, 0xE8, 0x08, 0xBA, 0x23, 0x40, 0x84, -0x80, 0x3B, 0x00, 0xEE, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x21, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x40, 0x10, 0x20, 0x41, -0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x84, 0x01, 0x12, -0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x00, -0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, -0x12, 0x04, 0x48, 0x10, 0x20, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x83, 0x00, 0x80, 0x0E, 0x00, 0x1A, 0x00, 0x6A, 0x08, 0xA2, 0x61, 0x80, -0x86, 0xA0, 0x1A, 0x00, 0x28, 0x08, 0xA8, 0x01, 0x80, 0x06, 0x00, 0x1A, 0x80, -0x68, 0x08, 0xAA, 0x01, 0x80, 0x86, 0x01, 0x1A, 0x00, 0x68, 0x08, 0xA8, 0x00, -0x80, 0x86, 0x00, 0x3A, 0x02, 0x68, 0x00, 0xA0, 0x01, 0x80, 0x0E, 0x00, 0x0A, -0x04, 0x60, 0x00, 0xA0, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA0, 0x12, 0xA0, 0x4E, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0xA0, 0x4E, -0x81, 0x3A, 0x01, 0xE8, 0x04, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xE8, -0x34, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA8, 0x13, 0xA0, -0x4E, 0x80, 0x2A, 0x01, 0xA8, 0x04, 0xA8, 0x12, 0xA0, 0x4E, 0x80, 0x32, 0x01, -0xEA, 0x04, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, -0x02, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x06, 0x00, -0x18, 0x01, 0x62, 0x00, 0x80, 0x81, 0x00, 0x06, 0x01, 0x18, 0x00, 0x42, 0x00, -0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x10, 0x80, 0x01, 0x00, 0x06, -0x03, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, -0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x82, -0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x14, 0x00, 0x10, 0x20, 0x84, 0x80, 0x10, -0x08, 0x42, 0x10, 0x08, 0x11, 0x20, 0x04, 0x80, 0x10, 0x0C, 0x42, 0x08, 0x08, -0x11, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x11, 0x20, 0x04, 0x80, -0x10, 0x04, 0x42, 0x04, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04, -0x08, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xF2, 0xA0, -0x02, 0x03, 0x0A, 0x04, 0x28, 0x1C, 0xAA, 0x50, 0xA0, 0x02, 0x01, 0x0A, 0x06, -0x2A, 0x10, 0xA0, 0xD0, 0x80, 0x02, 0x01, 0x0A, 0x04, 0x0A, 0x30, 0xA0, 0x50, -0xA0, 0x02, 0x01, 0x0A, 0x0E, 0x28, 0x10, 0xA0, 0x50, 0x80, 0x82, 0x01, 0x0A, -0x04, 0x2A, 0x14, 0xA0, 0x40, 0x80, 0x02, 0x01, 0x2A, 0x05, 0x28, 0x3C, 0xA8, -0x00, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x80, 0xC8, -0x00, 0xA2, 0x03, 0xA8, 0x2E, 0xA0, 0x32, 0x80, 0xEA, 0x00, 0xAA, 0x03, 0x08, -0x0C, 0xA0, 0x3A, 0x80, 0x6A, 0x00, 0x82, 0x01, 0x08, 0x0C, 0x20, 0x3A, 0x80, -0x6A, 0x00, 0x82, 0x03, 0x08, 0x0C, 0xA0, 0x3A, 0x80, 0xEA, 0x01, 0xA2, 0x03, -0x08, 0x0E, 0xA0, 0x3A, 0x80, 0xE0, 0x00, 0xAA, 0x03, 0x08, 0x1C, 0x20, 0x02, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x08, 0x80, -0x30, 0x01, 0x20, 0x18, 0x80, 0x00, 0x00, 0xC2, 0x01, 0x08, 0x02, 0x00, 0x04, -0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x02, 0x00, 0x82, -0x00, 0x10, 0x06, 0x00, 0x04, 0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x44, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x82, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16, 0x40, 0x18, 0x00, 0x61, -0x00, 0x04, 0x21, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x01, 0x06, 0x01, 0x10, -0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x10, 0x06, 0x40, 0x10, 0x80, -0x41, 0x00, 0x06, 0x01, 0x10, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, -0x10, 0x04, 0x60, 0x14, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A, 0x00, -0x6D, 0x02, 0xA0, 0x01, 0xA0, 0x26, 0x40, 0x9B, 0x00, 0x4A, 0x00, 0xB0, 0x09, -0x88, 0x26, 0x80, 0x92, 0x00, 0x48, 0x00, 0x80, 0x09, 0xA0, 0x26, 0x40, 0x92, -0x00, 0x48, 0x00, 0xB0, 0x09, 0x80, 0x26, 0x80, 0x9A, 0x00, 0x4A, 0x02, 0xA8, -0x09, 0xA0, 0x24, 0x80, 0x9B, 0x00, 0x4A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x1A, 0x01, 0x68, -0x00, 0xB0, 0x01, 0xC0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x04, 0xA8, 0x01, 0xC0, -0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xB0, 0x01, 0xE0, 0x06, 0x80, 0x1B, 0x00, -0x6E, 0x04, 0xA8, 0x01, 0xC8, 0x06, 0x00, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01, -0xE0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x8C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x20, 0x0C, 0x81, 0x31, 0x0C, 0x82, 0x10, -0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x20, 0x0C, -0x01, 0x30, 0x0C, 0xC2, 0x30, 0x10, 0x43, 0x20, 0x0C, 0x03, 0x30, 0x0C, 0xC0, -0x30, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x0C, 0xC0, 0x10, 0x08, 0x43, 0x00, -0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, -0x03, 0x00, 0x0C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x4C, 0x00, -0x30, 0x01, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, -0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x08, 0x08, -0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x21, 0x40, 0x80, 0x4C, 0x23, 0x32, 0x04, 0xCA, 0x10, 0x20, 0x43, -0x80, 0x0C, 0x03, 0x32, 0x0C, 0xCA, 0x10, 0x20, 0x43, 0x88, 0x4C, 0x23, 0x32, -0x05, 0xC8, 0x14, 0x20, 0x43, 0x80, 0x4C, 0x81, 0x32, 0x05, 0xCA, 0x10, 0x20, -0x43, 0x80, 0x48, 0x03, 0x32, 0x05, 0x88, 0x10, 0x20, 0xD3, 0xA0, 0x0C, 0x03, -0x32, 0x04, 0xCA, 0x10, 0x20, 0x03, 0x84, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA2, 0x42, 0xA0, 0x06, 0x83, 0x3A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0, -0x06, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x0C, -0x4A, 0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0x88, 0x41, -0xA0, 0x06, 0x01, 0x0A, 0x0C, 0x08, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x83, 0x1A, -0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA3, 0x40, 0x00, 0x04, 0x01, 0x18, 0x04, 0xC0, 0x10, 0x00, 0x41, 0x00, 0x04, -0x01, 0x20, 0x04, 0x40, 0x10, 0x00, 0x42, 0x00, 0x00, 0x01, 0x10, 0x04, 0x40, -0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x00, 0x10, 0x00, 0x43, 0x00, -0x00, 0x81, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04, -0x40, 0x10, 0x00, 0x01, 0x8C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, -0x4A, 0x20, 0x2C, 0x81, 0x10, 0x0C, 0x82, 0x12, 0x88, 0x41, 0x20, 0x26, 0x81, -0xB0, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26, 0x83, 0x90, 0x04, 0x02, 0x12, -0x08, 0x41, 0x00, 0x26, 0x81, 0x90, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26, -0x83, 0x90, 0x04, 0x40, 0x10, 0x88, 0xC9, 0x20, 0x0C, 0x81, 0xB0, 0x04, 0x62, -0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06, -0x20, 0x1A, 0x00, 0x62, 0x00, 0x88, 0x01, 0xA8, 0x06, 0xA0, 0x1A, 0x80, 0x62, -0x00, 0x80, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80, 0x42, 0x00, 0x0A, 0x01, 0xA0, -0x06, 0x80, 0x18, 0x00, 0x6A, 0x00, 0x88, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80, -0x6A, 0x80, 0x08, 0x01, 0xA8, 0x06, 0x80, 0x18, 0x80, 0x62, 0x00, 0xA8, 0x01, -0x88, 0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, -0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06, -0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60, -0xA0, 0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, -0x06, 0xAA, 0x18, 0xA0, 0x60, 0x80, 0x8A, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x20, -0x81, 0x02, 0x84, 0x08, 0x12, 0x20, 0x40, 0x80, 0x20, 0x81, 0x82, 0x04, 0x08, -0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04, 0x4A, 0x12, 0x20, 0x40, 0x80, -0x20, 0x01, 0x82, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04, -0x08, 0x10, 0x20, 0x48, 0x80, 0x00, 0x01, 0x82, 0x04, 0x48, 0x12, 0x20, 0x00, -0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62, 0xC0, 0x80, 0x01, -0x03, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAE, 0x18, -0xB0, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xA0, 0x62, 0xC0, 0x8A, -0x81, 0x29, 0x06, 0xAE, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xA6, -0x18, 0xB0, 0x62, 0x60, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x8C, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A, -0x06, 0xEE, 0x18, 0xA4, 0x63, 0x80, 0x8E, 0x81, 0x3A, 0x06, 0xE8, 0x18, 0xB0, -0x63, 0x80, 0x8E, 0x01, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0x80, 0x8E, 0x81, -0x3A, 0x06, 0xE0, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x81, 0x3B, 0x06, 0xE8, 0x18, -0xA8, 0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x03, 0x8C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xC0, 0x8E, 0x01, 0x3A, 0x06, -0xE8, 0x18, 0xB0, 0x63, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xCC, 0x18, 0xA0, 0x63, -0xC0, 0x8E, 0x01, 0x3B, 0x86, 0xEA, 0x18, 0x30, 0x63, 0xC0, 0x8E, 0x01, 0x3B, -0x06, 0xCC, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01, 0x3B, 0x06, 0xEC, 0x18, 0xB0, -0x63, 0xE0, 0x8E, 0x81, 0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x31, 0x06, 0xC2, -0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xC2, 0x18, 0x0A, 0x63, 0xA0, -0x8E, 0x01, 0x10, 0x06, 0xC4, 0x18, 0x30, 0x63, 0x00, 0x8C, 0x21, 0x10, 0x06, -0xC0, 0x18, 0x08, 0x61, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0x80, 0x18, 0xA8, 0x63, -0x00, 0x84, 0x81, 0x38, 0x06, 0xEE, 0x18, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04, 0x01, 0x1A, 0x04, 0xE8, 0x10, -0x20, 0x41, 0x80, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0xA0, 0x43, 0x80, 0x04, -0x01, 0x12, 0x04, 0x68, 0x10, 0x20, 0x41, 0x00, 0x04, 0x01, 0x12, 0x04, 0x48, -0x10, 0x20, 0x43, 0x80, 0x04, 0x01, 0x32, 0x04, 0x68, 0x10, 0x20, 0x41, 0x80, -0x04, 0x01, 0x32, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x01, 0x12, 0x06, 0x6A, 0x18, 0xA0, -0x60, 0x88, 0x86, 0x81, 0x1A, 0x06, 0x48, 0x18, 0xA8, 0x60, 0x00, 0x82, 0x01, -0x02, 0x86, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x48, 0x18, -0xA8, 0x61, 0x88, 0x86, 0x01, 0x1A, 0x06, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84, -0x01, 0x18, 0x06, 0x68, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00, 0x28, 0x03, -0xA0, 0x0A, 0x80, 0x32, 0x00, 0xC8, 0x00, 0xA8, 0x02, 0xA0, 0x0C, 0x00, 0x32, -0x00, 0xC8, 0x00, 0xA8, 0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xC8, 0x00, 0xA8, -0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xE8, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80, -0x32, 0x00, 0xCA, 0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA2, 0x42, 0x00, 0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, -0x06, 0x01, 0x10, 0x0C, 0x42, 0x10, 0x80, 0x41, 0x00, 0x04, 0x83, 0x10, 0x0C, -0x40, 0x10, 0x80, 0xC1, 0x00, 0x04, 0x83, 0x10, 0x04, 0x42, 0x10, 0x80, 0xC1, -0x00, 0x04, 0x83, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xC0, 0x00, 0x04, 0x03, 0x10, -0x04, 0x60, 0x10, 0x80, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA2, 0x42, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04, -0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x60, -0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, -0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x05, -0x42, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, -0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xA8, 0x30, 0xA8, 0x42, 0xA0, 0x02, 0x03, -0x2A, 0x04, 0xAA, 0x10, 0xA0, 0xC0, 0xA0, 0x0A, 0x81, 0x2A, 0x84, 0xA0, 0x10, -0xA0, 0x40, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xAA, 0x10, 0xA0, 0x40, 0xA8, 0x0A, -0x81, 0x2A, 0x04, 0x2A, 0x10, 0xA8, 0x42, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xA8, -0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A, -0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x04, 0xA8, 0x30, 0xA0, -0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, -0x2A, 0x04, 0xA8, 0x30, 0xA0, 0x42, 0x80, 0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30, -0xA0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, -0x42, 0x80, 0x08, 0x00, 0x20, 0x00, 0x80, 0x10, 0x00, 0x02, 0x80, 0x08, 0x00, -0x20, 0x04, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x22, 0x04, 0x80, 0x00, -0x00, 0x02, 0x20, 0x08, 0x00, 0x20, 0x04, 0x80, 0x00, 0x00, 0x02, 0x20, 0x08, -0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x60, 0x04, 0x80, -0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00, -0x01, 0x01, 0x05, 0x04, 0x14, 0x10, 0x40, 0x40, 0x40, 0x01, 0x01, 0x0C, 0x44, -0x10, 0x10, 0x50, 0x40, 0x00, 0x81, 0x01, 0x04, 0x00, 0x30, 0x00, 0x50, 0x00, -0x00, 0x81, 0x01, 0x0C, 0x06, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01, 0x04, -0x46, 0x14, 0x10, 0x40, 0x60, 0x44, 0x01, 0x01, 0x04, 0x04, 0x30, 0x10, 0x00, -0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0xA0, 0x06, 0x80, -0x1A, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00, -0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0xA0, 0x06, -0x80, 0x1A, 0x00, 0x68, 0x00, 0xB0, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A, -0x00, 0xA8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x88, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x12, -0x00, 0xE8, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x80, 0x3A, 0x00, 0x4C, 0x00, 0xA0, -0x03, 0xC0, 0x06, 0x80, 0x13, 0x00, 0x4E, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, -0x13, 0x00, 0x6E, 0x00, 0xA0, 0x03, 0xC0, 0x06, 0x00, 0x1B, 0x00, 0x4C, 0x00, -0xB0, 0x01, 0xC0, 0x04, 0x00, 0x3A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x11, 0x00, -0x62, 0x00, 0x08, 0x02, 0x20, 0x0C, 0x80, 0x18, 0x00, 0x42, 0x00, 0x8A, 0x01, -0x20, 0x0C, 0x02, 0x10, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x0C, 0x02, 0x10, -0x00, 0x40, 0x00, 0x80, 0x01, 0x20, 0x0C, 0x00, 0x10, 0x00, 0x40, 0x00, 0x08, -0x83, 0x00, 0x04, 0x80, 0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x90, 0x00, 0x40, -0x02, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x00, -0xA8, 0x01, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x02, 0xAC, 0x08, 0x90, 0x22, -0x40, 0x02, 0x00, 0x21, 0x00, 0xAC, 0x05, 0x90, 0x22, 0x40, 0x08, 0x00, 0x2B, -0x02, 0xA4, 0x00, 0x90, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x8C, 0x00, 0x32, 0x0A, 0xCA, 0x28, -0x22, 0xA3, 0x80, 0x8C, 0x02, 0x32, 0x06, 0x48, 0x28, 0x28, 0xA2, 0x88, 0x8C, -0x82, 0x12, 0x00, 0x48, 0x08, 0x20, 0xA1, 0x80, 0x8C, 0x03, 0x32, 0x00, 0x48, -0x28, 0x28, 0xA2, 0x80, 0x8C, 0x00, 0x22, 0x06, 0x08, 0x38, 0x20, 0xA3, 0x80, -0x84, 0x82, 0x32, 0x02, 0xCA, 0x08, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x4A, 0x31, 0xA8, -0xC5, 0xA0, 0x16, 0x83, 0x5A, 0x0E, 0x68, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x83, -0x5A, 0x0C, 0x60, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x03, 0x5A, 0x0C, 0x6A, 0x31, -0xA8, 0xC5, 0xA0, 0x16, 0x03, 0x58, 0x0E, 0x28, 0x31, 0xA8, 0xE4, 0x80, 0x12, -0x82, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x90, 0x01, 0x40, 0x06, 0x00, 0x09, -0x00, 0x64, 0x00, 0x90, 0x00, 0x42, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x00, 0x90, -0x00, 0x40, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x80, 0x90, 0x08, 0x40, 0x02, 0x00, -0x31, 0x00, 0xA4, 0x80, 0x80, 0x00, 0x42, 0x0C, 0x00, 0x09, 0x20, 0x64, 0x02, -0x90, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x22, 0x42, 0x88, 0x18, 0x20, 0x42, 0x80, 0x88, 0x11, 0x22, -0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, -0x60, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x21, -0x26, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x21, 0x22, 0x06, 0x88, 0x18, -0x20, 0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0x08, 0x00, 0xA8, 0x02, 0xA2, 0x0A, -0x84, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6, 0x0A, 0x1C, 0x2A, 0x28, 0xA8, -0xC0, 0xA0, 0x02, 0xA2, 0x0A, 0x88, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA2, -0x0A, 0x88, 0x2A, 0xA0, 0xAA, 0x80, 0xA9, 0x02, 0xA2, 0x0A, 0x18, 0x28, 0x20, -0xA8, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0xA8, 0x04, 0xA0, 0x12, 0x80, 0x42, 0x10, -0x2A, 0x41, 0x28, 0x84, 0xA1, 0x10, 0x84, 0x4A, 0x10, 0x2A, 0x61, 0xA8, 0x04, -0xA1, 0x10, 0x84, 0x4A, 0x18, 0x2A, 0x61, 0xA8, 0x44, 0xA1, 0x10, 0x84, 0x4A, -0x14, 0x2A, 0x61, 0xA8, 0x04, 0xA1, 0x12, 0x84, 0x4A, 0x10, 0x2A, 0x01, 0xA8, -0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, -0x80, 0x40, 0x81, 0x02, 0x8D, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x83, 0x02, -0x05, 0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20, -0x50, 0x00, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x28, 0x50, 0x80, 0x40, 0x01, -0x02, 0x85, 0x00, 0x14, 0x20, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14, -0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, -0xCA, 0x00, 0x2B, 0x03, 0xA4, 0x0C, 0x10, 0x32, 0xC0, 0xCA, 0x00, 0x01, 0x03, -0x0C, 0x0C, 0xB0, 0x32, 0x40, 0xC0, 0x80, 0x21, 0x03, 0x86, 0x0C, 0xA1, 0x32, -0x00, 0xC8, 0x80, 0x01, 0x03, 0x86, 0x0C, 0xA0, 0x32, 0x40, 0xC8, 0x00, 0x20, -0x03, 0x86, 0x0C, 0x10, 0x30, 0x60, 0xC8, 0x20, 0x21, 0x03, 0x84, 0x0C, 0xB0, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA2, 0x4E, -0x80, 0x3A, 0x09, 0xEE, 0x04, 0xA0, 0x13, 0x80, 0x4E, 0x82, 0x3A, 0x11, 0xEA, -0x04, 0xB8, 0x13, 0x90, 0x4E, 0x90, 0x3A, 0x21, 0x6A, 0x04, 0xA8, 0x13, 0xA0, -0x4E, 0x88, 0x3A, 0x21, 0xCA, 0x04, 0xA8, 0x13, 0x10, 0x4C, 0x84, 0x32, 0x01, -0xE8, 0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x01, 0xEA, 0x04, 0xA9, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x03, -0x08, 0x8C, 0x20, 0x32, 0x80, 0xC4, 0x08, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, -0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0, 0x18, 0x02, -0x03, 0x08, 0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20, -0x30, 0x86, 0xC0, 0x00, 0x02, 0x23, 0x08, 0x0C, 0x20, 0x31, 0x84, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, -0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, -0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, -0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, -0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 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, 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, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, -0xED, 0xBF, 0x34, 0xFB, 0xD2, 0xFE, 0xCB, 0xFF, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB, -0xF0, 0xFF, 0xCB, 0xFF, 0x2F, 0xED, 0xBF, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xFF, -0x2F, 0xCD, 0xBE, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xB7, 0x2F, 0xDF, 0x36, 0x7C, -0xDB, 0xF0, 0x6D, 0x43, 0xB3, 0x2F, 0xED, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3, -0xBF, 0xCC, 0xFC, 0x32, 0xFF, 0xCB, 0xFF, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0xF2, -0xFF, 0xCB, 0xFF, 0x2F, 0xF3, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, -0x33, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xCF, 0x2F, 0x3F, 0x8F, 0xFC, 0x3C, -0xF2, 0xF3, 0xC8, 0xCC, 0x2F, 0xF3, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x63, 0x48, 0xEC, 0x21, 0xB1, 0x9F, -0xDC, 0x7E, 0x12, 0x7B, 0x48, 0x8C, 0x21, 0xB7, 0x87, 0xC4, 0x7E, 0x12, 0x63, -0x48, 0x8C, 0x21, 0x37, 0x86, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB7, -0x87, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB1, 0x9F, 0xC4, 0x18, 0x12, -0x7B, 0x48, 0x8C, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x00, 0x0E, 0x02, 0x39, 0x0A, 0xE4, 0x20, 0x90, 0x83, -0x00, 0x0E, 0x02, 0x39, 0x08, 0xE0, 0x20, 0x80, 0x83, 0x40, 0x0E, 0x02, 0x39, -0x08, 0xE4, 0x20, 0x90, 0x83, 0x00, 0x0E, 0x02, 0x38, 0x0A, 0xE4, 0x20, 0x80, -0x83, 0x40, 0x0E, 0x02, 0x38, 0x06, 0xE6, 0x20, 0x90, 0xA3, 0x40, 0x0E, 0x02, -0x39, 0x08, 0xE4, 0x28, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x20, 0x60, 0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0xA0, -0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xB8, 0x23, 0xA0, 0x8E, 0x00, 0x3A, 0x02, -0xE8, 0x08, 0xA0, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, -0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEE, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A, -0x02, 0xEA, 0x08, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x40, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, -0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, -0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, -0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x61, 0x80, 0x04, 0x01, 0x12, 0x04, -0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x0E, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20, 0x06, 0x00, -0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, -0x80, 0x01, 0x28, 0x06, 0x80, 0x18, 0x02, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06, -0x80, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, -0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x20, 0x4E, 0x00, 0x38, 0x05, 0xE2, 0x04, 0x80, 0x13, 0x20, 0x4E, 0x00, 0x38, -0x09, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x00, 0x38, 0x01, 0xE0, 0x04, 0x80, -0x13, 0x20, 0x4E, 0x82, 0x38, 0x05, 0xE2, 0x04, 0x88, 0x12, 0x20, 0x4E, 0x80, -0x38, 0xA1, 0xE2, 0x04, 0x28, 0x51, 0x20, 0x4E, 0x80, 0x30, 0x01, 0xE2, 0x14, -0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x80, 0x18, 0x00, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00, -0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x81, -0x00, 0x06, 0x02, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, -0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x08, 0x10, 0x00, 0x60, 0x00, 0x80, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x24, -0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x29, 0x20, 0x24, 0x80, 0x90, 0x02, 0x42, -0x02, 0x08, 0x11, 0x20, 0x24, 0x80, 0x90, 0x00, 0x42, 0x02, 0x08, 0x09, 0x20, -0xA4, 0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x11, 0x20, 0xA4, 0x80, 0x90, 0x01, -0x42, 0x04, 0x08, 0x39, 0x20, 0x44, 0x80, 0x18, 0x01, 0x42, 0x06, 0x08, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x12, 0x81, -0x48, 0x05, 0x22, 0x11, 0x88, 0x44, 0x00, 0x12, 0x81, 0x48, 0x04, 0x20, 0x31, -0x80, 0x54, 0x20, 0x12, 0x81, 0x48, 0x04, 0x22, 0x11, 0x88, 0xC4, 0x00, 0x12, -0x03, 0x48, 0x0D, 0x22, 0x11, 0x80, 0x54, 0x20, 0x12, 0x01, 0x48, 0x05, 0x20, -0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x68, 0x0D, 0x22, 0x1D, 0x88, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30, 0x00, 0xC8, 0x00, 0x00, -0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00, 0x20, 0x03, 0xA0, 0x0C, 0x00, -0x32, 0x00, 0xC0, 0x02, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00, -0x28, 0x03, 0x80, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C, -0x80, 0x72, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x1C, 0x80, 0x02, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x20, 0x2C, 0x00, 0x90, 0x00, -0x00, 0x02, 0x00, 0x78, 0x00, 0x26, 0x00, 0x90, 0x03, 0x60, 0x02, 0x08, 0x03, -0x00, 0x20, 0x00, 0x90, 0x00, 0x40, 0x02, 0x00, 0x19, 0x00, 0xE2, 0x00, 0x88, -0x00, 0x80, 0x06, 0x80, 0x00, 0x00, 0xE2, 0x01, 0x88, 0x00, 0x20, 0x00, 0x80, -0x28, 0x00, 0x02, 0x00, 0x08, 0x00, 0x80, 0x0A, 0x80, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x80, 0x01, 0x00, 0x04, -0x00, 0x18, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, -0x00, 0x82, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x20, 0x06, 0x80, 0x10, 0x00, 0x42, 0x00, -0x08, 0x01, 0x60, 0x06, 0x80, 0x10, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x04, -0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x40, 0x06, 0x80, 0x19, 0x00, 0x62, -0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20, -0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x08, 0x80, 0x02, 0x00, 0x06, 0x00, 0x19, 0x00, 0x64, 0x00, 0x90, -0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x80, 0x01, 0x40, 0x06, 0x00, -0x19, 0x00, 0x64, 0x00, 0x90, 0x11, 0x00, 0x46, 0x00, 0x18, 0x00, 0x64, 0x04, -0x80, 0x01, 0x40, 0x46, 0x00, 0x18, 0x00, 0x66, 0x00, 0x90, 0x01, 0x40, 0x06, -0x00, 0x19, 0x00, 0x64, 0x00, 0x90, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xA2, 0x42, 0x60, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43, -0x20, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x20, 0x0C, 0x01, 0x30, -0x04, 0xC0, 0x10, 0x00, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, -0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81, -0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x10, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, -0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, -0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, -0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, -0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x00, 0xD0, 0x00, 0x4C, 0x03, 0x30, 0x04, 0xC0, 0x34, 0x00, 0xC3, 0x20, 0x4C, -0x03, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x43, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, -0x34, 0x00, 0xC3, 0x20, 0x0C, 0x83, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00, -0x0C, 0x83, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04, -0xC0, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, -0xC2, 0x20, 0x0E, 0x03, 0x10, 0x04, 0x62, 0x30, 0x00, 0xC1, 0x20, 0x06, 0x03, -0x10, 0x0C, 0x62, 0x30, 0x88, 0x43, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x40, 0x30, -0x00, 0xC1, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x30, 0x88, 0x41, 0x20, 0x06, -0x83, 0x18, 0x04, 0x60, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, -0x10, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42, -0x00, 0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x0C, 0x81, 0x10, -0x04, 0xC0, 0x10, 0x80, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, -0x41, 0x00, 0x08, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00, 0x04, 0x01, -0x30, 0x04, 0x42, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, -0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20, -0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x0C, 0x81, 0x10, 0x04, -0xC2, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41, -0x20, 0x0C, 0x83, 0x30, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x30, -0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x00, 0x08, -0x80, 0x00, 0x00, 0xA2, 0x00, 0x08, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80, -0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x20, 0x00, 0x82, 0x00, 0x08, 0x02, 0x00, -0x08, 0x00, 0x20, 0x00, 0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x00, 0x20, 0x00, -0xA0, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x42, -0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01, -0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, -0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, -0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, -0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x28, 0x06, 0x20, 0x18, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0xA0, 0x00, 0x01, 0x02, -0x04, 0x08, 0x10, 0x20, 0x41, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x28, -0x40, 0x80, 0x04, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, -0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, -0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, -0xAC, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62, -0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAE, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x01, 0x2B, -0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, -0x62, 0xC0, 0x8A, 0x01, 0x29, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, -0x18, 0x88, 0x63, 0x60, 0x8E, 0x81, 0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20, -0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x50, 0x8E, 0x81, 0x39, 0x06, -0xE2, 0x18, 0x98, 0x63, 0x20, 0x8E, 0x81, 0x39, 0x04, 0xE2, 0x18, 0x88, 0x63, -0x20, 0x8E, 0x81, 0x3A, 0x06, 0xE2, 0x18, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x80, 0x62, 0x00, 0x8E, 0x01, 0x3B, 0x06, 0xE4, 0x18, -0xB0, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x63, 0x40, 0x8E, -0x01, 0x39, 0x06, 0xEC, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x01, 0x38, 0x06, 0xE4, -0x18, 0x80, 0x63, 0x40, 0x8E, 0x01, 0x38, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x40, -0x0E, 0x01, 0x39, 0x06, 0xE4, 0x18, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0A, 0xA2, 0x62, 0x60, 0x8C, 0x01, 0x30, 0x06, 0xEA, 0x18, 0x80, -0x63, 0x20, 0x8C, 0x01, 0x30, 0x06, 0xC2, 0x18, 0x18, 0x63, 0xA0, 0x8E, 0x01, -0x30, 0x06, 0xC0, 0x18, 0x00, 0x63, 0x20, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18, -0x08, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E, -0x81, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x00, 0x48, 0x00, 0x24, 0x01, 0x9A, 0x04, 0x48, 0x12, 0x20, 0x49, -0x80, 0x2E, 0x01, 0x90, 0x04, 0xE8, 0x12, 0x00, 0x49, 0x80, 0x24, 0x01, 0x90, -0x04, 0x68, 0x12, 0xA0, 0x41, 0x80, 0x2C, 0x01, 0xBA, 0x04, 0x48, 0x10, 0xA0, -0x43, 0x80, 0x24, 0x01, 0xBA, 0x04, 0x48, 0x10, 0x20, 0x49, 0x80, 0x04, 0x01, -0x92, 0x04, 0x48, 0x12, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x60, 0x00, 0x84, 0x01, 0x10, 0x06, 0x60, 0x18, 0x00, 0x61, 0x20, -0x86, 0x01, 0x10, 0x06, 0x62, 0x18, 0x00, 0x61, 0x00, 0x86, 0x01, 0x10, 0x06, -0x40, 0x18, 0x00, 0x61, 0x20, 0x86, 0x81, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61, -0x00, 0x86, 0x81, 0x58, 0x06, 0x60, 0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18, -0x06, 0x60, 0x18, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA2, 0x06, 0x20, 0x1E, 0x00, 0x70, 0x00, 0xC2, 0x01, 0x00, 0x07, 0x20, 0x1E, -0x00, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1C, 0x00, 0x70, 0x00, 0xC0, -0x01, 0x00, 0x07, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xE2, 0x01, 0x88, 0x07, 0x20, -0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00, -0xE2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, -0x4A, 0x00, 0x26, 0x83, 0x90, 0x04, 0x40, 0x12, 0x08, 0x49, 0x00, 0x26, 0x81, -0x90, 0x04, 0x40, 0x12, 0x80, 0x49, 0x00, 0x24, 0x81, 0x90, 0x04, 0x42, 0x12, -0x08, 0x41, 0x00, 0x24, 0x01, 0x90, 0x04, 0x60, 0x10, 0x80, 0x41, 0x00, 0x26, -0x01, 0x98, 0x04, 0x40, 0x10, 0x80, 0x49, 0x00, 0x06, 0x01, 0x98, 0x04, 0x60, -0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42, -0x20, 0x04, 0x81, 0x18, 0x05, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04, 0x81, 0x18, -0x04, 0x62, 0x10, 0x08, 0x51, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, -0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, -0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, -0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x00, -0x02, 0x81, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0x42, 0x00, 0x02, 0x83, 0x28, 0x0C, -0xA0, 0x10, 0x80, 0xC0, 0x20, 0x0A, 0x83, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0xC2, -0x00, 0x0A, 0x03, 0x28, 0x04, 0x22, 0x10, 0x80, 0x40, 0x20, 0x02, 0x01, 0x08, -0x04, 0xA2, 0x10, 0x88, 0x40, 0x20, 0x02, 0x81, 0x08, 0x04, 0x22, 0x10, 0x88, -0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A, -0x01, 0x28, 0x05, 0xA0, 0x10, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0, -0x10, 0x80, 0x52, 0x00, 0x0A, 0x01, 0x28, 0x04, 0xA0, 0x10, 0x80, 0xC2, 0x00, -0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C, -0x80, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x04, 0xA0, 0x30, 0x80, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x20, 0x06, 0x00, -0x08, 0x00, 0x60, 0x00, 0x80, 0x11, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x04, -0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, -0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x80, -0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x40, 0x00, 0x81, 0x01, -0x04, 0x04, 0x10, 0x18, 0x40, 0x40, 0x00, 0x83, 0x01, 0x05, 0x04, 0x10, 0x10, -0x40, 0x40, 0x00, 0x81, 0x01, 0x04, 0x06, 0x10, 0x18, 0x50, 0x40, 0x40, 0x01, -0x01, 0x0C, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x84, 0x10, -0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18, 0x00, -0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, -0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x19, -0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88, -0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x24, 0x00, 0x99, 0x00, 0x64, -0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0x91, 0x00, 0xE0, 0x00, 0x00, 0x09, 0x40, -0x26, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0xB8, 0x00, -0x64, 0x00, 0x80, 0x0B, 0x40, 0x26, 0x00, 0xB8, 0x00, 0x64, 0x02, 0x98, 0x09, -0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA2, 0x06, 0x60, 0x14, 0x00, 0x50, 0x00, 0xC2, 0x01, -0x00, 0x05, 0x20, 0x16, 0x00, 0x50, 0x00, 0x62, 0x01, 0x18, 0x05, 0x20, 0x1C, -0x00, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x20, 0x16, 0x80, 0x58, 0x00, 0xC2, -0x01, 0x88, 0x05, 0x28, 0x1C, 0x80, 0x58, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20, -0x1C, 0x80, 0x70, 0x08, 0xC2, 0x01, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x04, 0x02, 0x10, 0x08, 0xC0, 0x20, 0x00, -0xA1, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x0C, 0x02, -0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x0A, 0xC0, 0x20, -0x00, 0xA1, 0x00, 0x8C, 0x02, 0x10, 0x08, 0xC0, 0x28, 0x00, 0xE3, 0x00, 0x1C, -0x02, 0x30, 0x0A, 0xC0, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x00, 0x20, 0x00, 0xA4, 0x00, 0x90, 0x02, 0xC0, 0x0A, 0x00, 0xA9, -0x20, 0xAC, 0x00, 0xB0, 0x0A, 0xC2, 0x08, 0x00, 0x29, 0x00, 0xAC, 0x00, 0xB0, -0x02, 0xC0, 0x0A, 0x00, 0xAB, 0x20, 0xAC, 0x82, 0xB0, 0x06, 0xC0, 0x28, 0x08, -0xAB, 0x00, 0xAC, 0x82, 0xB0, 0x0A, 0xC0, 0x3A, 0x08, 0xAB, 0x00, 0xAC, 0x02, -0xB0, 0x0E, 0xC0, 0x28, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xA2, 0xC2, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x80, 0xE1, 0x20, -0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x0C, -0x60, 0x30, 0x80, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1, -0x20, 0x06, 0x83, 0x18, 0x0C, 0x62, 0x38, 0x80, 0xE1, 0x20, 0x06, 0x83, 0x18, -0x0E, 0x62, 0x30, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x80, 0x02, 0x00, 0x04, 0x80, 0x10, 0x00, 0x40, 0x00, 0x08, 0x01, 0x00, 0x04, -0x80, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x80, 0x10, 0x00, 0x42, -0x00, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x84, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, -0x12, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x20, 0x06, 0x88, -0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, -0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x31, 0x20, 0x46, -0x80, 0x18, 0x20, 0x62, 0x04, 0x80, 0x11, 0x20, 0x46, 0x88, 0x18, 0x01, 0x62, -0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, -0x02, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88, 0x22, 0x00, 0x0A, 0x88, 0x28, -0x00, 0xA0, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88, -0x02, 0x02, 0x0A, 0x00, 0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x02, -0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x20, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, -0x88, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04, -0x42, 0x10, 0x28, 0x01, 0xA0, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x28, 0x41, -0xA0, 0x04, 0x81, 0x10, 0x04, 0x4A, 0x10, 0x28, 0x41, 0xA0, 0x04, 0x81, 0x12, -0x04, 0x4A, 0x10, 0x28, 0x01, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, -0x01, 0xA0, 0x04, 0x81, 0x10, 0x00, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xA0, 0x40, -0x01, 0x00, 0x05, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00, -0x14, 0x28, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14, 0x20, 0x50, 0x00, -0x40, 0x01, 0x00, 0x85, 0x08, 0x34, 0x20, 0x50, 0x80, 0x40, 0x03, 0x02, 0x05, -0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0xB2, 0xC0, 0xCA, 0x82, -0x21, 0x0B, 0xA4, 0x2C, 0x18, 0xB2, 0xC0, 0xCA, 0x02, 0x28, 0x0B, 0x84, 0x2C, -0xB0, 0xB2, 0x40, 0xC8, 0x82, 0x21, 0x0B, 0x86, 0x2C, 0x80, 0xB2, 0x40, 0xC8, -0x02, 0x21, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0x84, -0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0xAC, 0x2C, 0xB0, 0x02, 0x88, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x20, 0x4E, 0x80, 0x38, -0x01, 0xEA, 0x04, 0x88, 0x13, 0x60, 0x4E, 0x80, 0x3A, 0x01, 0xE6, 0x04, 0x88, -0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0xA8, 0x13, 0x60, 0x4E, 0x00, -0x39, 0x01, 0xE2, 0x24, 0x98, 0x13, 0x20, 0x4E, 0x82, 0x39, 0x01, 0xE2, 0x04, -0x88, 0x13, 0x20, 0x4E, 0x82, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x02, 0x03, 0x08, 0x0C, -0x20, 0x30, 0x80, 0xC0, 0x00, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0, -0x10, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x30, 0x80, 0xC0, 0x08, 0x02, 0x03, 0x08, -0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x43, 0x08, 0x0C, 0x20, 0x30, 0x86, -0xC0, 0x00, 0x02, 0x63, 0x08, 0x0C, 0x21, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, -0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, -0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, -0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, -0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x2F, 0xCD, 0x36, -0xFC, 0xDF, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x6C, -0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x7E, 0xC3, 0xB7, 0x2F, 0xCD, -0x36, 0x7C, 0xDB, 0xF0, 0x7F, 0x43, 0xB3, 0x2F, 0xDF, 0x36, 0xFC, 0xFF, 0xD2, -0x6C, 0xC3, 0xB7, 0x0D, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x2F, 0x33, 0x8F, 0xFC, -0x3F, 0x32, 0xF3, 0xC8, 0xFC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xC8, -0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCF, 0x2F, 0x33, 0x8F, -0xFC, 0x3C, 0xF2, 0xFF, 0xC8, 0xCC, 0x2F, 0x3F, 0x8F, 0xFC, 0xFF, 0x32, 0xF3, -0xC8, 0xCF, 0x23, 0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xDC, 0x18, 0x12, 0x63, 0x48, 0x8C, 0x27, 0x31, 0x86, 0xDC, 0x1E, -0x12, 0x63, 0x48, 0xEC, 0x21, 0x37, 0x86, 0xC4, 0x78, 0x12, 0x63, 0x48, 0x8C, -0x21, 0x31, 0x86, 0xC4, 0x1E, 0x12, 0x7B, 0xC8, 0x8D, 0x27, 0xB7, 0x87, 0xDC, -0x7E, 0x72, 0x7B, 0x48, 0x8C, 0x27, 0xB7, 0x9F, 0xDC, 0x7E, 0x12, 0xFB, 0xC9, -0x8D, 0x27, 0xB7, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x40, 0xE1, 0x0C, 0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, -0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, -0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x40, 0x21, -0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0xE1, 0x0C, 0x85, 0x00, 0x14, -0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, -0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, -0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01, 0x02, -0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, -0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, -0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, -0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, -0x0C, 0x80, 0x33, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, -0x02, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, -0x20, 0x00, 0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, -0x00, 0x02, 0x04, 0x08, 0x00, 0xE0, 0x4C, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0xCC, 0x40, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x00, 0x00, 0xC1, -0x0C, 0x04, 0x00, 0x10, 0xCC, 0x40, 0x30, 0x03, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0xC1, 0x0C, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, -0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, -0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, -0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, -0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x30, 0x13, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, -0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, -0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, -0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, -0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, -0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, -0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, -0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, -0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, -0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, -0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33, -0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x08, -0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, -0x00, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x33, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, -0xCE, 0x40, 0x08, 0x00, 0xE1, 0x0C, 0x84, 0x00, 0x10, 0xCE, 0x40, 0x38, 0x03, -0x21, 0x00, 0x84, 0x33, 0x10, 0xCE, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x33, -0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x02, -0x10, 0x00, 0x40, 0x20, 0x00, 0x01, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00, -0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, -0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, -0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, -0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, -0x84, 0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, -0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, -0x00, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, -0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x20, 0x04, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, -0xF0, 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, 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, -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, 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, 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, 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, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, -0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, -0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, -0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, -0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, -0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, -0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, -0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, -0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, -0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, -0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, -0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, -0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, -0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, -0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, -0x40, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, -0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, -0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, -0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, -0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, -0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, -0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x10, 0x00, 0x44, 0x00, -0x10, 0x01, 0x00, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0xCE, 0x54, -0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, -0x85, 0x00, 0x15, 0x02, 0x54, 0x38, 0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, -0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, -0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, -0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, -0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, -0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, -0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, -0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, -0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, -0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, -0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, -0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, -0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33, -0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, -0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, -0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, -0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x20, 0x04, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, -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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, -0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 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, 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, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80, -0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x22, 0x08, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x0C, 0x00, 0x04, 0x80, 0x40, -0x40, 0x00, 0x00, 0x0C, 0x00, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, -0x00, 0x22, 0x25, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x00, -0x02, 0x08, 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, 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, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0xE8, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00 -}; diff --git a/drivers/staging/me4000/me4610_firmware.h b/drivers/staging/me4000/me4610_firmware.h deleted file mode 100644 index c550d99286c..00000000000 --- a/drivers/staging/me4000/me4610_firmware.h +++ /dev/null @@ -1,5409 +0,0 @@ -/* - This file is copyright by Meilhaus Electronic GmbH 2003. - You are not allowed to distribute, sell, modify, reverse engineer or use this - code (or parts of it) for any other purpose or under any other conditions - than stated below. - - 1) You are allowed to distribute verbatim copies of this file together - with device drivers for the Meilhaus ME-4000, board family. - - 2) Derived work (device drivers using this file) can be published 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. Any other license terms have - to be agreed by Meilhaus GmbH in written. - - 2) This file is distributed WITHOUT ANY WARRANTY; - without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under - no means liable for products using this file or parts of it. - - 3) The copyright of this file has to be mentioned in derived work. - - 4) If this license terms are not valid due to any other law - or restrictions imposed on you, you are not allowed to use - this file in any way at all. - */ - -/* Version 0 of ME-4610 firmware */ -static unsigned char xilinx_firm_4610[] = { -0x00, 0x01, 0x11, 0x0c, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00, -0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00, -0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00, -0xD0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C, -0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, -0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x7C, 0x20, 0x40, 0x58, 0x04, -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, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 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, 0x00, 0x00, 0x00, 0x02, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x40, 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, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, -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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x40, 0x48, 0x02, 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, 0x00, -0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x58, 0x80, 0x54, 0x00, -0x44, 0x01, 0x18, 0x05, 0x60, 0x04, 0x80, 0x01, 0x00, 0x66, 0x00, 0xD8, 0x00, -0x60, 0x0A, 0x80, 0x2D, 0x00, 0xF6, 0x00, 0xD8, 0x03, 0x60, 0x0A, 0x80, 0x69, -0x00, 0xC6, 0x01, 0x98, 0x05, 0x20, 0x16, 0xFC, 0x23, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xBF, 0x00, 0xDC, 0x32, 0xF0, -0x13, 0xC0, 0x4F, 0x00, 0xFB, 0x28, 0xBC, 0x04, 0xB0, 0x17, 0xC0, 0x4E, 0x12, -0x1B, 0x10, 0xFC, 0x13, 0x30, 0x93, 0xC0, 0x4B, 0x00, 0x1F, 0x01, 0xFC, 0x24, -0x30, 0xCF, 0xE2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x08, 0x37, 0x01, 0x9D, 0x06, 0x44, 0x30, 0xD1, 0x11, 0x40, 0x47, 0x00, -0xFD, 0x0A, 0x74, 0x06, 0x10, 0x09, 0x40, 0x17, 0x09, 0x11, 0x42, 0xF4, 0x0B, -0x50, 0x49, 0x40, 0x06, 0x0C, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x8F, 0x40, 0x04, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x33, 0x00, -0x8D, 0x18, 0x05, 0x16, 0xDA, 0x08, 0x40, 0x33, 0x00, 0xCD, 0x40, 0x74, 0x03, -0x91, 0x0C, 0x40, 0x35, 0x01, 0x0D, 0x20, 0x34, 0xA3, 0x10, 0x48, 0x40, 0x01, -0x01, 0xCD, 0xA0, 0x74, 0x13, 0xD2, 0x4C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x00, 0x9D, 0x01, 0x44, 0x86, -0xD0, 0x39, 0x40, 0x07, 0x00, 0xDD, 0x00, 0x64, 0x8A, 0x10, 0x89, 0x02, 0x37, -0x00, 0x15, 0x10, 0x74, 0x03, 0x50, 0x19, 0x07, 0x47, 0x20, 0x5D, 0x04, 0x74, -0xA3, 0xDA, 0x0D, 0x48, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA8, 0x77, 0x00, 0x1F, 0x91, 0x4C, 0x86, 0xE0, 0x19, 0xC0, 0x57, -0x21, 0xDB, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0x80, 0x06, 0x91, 0x1B, 0x0B, 0x7C, -0x03, 0x31, 0x31, 0xC0, 0x47, 0x01, 0x9F, 0x44, 0x7C, 0x02, 0xD0, 0x0D, 0x60, -0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, -0x02, 0x3E, 0x40, 0xE8, 0x00, 0xF0, 0x0B, 0x40, 0x8F, 0x00, 0xFE, 0x00, 0xF4, -0x48, 0xF0, 0x0B, 0xC0, 0x1F, 0x80, 0x1A, 0x20, 0xBC, 0x03, 0xE1, 0x0B, 0xC8, -0x0E, 0x00, 0x3E, 0x01, 0xF8, 0x02, 0x30, 0x0F, 0xD1, 0x1F, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x00, 0x5C, -0x46, 0x70, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x21, 0x30, 0x0D, 0xC4, -0x34, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB0, 0x29, 0xC0, 0x84, 0x08, 0x9F, 0x44, -0x7C, 0x43, 0xF0, 0x0C, 0xC4, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x90, 0x09, 0x40, -0x67, 0x00, 0xF0, 0x80, 0x34, 0x04, 0xB0, 0xB9, 0x40, 0x32, 0x00, 0xD1, 0x41, -0xC0, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x51, 0x00, 0x34, 0x43, 0xD0, 0x3F, -0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, -0x32, 0x10, 0x1D, 0x40, 0x30, 0x00, 0x90, 0x10, 0x40, 0xA3, 0x84, 0xC9, 0x00, -0x34, 0x00, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC0, 0x21, 0x00, 0x03, 0x90, 0x00, -0x40, 0x00, 0x00, 0x49, 0x83, 0x04, 0x89, 0xD8, 0x0C, 0x40, 0x1C, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x02, 0xEC, 0x81, -0xB4, 0x05, 0x9A, 0x92, 0x60, 0x4B, 0x90, 0xE1, 0xA9, 0xB6, 0x06, 0x90, 0x1A, -0x60, 0x7A, 0x00, 0xE1, 0x13, 0xA4, 0x07, 0xC0, 0x12, 0x40, 0x4F, 0x00, 0x61, -0x35, 0xB4, 0x25, 0xC0, 0x9F, 0x61, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x10, 0x4D, 0x00, 0x1C, 0xA1, 0x78, 0x80, -0xE1, 0x33, 0x25, 0xCF, 0x20, 0x3C, 0x23, 0x30, 0x2C, 0xC1, 0x34, 0x08, 0x07, -0x05, 0x0D, 0x03, 0xB0, 0xC0, 0xE8, 0x10, 0x22, 0xCF, 0x41, 0x3C, 0x17, 0xF2, -0xDD, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xB2, 0x3D, 0x08, 0xFF, 0x00, 0xFE, 0xA3, 0x80, 0x8F, 0xC2, 0x1B, 0x00, 0xFF, -0x80, 0xFE, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x10, 0x37, 0x08, 0xDC, 0x63, 0xF0, -0x87, 0xC6, 0x3F, 0x08, 0xDF, 0x00, 0x7C, 0x23, 0xFA, 0x8F, 0xC2, 0x09, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x77, 0x00, 0x57, -0x00, 0x7C, 0x03, 0xF0, 0x11, 0xC0, 0x35, 0x00, 0xDF, 0x10, 0x5C, 0x01, 0xF0, -0x18, 0xC0, 0x66, 0x00, 0xD3, 0x00, 0x6C, 0x13, 0xF0, 0x01, 0xC8, 0x17, 0x10, -0x9F, 0x00, 0x7C, 0x03, 0x32, 0xBD, 0xC5, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x3D, 0x00, 0x61, 0x80, 0xB6, 0x01, 0xD0, -0x0A, 0x48, 0x38, 0x00, 0xFD, 0x06, 0x84, 0x03, 0xD2, 0x0A, 0x40, 0x39, 0x40, -0xF1, 0x80, 0x86, 0x43, 0xD0, 0x0A, 0x48, 0x1B, 0x00, 0xED, 0x00, 0xB4, 0x03, -0x10, 0x0F, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x79, 0x80, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x40, 0x79, 0x08, -0xEC, 0x01, 0x94, 0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE1, 0x01, 0x84, 0x07, -0xD0, 0x1E, 0x60, 0x79, 0x00, 0xAD, 0x11, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x0C, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x23, 0x00, -0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x02, 0xCD, 0x00, 0x14, 0x4B, -0xD1, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x0D, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x73, -0x01, 0xCD, 0x80, 0x74, 0x0B, 0x50, 0x0C, 0x40, 0x48, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x14, 0x01, 0x77, 0x03, 0xFC, 0x29, -0xD0, 0x17, 0xC1, 0x5D, 0x00, 0x5F, 0x00, 0x9C, 0x19, 0xD0, 0x07, 0xC0, 0x1E, -0x00, 0x73, 0x02, 0x4C, 0x01, 0xF0, 0x47, 0xC0, 0x1F, 0x8C, 0x7F, 0x00, 0xFC, -0x09, 0x72, 0x05, 0x40, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xD0, 0x11, 0x40, 0x46, -0x00, 0x0E, 0x40, 0x68, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x42, 0x5C, -0x00, 0xB2, 0x11, 0xC0, 0x07, 0x00, 0x1B, 0x10, 0x7C, 0x10, 0x82, 0x01, 0xC0, -0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27, -0x00, 0x8F, 0x10, 0x54, 0x0A, 0xF2, 0x09, 0x40, 0x27, 0x00, 0x9B, 0x00, 0x4C, -0x06, 0xD0, 0x99, 0xC0, 0x27, 0x00, 0x8F, 0x04, 0x5C, 0x82, 0xE0, 0x09, 0xC0, -0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0x30, 0x89, 0xC2, 0x43, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x9C, 0x00, 0x54, -0x02, 0xD0, 0xB9, 0x40, 0xE7, 0x00, 0x9D, 0x00, 0x44, 0x6A, 0x10, 0x19, 0x04, -0x27, 0x00, 0x9D, 0x02, 0x45, 0x02, 0xC2, 0x09, 0x40, 0x27, 0x00, 0x90, 0x13, -0x74, 0x22, 0x10, 0x59, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40, -0xE7, 0x00, 0x9D, 0x80, 0x45, 0x02, 0x90, 0x09, 0x41, 0x26, 0x00, 0x9D, 0x02, -0x44, 0x82, 0x90, 0x09, 0x40, 0x23, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x09, -0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x20, 0x02, 0x8D, 0x14, 0x14, 0x56, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x8D, 0x00, -0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x02, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x88, -0x00, 0x23, 0x02, 0x81, 0x00, 0x30, 0x02, 0x14, 0x48, 0x49, 0x43, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x00, 0x1F, 0x24, -0x4C, 0x10, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1E, 0x14, 0x4C, 0x00, 0xB0, 0xA1, -0xC2, 0x83, 0x00, 0x1F, 0x1E, 0x4C, 0x78, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x17, -0x0A, 0x3C, 0x81, 0x30, 0x41, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x19, 0xB0, 0x2F, 0x01, 0xBF, 0x94, 0xFC, 0x52, 0xF2, 0x0A, -0xC8, 0x2F, 0x00, 0x9C, 0x14, 0xFC, 0x02, 0xB0, 0x1F, 0x80, 0x2F, 0x01, 0xBF, -0x81, 0x70, 0x06, 0xF1, 0x4F, 0xC0, 0x2F, 0x41, 0xBF, 0x01, 0xFC, 0x53, 0xF0, -0x49, 0x41, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, -0x80, 0x23, 0x00, 0x97, 0x08, 0xF0, 0x37, 0x30, 0x0A, 0xC0, 0x2F, 0x20, 0x9F, -0x0C, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xA2, 0x00, 0xBF, 0x10, 0x4C, 0x02, 0xF0, -0x29, 0xC0, 0x25, 0x02, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x01, 0x01, -0x05, 0x74, 0x3D, 0xB0, 0x01, 0x40, 0x17, 0x00, 0x1D, 0x01, 0x74, 0x01, 0xD1, -0x01, 0x40, 0x04, 0x00, 0x0D, 0x02, 0x51, 0x28, 0x91, 0x01, 0x40, 0x14, 0x11, -0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x48, 0x71, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x04, 0x85, 0x42, 0x34, 0x02, 0x59, -0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x34, 0x02, 0xD0, 0x09, 0x42, 0x22, 0x10, -0x8D, 0x00, 0x16, 0x82, 0xD0, 0x09, 0x40, 0x21, 0x00, 0xC5, 0x20, 0x74, 0x02, -0x11, 0x08, 0x50, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0xA8, 0x21, 0x00, 0x91, 0x04, 0x74, 0x03, 0xD0, 0x39, 0x60, 0x27, 0x08, -0x9D, 0x00, 0x74, 0x02, 0xD0, 0x8D, 0x42, 0x24, 0x00, 0x9D, 0x00, 0x54, 0x02, -0xD0, 0x09, 0x40, 0x24, 0x40, 0x95, 0x04, 0x74, 0x02, 0x52, 0x09, 0x40, 0x61, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x08, -0x97, 0x93, 0x78, 0x0A, 0x74, 0x19, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x0A, -0xF0, 0x08, 0xC8, 0xE6, 0x01, 0x9F, 0xB8, 0x5C, 0x02, 0xF0, 0x28, 0xC2, 0x25, -0x00, 0x97, 0x04, 0x3C, 0x0E, 0x20, 0x09, 0xC4, 0x14, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x64, 0x02, 0x9F, 0x00, 0x3C, 0x16, -0xB0, 0x09, 0xC4, 0xE7, 0x00, 0x9F, 0x80, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27, -0x01, 0x9F, 0x01, 0x68, 0x02, 0xB0, 0x29, 0xC4, 0x27, 0x01, 0x9B, 0x00, 0x7C, -0x0E, 0xB4, 0x08, 0x40, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x02, 0x4C, 0x08, 0xF0, 0x61, 0xC0, 0x07, -0x00, 0x17, 0x00, 0x4C, 0x40, 0xF0, 0x21, 0x40, 0x04, 0x00, 0x03, 0x42, 0x5C, -0x00, 0x30, 0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xD1, -0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, -0x00, 0x51, 0x00, 0xC4, 0x0D, 0xD0, 0x37, 0x40, 0x1C, 0x02, 0x51, 0x20, 0xCC, -0x41, 0xD2, 0x07, 0x48, 0x14, 0x00, 0x71, 0x49, 0x44, 0x81, 0x50, 0x05, 0x40, -0x17, 0x00, 0x7C, 0x82, 0xC4, 0x69, 0xD0, 0x07, 0x40, 0x50, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x60, 0xC1, 0x40, 0x14, -0xCF, 0xC0, 0xB4, 0x40, 0x72, 0x02, 0xC5, 0x00, 0x24, 0x03, 0xD0, 0x8C, 0x40, -0x30, 0x10, 0xC1, 0x0B, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x00, 0xC9, 0x04, -0x04, 0x80, 0xD0, 0x30, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x82, 0x3C, 0x22, 0xE1, 0x0D, 0x94, 0x43, 0xD0, 0x12, 0x40, -0x7E, 0x00, 0xC1, 0x01, 0x84, 0x01, 0xD0, 0x0E, 0x40, 0x7C, 0x43, 0x61, 0x00, -0xA4, 0x27, 0x50, 0x0E, 0x40, 0x3B, 0x10, 0xAD, 0x21, 0x84, 0x01, 0xD0, 0x23, -0x44, 0x10, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, -0x78, 0x01, 0xE3, 0x91, 0x9D, 0x07, 0xF0, 0x16, 0xC0, 0x4A, 0x00, 0xE7, 0x01, -0xAD, 0x07, 0xE1, 0x13, 0xC0, 0x78, 0x02, 0xA3, 0x61, 0xFC, 0x37, 0x30, 0x5E, -0xC1, 0x7B, 0x00, 0xBB, 0x01, 0x8C, 0x06, 0xFA, 0x1B, 0xC0, 0x50, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x04, 0xDF, 0x40, -0x6C, 0x03, 0xF3, 0x01, 0xC0, 0x00, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0xD0, 0x05, -0x90, 0x37, 0x01, 0x1F, 0x00, 0x5C, 0x93, 0xF1, 0xAD, 0x80, 0xB7, 0x03, 0x9C, -0x40, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xDC, 0x25, 0x30, 0x1F, -0xC0, 0x7F, 0x00, 0xF7, 0x11, 0xFC, 0x26, 0x10, 0x1F, 0xC0, 0x7F, 0x10, 0x7F, -0x09, 0xCC, 0x87, 0x30, 0x9F, 0xC0, 0xFC, 0x8A, 0xBF, 0x0D, 0xEC, 0x24, 0xF1, -0x17, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x88, 0x39, 0x24, 0xED, 0x00, 0xF4, 0x03, 0xB0, 0x4A, 0x48, 0x0B, 0x00, 0xED, -0x04, 0xB4, 0x21, 0x10, 0x4E, 0x42, 0x7B, 0x01, 0x29, 0x01, 0x84, 0x03, 0xF0, -0x0E, 0x44, 0x38, 0x00, 0x8D, 0x43, 0x34, 0x21, 0xD0, 0x84, 0x40, 0x57, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xED, -0x10, 0x94, 0x01, 0x98, 0x02, 0x40, 0x0B, 0x04, 0xED, 0x80, 0xF4, 0x00, 0x90, -0x02, 0x41, 0x3B, 0x01, 0x0D, 0x08, 0x94, 0x03, 0x10, 0x0E, 0x48, 0x38, 0x20, -0x25, 0x02, 0xB4, 0x20, 0xD8, 0x0E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x74, 0x42, 0x90, -0x00, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x2D, 0x90, 0x10, 0x40, 0x37, 0x00, -0x19, 0x00, 0x14, 0x03, 0xD0, 0x2D, 0x40, 0xB0, 0x00, 0x0D, 0x08, 0x34, 0x03, -0xD0, 0x0C, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x88, 0x3D, 0x00, 0xFF, 0x01, 0x5C, 0x02, 0xB0, 0xA5, 0xC0, 0x27, 0x90, -0xF7, 0x00, 0x7C, 0x27, 0xB6, 0xB9, 0xC8, 0x3F, 0x00, 0x9F, 0x20, 0xDC, 0x03, -0x30, 0xAF, 0xC8, 0x3C, 0x08, 0x8F, 0x01, 0x6C, 0x83, 0xD0, 0x0D, 0xC8, 0x57, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, -0xDF, 0x10, 0x7C, 0x28, 0xF0, 0x15, 0xC0, 0xA7, 0x00, 0xDF, 0x00, 0x7C, 0x03, -0x70, 0x21, 0xC0, 0x77, 0x00, 0x1E, 0x42, 0x25, 0x83, 0xB0, 0x8D, 0xC0, 0x37, -0x00, 0x1D, 0x02, 0x7C, 0x03, 0xD0, 0x0D, 0xC4, 0x27, 0x00, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x28, 0xFB, 0x40, 0xFC, 0x02, -0x30, 0x37, 0xC0, 0x2F, 0x04, 0xFF, 0x00, 0xFC, 0x16, 0xF0, 0x03, 0xC0, 0x3F, -0x00, 0x33, 0x00, 0xCC, 0x03, 0x71, 0x0F, 0xE0, 0x3C, 0x0C, 0xBF, 0x20, 0xDC, -0x03, 0xF2, 0x0B, 0xC2, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA1, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xB0, 0x05, 0xC0, 0xE7, -0x00, 0xDD, 0x00, 0x74, 0x0A, 0xD0, 0x11, 0x40, 0x36, 0x00, 0x1B, 0x00, 0x6C, -0x03, 0x10, 0x0D, 0x40, 0x35, 0x00, 0x1C, 0x03, 0x40, 0x04, 0xD0, 0x35, 0x40, -0x84, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, -0x00, 0xDD, 0x00, 0x74, 0x04, 0x18, 0x0D, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x64, -0x0A, 0xD0, 0x1B, 0x40, 0x37, 0x00, 0x31, 0x06, 0xC0, 0x03, 0x00, 0x0D, 0x44, -0x36, 0x00, 0xBD, 0x01, 0x44, 0xA3, 0xD0, 0x64, 0x50, 0x04, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00, 0x36, -0x00, 0x18, 0x0C, 0x40, 0x01, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x00, 0x42, -0x36, 0x21, 0x19, 0x24, 0x24, 0x03, 0x15, 0x0C, 0x40, 0x30, 0x00, 0x1D, 0x04, -0x04, 0xA6, 0xD0, 0x28, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xB0, 0x3E, 0x08, 0xFB, 0x80, 0x7C, 0x00, 0x14, 0x01, 0x40, -0x27, 0x08, 0xDF, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC2, 0x3F, 0x05, 0x13, 0x16, -0x8C, 0x03, 0x70, 0x0E, 0xD0, 0x3C, 0x10, 0x1F, 0x1C, 0x5C, 0x01, 0xF0, 0x21, -0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, -0x3F, 0x00, 0xFF, 0x40, 0xFC, 0x02, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x40, -0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x36, 0x00, 0x1F, 0x14, 0xFC, 0x03, 0xF0, 0x0F, -0xC4, 0x3F, 0x00, 0x1F, 0x04, 0xFD, 0x10, 0xF2, 0x43, 0x00, 0x17, 0x60, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7D, 0x02, 0xFA, 0x00, -0xFC, 0x20, 0xB0, 0x0F, 0xC0, 0x3F, 0x20, 0xF7, 0xA0, 0xEC, 0x03, 0x30, 0x4F, -0xC4, 0x0D, 0x10, 0x33, 0x01, 0xFC, 0x27, 0xF1, 0x33, 0xC0, 0x3E, 0x00, 0x2F, -0x01, 0x6C, 0x80, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x08, 0x37, 0x20, 0xF1, 0x82, 0x34, 0x3A, 0x10, 0x3F, -0x40, 0xBE, 0x16, 0xF1, 0x89, 0xF4, 0x0F, 0x10, 0x9F, 0xC8, 0x45, 0x32, 0x95, -0x00, 0x74, 0x11, 0xD1, 0x41, 0x40, 0x3F, 0x20, 0x1D, 0x54, 0x44, 0x04, 0xD0, -0x01, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, -0x20, 0x33, 0x11, 0xC1, 0x36, 0x74, 0x03, 0x11, 0x2C, 0x44, 0x33, 0x01, 0xC5, -0x80, 0x34, 0x23, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x13, 0x90, -0x00, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24, 0x80, 0xD8, 0x00, 0x40, 0x47, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x20, 0xD1, -0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x20, 0xD1, 0x00, 0x74, 0x83, 0x10, -0x0D, 0x40, 0x97, 0x00, 0x94, 0x04, 0x74, 0x21, 0xD0, 0x11, 0x43, 0x3F, 0x00, -0x1D, 0x10, 0xC0, 0x60, 0xC0, 0x3B, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x40, 0xDB, 0x00, 0x3C, 0x06, 0xB4, -0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x6E, 0x03, 0x30, 0x0D, 0xC0, 0x83, 0x00, -0xD3, 0x80, 0x7C, 0x97, 0xF0, 0x11, 0xC8, 0x36, 0x00, 0xDF, 0x00, 0x6C, 0x00, -0xF1, 0x31, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, -0xDF, 0x00, 0xFA, 0x43, 0xF0, 0x0D, 0xC2, 0x4D, 0x01, 0xFF, 0x01, 0xFC, 0x01, -0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x09, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x1F, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01, -0xDF, 0x08, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x33, 0x00, 0xDF, 0x40, 0x3C, 0x03, -0xF0, 0x0D, 0xC0, 0x27, 0x08, 0xDB, 0x00, 0x7C, 0x03, 0x30, 0x21, 0xC0, 0x37, -0x04, 0xDF, 0x02, 0x4C, 0x00, 0xF0, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x09, 0xFD, 0xC1, 0x74, 0x83, -0x50, 0x3F, 0x44, 0x3F, 0x00, 0xFC, 0x0A, 0xC4, 0x8F, 0xD0, 0x0F, 0x41, 0x34, -0x00, 0xDD, 0x01, 0x74, 0x81, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x1C, 0x00, 0x44, -0x12, 0xD0, 0x39, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0xA0, 0x76, 0x00, 0xC9, 0x47, 0x34, 0x03, 0x18, 0x0C, 0x49, 0x33, -0x00, 0xCD, 0x03, 0x04, 0x2F, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0x49, 0x00, 0x34, -0x02, 0x10, 0x00, 0x40, 0xF3, 0x00, 0x1D, 0x00, 0x14, 0x04, 0xD0, 0x00, 0x01, -0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, -0x00, 0xED, 0x01, 0xB4, 0x27, 0x50, 0x9E, 0x40, 0x7B, 0x00, 0xED, 0x35, 0x85, -0x07, 0xD0, 0x5E, 0x40, 0x69, 0x80, 0xED, 0x03, 0xF4, 0x06, 0x90, 0x92, 0x02, -0x7B, 0x00, 0x3D, 0x01, 0x96, 0x24, 0xD0, 0x9A, 0x48, 0x13, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x02, 0xCF, 0x08, 0x3C, -0x03, 0x3A, 0x0C, 0xC1, 0x33, 0x00, 0xCF, 0x0D, 0x2C, 0x03, 0xF0, 0x5C, 0xC0, -0x11, 0x00, 0x4B, 0x10, 0x3C, 0x06, 0x30, 0x00, 0xC2, 0x33, 0x06, 0xCF, 0x00, -0x1C, 0x14, 0xF0, 0x00, 0xC1, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFE, 0x00, 0xF8, 0x03, 0xF8, 0x0F, 0xC9, -0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1C, 0x00, 0xFF, 0x08, -0x3C, 0x02, 0x75, 0x07, 0xC6, 0x3F, 0x00, 0xFF, 0x00, 0xED, 0x20, 0xF0, 0x0B, -0xE8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, -0x37, 0x10, 0xDE, 0x44, 0x7C, 0x03, 0x30, 0x5D, 0xC2, 0x34, 0x11, 0xD3, 0x04, -0x7C, 0x0B, 0xF3, 0x3D, 0xD1, 0x34, 0x00, 0xD3, 0x01, 0x4C, 0x03, 0xF0, 0x01, -0xD0, 0xB4, 0x07, 0xCE, 0x00, 0x4C, 0x04, 0x32, 0x19, 0xC0, 0x54, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x38, 0x00, 0xED, 0x96, -0xF4, 0x03, 0xB0, 0x0C, 0x55, 0x38, 0x14, 0xE1, 0x16, 0xB4, 0x5B, 0xD0, 0x4C, -0x40, 0x20, 0x10, 0xF1, 0x80, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x38, 0x01, 0xED, -0x00, 0x84, 0x02, 0x11, 0x0B, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E, -0x4A, 0x70, 0x13, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x5E, 0x40, 0x78, 0x40, 0xE1, -0x01, 0x84, 0x07, 0xD0, 0x16, 0x43, 0x78, 0x81, 0xFD, 0x01, 0x04, 0x84, 0x18, -0x1A, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x28, 0x23, 0x02, 0xDD, 0x00, 0x34, 0x03, 0x92, 0x0C, 0x40, 0x30, 0x40, 0xC1, -0x20, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x30, 0x04, 0xC1, 0x08, 0x04, 0x07, 0xD0, -0x2C, 0x41, 0x30, 0x00, 0xDD, 0x10, 0x04, 0x0F, 0x18, 0x3C, 0x40, 0x4A, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F, -0x80, 0xFC, 0x29, 0x30, 0x05, 0xC0, 0x14, 0x00, 0x43, 0x00, 0x7C, 0x01, 0xF0, -0x05, 0x82, 0x1C, 0x00, 0x73, 0x03, 0xCD, 0x15, 0xF0, 0x37, 0xC0, 0x14, 0x00, -0x7F, 0x12, 0xCC, 0x15, 0x30, 0x17, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x20, 0x7C, 0x00, 0xF0, -0x01, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC8, 0x87, 0x00, -0x1F, 0x10, 0x7C, 0x80, 0xF3, 0x01, 0xC0, 0x07, 0x30, 0x1F, 0x00, 0x7D, 0x10, -0xF1, 0x81, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x02, 0x70, 0x19, 0xC0, 0x27, 0x00, -0x97, 0x01, 0x5C, 0x26, 0xF0, 0x19, 0xC0, 0x23, 0x00, 0x90, 0x80, 0x7C, 0x02, -0x30, 0x09, 0xC0, 0xA4, 0x00, 0x9F, 0x05, 0x4C, 0x12, 0xF0, 0x29, 0xC0, 0x43, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE2, 0x22, -0x91, 0x00, 0x14, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x44, 0x8A, -0xD0, 0x99, 0x44, 0x27, 0x02, 0x91, 0x02, 0x74, 0x82, 0x12, 0x08, 0x42, 0x24, -0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x44, 0x91, 0x21, 0x54, 0x03, -0x50, 0x49, 0x41, 0x23, 0x00, 0x95, 0x86, 0x54, 0x0A, 0xD1, 0x09, 0x40, 0x27, -0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, -0x02, 0xD0, 0x09, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x20, 0x24, 0x00, 0xC1, 0x00, 0x54, 0x52, 0x54, 0x08, 0x40, 0x23, -0x02, 0x81, 0x80, 0x00, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x40, 0x85, 0x01, 0x34, -0x22, 0x10, 0x89, 0x42, 0x60, 0x01, 0x8D, 0x08, 0x04, 0x12, 0xD0, 0x48, 0x48, -0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, -0x00, 0x13, 0x94, 0x5C, 0x10, 0x74, 0x41, 0xC1, 0x87, 0x05, 0x16, 0x94, 0x5C, -0x50, 0xF1, 0x45, 0xC1, 0x17, 0x05, 0x17, 0x0A, 0x7C, 0x08, 0x34, 0x20, 0xC0, -0xC4, 0x02, 0x1F, 0x02, 0x4D, 0x04, 0xF0, 0xB1, 0xC0, 0x77, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x05, 0x9F, 0x34, 0xFC, -0x52, 0xB0, 0x09, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, -0x2F, 0x00, 0xBB, 0x01, 0xFC, 0x12, 0xF0, 0x4B, 0xD0, 0x67, 0x02, 0xBF, 0x04, -0xFC, 0x22, 0xF0, 0x9B, 0xC2, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x2F, 0x02, 0xBF, 0x86, 0x0C, 0x16, 0xB0, 0x4B, 0xC0, -0x27, 0x05, 0xBB, 0x00, 0xDC, 0x82, 0x30, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0xC0, -0x7C, 0x22, 0x30, 0x29, 0xC0, 0x2F, 0x00, 0xB1, 0x02, 0xCC, 0x02, 0xE0, 0x0B, -0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, -0x47, 0x01, 0x1D, 0x01, 0x44, 0x5C, 0x10, 0x01, 0x40, 0x87, 0x01, 0x1D, 0x00, -0x44, 0x00, 0x14, 0xA1, 0x40, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x01, -0x40, 0x07, 0x00, 0x15, 0x04, 0x45, 0x00, 0xD2, 0x01, 0x48, 0x70, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x06, -0x04, 0x22, 0x92, 0x28, 0x40, 0x23, 0x04, 0x8D, 0x22, 0x04, 0x8A, 0x10, 0x08, -0x50, 0xA0, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x60, 0x23, 0x10, 0x81, -0x20, 0x05, 0x83, 0xD0, 0x09, 0x60, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x80, 0x9D, 0x00, 0x45, 0x02, 0x10, 0x09, -0x60, 0x27, 0x00, 0x9D, 0x00, 0x47, 0x02, 0x10, 0x09, 0x00, 0x24, 0x01, 0x9D, -0x00, 0x74, 0x02, 0x10, 0xA9, 0x40, 0x27, 0x00, 0x95, 0x14, 0x45, 0x0E, 0xD1, -0x69, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0x88, 0x67, 0x02, 0x9F, 0x00, 0x4C, 0x36, 0xB0, 0x09, 0xC8, 0x27, 0x00, 0x9B, -0x40, 0x5C, 0x02, 0x12, 0x09, 0xC0, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x02, 0x34, -0x29, 0xC0, 0x27, 0x00, 0x83, 0x01, 0x4C, 0x0E, 0xF2, 0x29, 0xD0, 0x16, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x10, 0x9F, -0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50, 0x3C, 0x02, 0xF0, -0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, -0x9F, 0x01, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x00, 0x50, -0x01, 0xC0, 0x05, 0x00, 0x03, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x87, 0x01, -0x13, 0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x01, 0x13, 0x02, 0x4C, 0x00, -0x30, 0x21, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0xA0, 0xDC, 0x00, 0x75, 0x19, 0x44, 0x01, 0x50, 0x27, 0xC0, 0x16, 0x50, -0x71, 0x23, 0xF4, 0x21, 0xD0, 0x06, 0x41, 0x1F, 0x20, 0x75, 0x01, 0x44, 0x01, -0xD0, 0x05, 0x48, 0x1F, 0x18, 0x75, 0x0A, 0x44, 0x01, 0x11, 0x27, 0xC0, 0x52, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x81, -0xC9, 0x03, 0x04, 0x03, 0x10, 0x9C, 0x41, 0x33, 0x00, 0x81, 0x03, 0x34, 0x2B, -0xD0, 0x2C, 0x40, 0x33, 0x00, 0xC5, 0x11, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0xF1, -0x80, 0xC9, 0x01, 0x04, 0x03, 0x12, 0x8D, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x04, 0xED, 0x20, 0xC4, 0x03, -0x50, 0x1A, 0x40, 0x7A, 0x00, 0xE1, 0x00, 0xB0, 0x01, 0xD0, 0x0E, 0x40, 0x7B, -0x48, 0xE5, 0x11, 0x84, 0x23, 0xC0, 0x8E, 0x40, 0x13, 0x04, 0xED, 0x10, 0xC4, -0x07, 0x1C, 0x0B, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x10, 0x7C, 0x00, 0xFB, 0x81, 0x8C, 0x47, 0x74, 0x1E, 0xC0, 0x73, -0x01, 0xA3, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0x67, 0x81, 0x84, -0xD7, 0xF0, 0x1E, 0xC1, 0x69, 0x20, 0xBB, 0x01, 0x8D, 0x07, 0x30, 0x1B, 0xC0, -0x56, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, -0x00, 0xD7, 0x00, 0x7C, 0x33, 0xF0, 0x00, 0xC0, 0xB5, 0x20, 0x9F, 0x00, 0x7C, -0x00, 0xF1, 0x09, 0xC0, 0x33, 0x00, 0x1B, 0x00, 0x75, 0x03, 0xF2, 0x6D, 0xC0, -0x07, 0x00, 0x97, 0x00, 0x3C, 0x02, 0xF1, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x5F, 0x00, 0x7F, 0x01, 0xFC, -0x07, 0x70, 0x1F, 0xC0, 0xFF, 0x44, 0xB3, 0x09, 0x9C, 0x27, 0x70, 0x9F, 0xC0, -0x7F, 0x00, 0xA3, 0x41, 0xEC, 0x07, 0x31, 0x1D, 0xC0, 0x4F, 0x00, 0xF3, 0x01, -0xCC, 0x07, 0x30, 0x9B, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x88, 0xB9, 0x00, 0x6D, 0x02, 0xB4, 0x03, 0xB0, 0x0A, 0x60, -0x3B, 0x00, 0xC1, 0x08, 0xB4, 0x82, 0x10, 0x04, 0x48, 0x3B, 0x00, 0x21, 0x00, -0x04, 0x37, 0x10, 0x1E, 0xC0, 0x0F, 0x00, 0xFB, 0x18, 0xC4, 0x23, 0xB2, 0xCA, -0x50, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x50, 0x0A, 0x40, 0x39, 0x00, 0xA9, 0x80, -0x94, 0x02, 0x50, 0x0E, 0x60, 0x1B, 0x02, 0x39, 0x00, 0xC4, 0x13, 0x10, 0x0E, -0x41, 0x0B, 0x00, 0xB1, 0x00, 0xC4, 0x43, 0x50, 0x0A, 0x40, 0x01, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x43, 0x20, 0x0D, 0x80, -0x34, 0x03, 0x90, 0x00, 0x40, 0x37, 0x08, 0x49, 0x40, 0x34, 0x02, 0x10, 0x00, -0x44, 0x53, 0x42, 0x09, 0x02, 0x04, 0x03, 0x94, 0x1D, 0x40, 0x01, 0x00, 0x89, -0x10, 0x04, 0x06, 0xD8, 0x60, 0x40, 0x11, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA8, 0x64, 0x01, 0x9F, 0x00, 0xFC, 0x03, 0x74, 0x01, -0xC0, 0x3F, 0x00, 0x9B, 0x00, 0x5C, 0x02, 0x50, 0x01, 0xC0, 0x37, 0x08, 0x13, -0x02, 0xCC, 0x03, 0x30, 0xBF, 0x40, 0x37, 0x00, 0x53, 0x00, 0x4D, 0xAB, 0x50, -0x09, 0xC1, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7, -0x20, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x33, 0x00, 0x17, 0x82, 0x5C, 0x43, 0x70, -0x0D, 0xC0, 0x87, 0x00, 0x5F, 0xC2, 0x7C, 0x03, 0xB0, 0x29, 0x88, 0x06, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x20, 0x2F, -0x80, 0xD4, 0x03, 0x3C, 0x02, 0xC8, 0x34, 0x00, 0xB3, 0x00, 0xDC, 0x00, 0xF0, -0x2B, 0xE0, 0x24, 0x20, 0x33, 0x10, 0xF4, 0x03, 0xB0, 0x0F, 0xC0, 0x0C, 0x00, -0x7F, 0x00, 0xCC, 0x27, 0xF0, 0x09, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x9D, 0x43, 0x06, 0x03, 0x10, -0x11, 0x40, 0x34, 0x00, 0x81, 0x00, 0x44, 0x14, 0xD0, 0x18, 0xE0, 0x26, 0x00, -0x11, 0x04, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x44, 0x01, 0x47, 0x85, 0x7C, 0x02, -0xD0, 0x51, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0xA0, 0x44, 0x00, 0x9D, 0x21, 0x40, 0x03, 0x92, 0x39, 0x44, 0x34, 0x00, -0x91, 0x00, 0x56, 0x06, 0xD2, 0x25, 0x48, 0x74, 0x00, 0x31, 0x84, 0x74, 0x83, -0xD8, 0x0D, 0x40, 0x4C, 0x00, 0x9D, 0x01, 0x45, 0x02, 0xD0, 0x13, 0x40, 0x07, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, -0x8D, 0x20, 0x54, 0x03, 0x12, 0x08, 0x40, 0x30, 0x20, 0xC1, 0x40, 0x16, 0x02, -0xD0, 0x24, 0x44, 0x32, 0x10, 0x01, 0x00, 0x34, 0x33, 0xD8, 0x0C, 0x45, 0x00, -0x10, 0x85, 0x00, 0x34, 0x22, 0xD0, 0x00, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x08, 0x1F, 0x00, 0xD4, 0x03, -0x32, 0x09, 0xC2, 0x3C, 0x00, 0x93, 0x2A, 0x54, 0x00, 0xD9, 0x0D, 0x40, 0x04, -0x00, 0x13, 0x00, 0xFC, 0x9B, 0xB1, 0x0F, 0xC0, 0x04, 0x00, 0x9F, 0x00, 0x4C, -0x02, 0xF1, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xB2, 0x2F, 0x00, 0xBF, 0x00, 0xAD, 0x03, 0xF1, 0x03, 0xC0, 0x3F, -0x10, 0x7F, 0x04, 0xEC, 0x00, 0xF0, 0x03, 0xC6, 0x0F, 0x40, 0x3F, 0x00, 0x3C, -0x0B, 0xF0, 0x0F, 0xC0, 0x0D, 0x10, 0xB7, 0x00, 0xFC, 0x12, 0xF8, 0x03, 0xC0, -0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F, -0x01, 0xBF, 0x08, 0xFC, 0x43, 0x30, 0x8F, 0xC0, 0x3F, 0x05, 0x3F, 0x03, 0xDC, -0x23, 0xF0, 0x3B, 0xD0, 0x3C, 0x00, 0xFB, 0x00, 0xFC, 0x13, 0x30, 0x13, 0xC0, -0x7C, 0x10, 0x3D, 0x61, 0xCC, 0x18, 0x30, 0x43, 0xC1, 0x0C, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x87, 0x1D, 0x9D, 0x02, 0xDC, -0x0F, 0x00, 0x6F, 0x40, 0xBF, 0x01, 0x1D, 0x04, 0xC4, 0x0B, 0x70, 0x0D, 0x40, -0xFC, 0x00, 0xF1, 0x03, 0xF4, 0xA7, 0x10, 0x11, 0x40, 0x04, 0x08, 0x1D, 0x00, -0x04, 0xAB, 0x10, 0x29, 0x51, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0xA0, 0x21, 0x82, 0x0D, 0x08, 0x14, 0x03, 0x10, 0x6C, 0x48, -0x33, 0x14, 0x9D, 0x00, 0x14, 0x33, 0xD2, 0x48, 0x60, 0x30, 0x0A, 0xC9, 0x08, -0x34, 0x03, 0x10, 0x01, 0x40, 0x30, 0x20, 0x1D, 0x00, 0x04, 0x10, 0x10, 0x40, -0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, -0x47, 0x00, 0x9D, 0x03, 0x54, 0x83, 0x14, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01, -0x44, 0x03, 0x50, 0x0C, 0x60, 0x34, 0x10, 0xD0, 0x00, 0x74, 0x03, 0x14, 0x15, -0x18, 0x24, 0x00, 0x1D, 0x01, 0x44, 0x81, 0x16, 0x01, 0x41, 0x0D, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0xC7, 0x00, 0x9F, 0x01, -0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x0F, 0x03, 0x5C, 0x83, 0xF0, 0x8D, -0xC0, 0x30, 0x08, 0xDB, 0x60, 0x3C, 0x03, 0x30, 0x20, 0xC4, 0x34, 0x00, 0x0F, -0x53, 0x4C, 0x24, 0x30, 0x11, 0xC4, 0x29, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF1, 0x0D, -0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xD0, 0x1F, 0xC0, 0x3F, 0x00, 0xFF, -0x50, 0xF0, 0x83, 0xF0, 0x03, 0xC8, 0x8F, 0x00, 0x3F, 0x00, 0xBC, 0xC7, 0xF0, -0x3D, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, -0x08, 0xA5, 0x00, 0x1F, 0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC4, 0x35, 0x00, 0x1F, -0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, -0x05, 0xC0, 0x34, 0x10, 0x1F, 0x00, 0x4C, 0x22, 0x34, 0x2C, 0xC0, 0x28, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x64, 0x04, 0x9D, -0x00, 0xC4, 0x3B, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00, 0xFC, 0x03, 0xD0, -0x0D, 0x48, 0x3F, 0x00, 0xF1, 0x03, 0xF4, 0x2B, 0xD0, 0xA5, 0xC0, 0x26, 0x08, -0x1D, 0x00, 0x44, 0x0F, 0x10, 0x3D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xE2, 0x34, 0x0D, 0x40, 0x04, 0x07, 0x90, -0x0C, 0x44, 0x30, 0x08, 0x8C, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48, 0x32, 0x00, -0xC0, 0x01, 0x34, 0x27, 0xD0, 0x20, 0x40, 0x30, 0x04, 0x0D, 0x00, 0x04, 0x00, -0x10, 0x04, 0x41, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x02, 0x7A, 0x02, 0x6D, 0x01, 0x84, 0x07, 0xD0, 0x9E, 0x42, 0x78, 0x00, -0xAD, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x02, 0xE5, 0x01, 0xB4, 0x07, -0xD0, 0x17, 0x40, 0x5B, 0x04, 0x3D, 0x01, 0x84, 0x06, 0x12, 0x92, 0x41, 0x34, -0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x32, 0x00, -0x5F, 0x08, 0x0D, 0x03, 0xF0, 0x0C, 0xC0, 0x31, 0x02, 0x8F, 0x08, 0x34, 0x03, -0xF0, 0x4C, 0xC0, 0x33, 0x0A, 0xC7, 0x10, 0x3C, 0x03, 0xF0, 0xA1, 0xE0, 0x30, -0x00, 0x5F, 0x00, 0x0C, 0x80, 0x30, 0x50, 0xD0, 0x48, 0x40, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xBA, 0x3D, 0x20, 0xFF, 0x00, 0xFC, 0x03, -0xF0, 0x0F, 0xC3, 0x3F, 0x00, 0xBF, 0x28, 0xFC, 0x23, 0xF0, 0x0F, 0xC4, 0x3F, -0x02, 0xDB, 0x10, 0xFC, 0x23, 0xF0, 0x07, 0xE0, 0x3E, 0x80, 0x7F, 0x00, 0xFC, -0x00, 0xF8, 0x81, 0xC2, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA0, 0x57, 0x00, 0xD3, 0x00, 0x7C, 0x6F, 0xB0, 0x5D, 0xE0, 0xB7, -0x14, 0x1F, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xC0, 0xB7, 0x03, 0xD3, 0x15, 0x4C, -0x53, 0xF0, 0x05, 0xE0, 0x77, 0x00, 0x53, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0, -0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x1D, -0x00, 0xEB, 0x00, 0xB4, 0x03, 0x18, 0xCF, 0x60, 0xB8, 0x01, 0xED, 0x00, 0xB4, -0x4B, 0xD0, 0x0E, 0x40, 0x3B, 0x03, 0xC1, 0x04, 0x84, 0x1B, 0xD0, 0x06, 0x40, -0x1B, 0x20, 0x61, 0x20, 0xF4, 0x03, 0x14, 0x0F, 0x40, 0x4C, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79, 0x14, 0x61, 0x21, 0x36, -0x07, 0x18, 0x5E, 0x4C, 0x79, 0x00, 0x6D, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x64, -0x71, 0x01, 0xE1, 0x41, 0x96, 0x17, 0xD0, 0x16, 0x40, 0x7F, 0x00, 0x65, 0x01, -0xB6, 0x07, 0x94, 0x1E, 0x42, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC9, 0x0B, 0x34, 0x83, 0x10, 0x0C, 0x40, -0x30, 0x00, 0xCD, 0x07, 0x74, 0x03, 0xD0, 0x9C, 0x60, 0x33, 0x40, 0xC1, 0x00, -0x15, 0x03, 0xD1, 0x1C, 0x42, 0x33, 0x00, 0xC4, 0x06, 0x34, 0x17, 0x90, 0x9C, -0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, -0x1F, 0x00, 0x73, 0x02, 0x7C, 0x01, 0xB0, 0x05, 0xC2, 0x17, 0x00, 0x7F, 0x10, -0x7C, 0x01, 0xF0, 0x15, 0xC0, 0x13, 0x00, 0x51, 0x00, 0x5C, 0x01, 0xF0, 0x46, -0xC0, 0x1F, 0x00, 0x77, 0x12, 0xFA, 0x1D, 0xB0, 0xB7, 0xC4, 0x5C, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x04, -0x7C, 0x00, 0xF4, 0x01, 0xC8, 0x07, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x07, 0x00, 0x1F, 0x00, 0x64, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x40, 0x1B, -0x00, 0x7C, 0x08, 0x70, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0xE5, 0x04, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0xA0, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27, 0x09, 0x93, -0x00, 0x3C, 0x92, 0x30, 0x19, 0xC1, 0x26, 0x01, 0x9F, 0x00, 0x3C, 0x06, 0x30, -0x89, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x26, 0x10, 0x9D, 0x80, 0x74, 0x32, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, -0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x09, 0x91, 0x23, 0x74, 0x4E, 0x14, -0x99, 0x42, 0xA4, 0x04, 0x9D, 0x00, 0x74, 0x0A, 0x10, 0x29, 0x44, 0x04, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x34, 0x00, 0x9D, -0x00, 0x54, 0x02, 0xC0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x02, 0x50, -0x09, 0x42, 0x25, 0x40, 0x91, 0x18, 0x74, 0x02, 0x90, 0x29, 0x40, 0x26, 0x00, -0x9D, 0x00, 0x74, 0x22, 0x08, 0x08, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x30, 0x05, 0x8D, 0x54, 0x34, 0x02, 0xD0, -0x88, 0x40, 0x23, 0x02, 0x8D, 0x88, 0x05, 0x22, 0x10, 0x88, 0x40, 0x23, 0x00, -0x81, 0x00, 0x30, 0x02, 0x10, 0x08, 0x42, 0x20, 0x00, 0x8D, 0x00, 0x36, 0x23, -0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB0, 0x06, 0x21, 0x1F, 0x24, 0x5C, 0xD0, 0xF0, 0x61, 0xC5, 0x87, 0x05, -0x1F, 0x02, 0x4C, 0x58, 0x70, 0x21, 0xC0, 0x05, 0x05, 0x13, 0x34, 0x7C, 0x50, -0x30, 0x01, 0xC0, 0x86, 0x02, 0x1F, 0x0A, 0x7C, 0x58, 0x34, 0x45, 0xC1, 0x75, -0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x05, -0xBF, 0x34, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xBF, 0x04, 0x7C, 0x12, -0xF4, 0x4B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0x6B, -0x00, 0xBF, 0x21, 0xFC, 0x12, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x02, 0xDC, 0x02, -0xF0, 0x89, 0xC0, 0xA6, 0x15, 0x9B, 0x00, 0x5C, 0x42, 0x30, 0x09, 0xC0, 0x2E, -0x04, 0xBF, 0x00, 0xDC, 0x02, 0xB2, 0x0B, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xCC, -0xC2, 0x32, 0x0B, 0xD0, 0x60, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1C, 0x18, 0x07, 0x01, 0x1B, 0x60, 0x74, 0xA8, 0xD0, 0xA0, 0x42, 0x84, -0x00, 0x11, 0x20, 0x74, 0x08, 0x10, 0x41, 0x40, 0x84, 0x00, 0x17, 0x4A, 0x44, -0x28, 0x10, 0x01, 0x44, 0x07, 0x20, 0x1D, 0x00, 0x44, 0x08, 0x14, 0x01, 0x40, -0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1, -0x84, 0x81, 0x02, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x22, 0x01, 0x85, 0x14, 0x34, -0x52, 0x12, 0x09, 0x61, 0x22, 0x00, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40, -0x33, 0x80, 0x8D, 0x00, 0x04, 0x02, 0x10, 0x08, 0x62, 0x4A, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x99, 0x80, 0x74, -0x02, 0xC0, 0x08, 0x40, 0x26, 0x20, 0x95, 0x02, 0x34, 0x02, 0x10, 0x09, 0x4A, -0x24, 0x00, 0x95, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0x8D, 0x14, -0x45, 0x02, 0x10, 0x0D, 0x40, 0x62, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0xA8, 0x27, 0x01, 0x93, 0x87, 0x7C, 0x02, 0xF0, 0x09, 0xC8, -0x26, 0x08, 0x97, 0x00, 0x5E, 0x02, 0x10, 0x08, 0xC0, 0x26, 0x20, 0x9F, 0x20, -0x5C, 0x02, 0xB0, 0x59, 0xC0, 0x27, 0x20, 0x9E, 0x23, 0x4C, 0x42, 0x30, 0x49, -0xC0, 0x16, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, -0x61, 0x02, 0x9F, 0x05, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x21, 0x40, 0x9B, 0x84, -0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x42, 0xD4, 0x39, -0xC0, 0x27, 0x00, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x48, 0xC0, 0x49, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x84, 0x04, 0x1F, 0x02, -0x6C, 0x00, 0xE0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x80, 0x7C, 0x00, 0x30, 0x01, -0xC0, 0x05, 0x04, 0x1F, 0x10, 0x4C, 0x00, 0x70, 0x11, 0xC2, 0x07, 0x01, 0x1F, -0xA2, 0x3C, 0x20, 0x10, 0x41, 0xC2, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00, 0x5D, 0x20, 0xD4, 0x65, 0xC0, 0x05, -0x40, 0x14, 0x00, 0x50, 0x00, 0x74, 0x81, 0x10, 0x05, 0xC0, 0x1C, 0x00, 0x6D, -0x20, 0x80, 0x0D, 0x70, 0x07, 0x80, 0x1D, 0x10, 0x5D, 0x80, 0xF4, 0x01, 0x10, -0x37, 0x42, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0xA0, 0xF2, 0x02, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x50, 0x30, 0x80, 0xC1, -0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00, 0xCD, 0x0A, 0x00, 0x0B, 0xD8, -0x8C, 0x48, 0xB2, 0x00, 0xCC, 0x00, 0x36, 0x93, 0x90, 0x00, 0x44, 0x53, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xCD, -0x01, 0x94, 0x00, 0xD0, 0x0E, 0x40, 0x38, 0xC2, 0xE1, 0x04, 0xB4, 0x23, 0x11, -0x0E, 0x40, 0x38, 0x80, 0x8D, 0x00, 0x85, 0x0B, 0xD8, 0x06, 0x40, 0x09, 0x20, -0xED, 0x04, 0x34, 0x00, 0x94, 0x0A, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x0D, 0x84, 0x04, 0xF0, -0x1E, 0xC1, 0x70, 0x05, 0xE1, 0x0D, 0x34, 0x57, 0x34, 0x3F, 0xC0, 0x79, 0x00, -0xAF, 0x01, 0x8C, 0x07, 0x70, 0x16, 0xC0, 0x6B, 0x00, 0xEF, 0x0B, 0xBC, 0x07, -0xB0, 0x16, 0xC0, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA2, 0x15, 0x10, 0xDF, 0x84, 0x5C, 0x00, 0xF0, 0x4D, 0xC0, 0x37, 0x00, -0xDF, 0x04, 0x7C, 0x1B, 0xF0, 0x6D, 0xC9, 0x37, 0x20, 0x1B, 0x00, 0x7C, 0x00, -0x78, 0x05, 0xC0, 0x07, 0x10, 0xDF, 0x00, 0x7C, 0x00, 0x74, 0x0D, 0xC0, 0x43, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7D, 0x00, -0xFF, 0x11, 0x8C, 0x24, 0x70, 0x1F, 0xC5, 0x7C, 0x00, 0xF3, 0x11, 0xFC, 0x07, -0x30, 0x1F, 0xC0, 0x7F, 0x02, 0xB7, 0x05, 0xFC, 0x07, 0xF8, 0x96, 0xC0, 0x6C, -0x02, 0xF3, 0x89, 0xCC, 0x07, 0x24, 0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x20, 0xED, 0x04, 0x84, 0x00, -0x18, 0x0E, 0x50, 0x38, 0x22, 0xE1, 0x00, 0xB4, 0x23, 0x10, 0x0E, 0x40, 0x3B, -0x00, 0xA7, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0x48, 0x0D, 0x02, 0xFB, 0x40, 0x85, -0x00, 0xF0, 0x88, 0xE1, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x39, 0x04, 0xED, 0x80, 0xA4, 0x00, 0x58, 0x0C, 0x40, 0x39, -0x00, 0xE9, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x1B, 0x00, 0xA5, 0x04, 0xB4, -0x03, 0xD0, 0x03, 0x46, 0x08, 0x82, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0C, 0x40, -0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61, -0x00, 0xCD, 0x41, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x34, 0x00, 0xD1, 0x42, 0x34, -0x03, 0x12, 0x8C, 0x40, 0x13, 0x00, 0x05, 0x00, 0x34, 0x00, 0xD0, 0xB0, 0x44, -0x01, 0x00, 0xC9, 0x02, 0x04, 0x41, 0xD0, 0x34, 0x50, 0x10, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x45, 0x20, 0xFF, 0x9A, 0x6C, -0x00, 0x41, 0x0F, 0xC0, 0x3D, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0x30, 0x1F, 0xC0, -0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0x44, 0x00, 0x06, 0xF3, 0x42, -0x4C, 0x4B, 0x30, 0x25, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x00, 0xA7, 0x01, 0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0, -0x37, 0x20, 0xDF, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x80, -0x3C, 0x8B, 0xF0, 0x01, 0xC8, 0x87, 0x00, 0xDF, 0x00, 0x3C, 0x00, 0x96, 0x65, -0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, -0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x10, -0x5C, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0x30, 0x03, -0xC1, 0x0D, 0x20, 0xF3, 0x10, 0x7C, 0x07, 0x30, 0x97, 0xC2, 0x13, 0x22, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6, 0x04, 0xDD, 0x00, -0x74, 0x0C, 0xD0, 0x0D, 0x50, 0x34, 0x20, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, -0x40, 0x27, 0x00, 0x19, 0x01, 0x74, 0x18, 0x00, 0x31, 0xC0, 0x47, 0x01, 0xD1, -0x00, 0x74, 0x20, 0x10, 0x29, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x44, 0xD0, 0x0C, -0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0x1D, -0x03, 0x74, 0x10, 0x10, 0x11, 0x40, 0x4F, 0x00, 0xF1, 0x00, 0x74, 0x43, 0x19, -0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x28, 0x20, 0x20, 0xCD, 0x80, 0x24, 0x00, 0xD2, 0x0C, 0x40, 0x30, 0x20, 0xC1, -0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x80, 0x09, 0x00, 0x34, 0x00, 0x10, -0x00, 0x44, 0x07, 0x40, 0xC1, 0x00, 0x34, 0x02, 0x13, 0x84, 0x40, 0x43, 0xA0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0xEF, -0x80, 0x7C, 0x80, 0xF0, 0x0F, 0xC0, 0x38, 0x00, 0xF3, 0x00, 0xC5, 0x03, 0xF0, -0x0F, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05, 0x00, -0xF3, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, -0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, -0x3B, 0x40, 0xFC, 0x00, 0xF0, 0x03, 0xE8, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00, -0xF0, 0x43, 0xC0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA8, 0x3F, 0x04, 0xB3, 0x08, 0xCC, 0x93, 0xF1, 0xCF, 0xC0, 0x3C, 0x42, -0xF3, 0x00, 0xFC, 0x03, 0x30, 0x13, 0xC0, 0x3D, 0x05, 0xF7, 0x2C, 0xFC, 0x04, -0xB0, 0x0F, 0xC0, 0x3E, 0x06, 0x3F, 0x04, 0xEC, 0x03, 0xF0, 0x83, 0xC0, 0x0F, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0xBF, 0x00, -0x1B, 0x04, 0xC4, 0xAF, 0xD0, 0x6F, 0x40, 0xBC, 0x03, 0xF1, 0x84, 0xF4, 0x0F, -0x10, 0x09, 0xC4, 0x7D, 0x08, 0xD5, 0x08, 0x74, 0x00, 0x50, 0x2F, 0x42, 0x3C, -0x10, 0x1D, 0x12, 0xC4, 0x87, 0xD0, 0x40, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x04, 0x81, 0x22, 0x04, 0x03, -0xD0, 0x2C, 0x44, 0x31, 0x01, 0xC1, 0x18, 0x24, 0x0B, 0x50, 0x04, 0x40, 0x31, -0x00, 0xC5, 0x00, 0x74, 0x02, 0x10, 0x2C, 0x44, 0x33, 0x01, 0x8D, 0x06, 0x24, -0x03, 0xD0, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA0, 0x34, 0x30, 0x09, 0x41, 0x46, 0x03, 0xD0, 0x0D, 0x40, 0x35, -0x00, 0xD1, 0x00, 0x74, 0x03, 0x14, 0x0D, 0x40, 0x35, 0x00, 0xD4, 0x00, 0x74, -0x22, 0x50, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00, 0xC4, 0x03, 0xD0, 0x33, 0x40, -0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, -0x00, 0x93, 0x03, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x35, 0x20, 0xD3, 0x80, 0x7C, -0x03, 0x72, 0x91, 0xC8, 0x35, 0x00, 0xD7, 0x80, 0x7C, 0x45, 0xB0, 0x0D, 0xC0, -0x37, 0x18, 0x1F, 0xA2, 0x6C, 0x03, 0xF0, 0x11, 0xC0, 0x03, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x40, 0xFD, -0x03, 0xF0, 0x0D, 0xC2, 0x36, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC1, -0x3F, 0x00, 0xD9, 0x00, 0xFC, 0x41, 0xF0, 0x0D, 0xC0, 0x3E, 0x08, 0xFC, 0x09, -0xFC, 0x03, 0xF0, 0x03, 0x80, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x08, 0x31, 0x01, 0x9F, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x31, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x00, 0xD7, 0x00, -0x4C, 0x22, 0xB0, 0x0C, 0xC8, 0x34, 0x08, 0x07, 0x00, 0x5C, 0x03, 0x30, 0x21, -0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0xFC, 0x0C, 0x9D, 0x00, 0xFC, 0x0F, 0xD0, 0x0F, 0x44, 0x3C, 0x00, 0xF1, 0x00, -0xF4, 0x07, 0xD0, 0x15, 0xC2, 0x39, 0x08, 0xF0, 0x03, 0x2C, 0x8B, 0xD0, 0x0F, -0x48, 0x3C, 0x00, 0xD5, 0x10, 0xC4, 0x2F, 0x10, 0x09, 0x40, 0x4C, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x32, 0x00, 0x0D, 0x00, -0x34, 0x43, 0xD0, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x1B, 0xD2, 0x14, -0x48, 0x32, 0x00, 0xC8, 0x87, 0x04, 0x0D, 0xD0, 0x0C, 0x00, 0x31, 0x00, 0x41, -0x10, 0x14, 0x23, 0x10, 0x00, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x88, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x67, 0xD0, 0x9E, -0x40, 0x78, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x48, 0xED, -0x01, 0xA4, 0x05, 0xD1, 0x1E, 0x40, 0x71, 0x00, 0xE5, 0x01, 0xC4, 0x17, 0x14, -0x92, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x10, 0x30, 0x02, 0xCF, 0x0C, 0x34, 0x03, 0xF0, 0x0C, 0x48, 0x31, 0x00, 0xC3, -0x00, 0x3C, 0x43, 0xF0, 0x04, 0xC1, 0x32, 0x00, 0xCF, 0x10, 0x0C, 0x00, 0xB0, -0x8C, 0xD0, 0x31, 0xA0, 0x17, 0x22, 0x5C, 0x17, 0x30, 0x50, 0xD0, 0x48, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x0C, 0xFF, -0x88, 0xDC, 0x83, 0xF0, 0x2F, 0x00, 0x3F, 0x00, 0xDF, 0x00, 0xF4, 0x03, 0xF0, -0x0F, 0xC0, 0x3D, 0x30, 0xF3, 0x08, 0x7C, 0x01, 0xF0, 0x0F, 0xC0, 0x3E, 0xA0, -0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x24, 0x5F, 0x40, 0x7C, 0x6F, 0x30, -0xBD, 0xC0, 0xF4, 0x05, 0xD3, 0x68, 0x1C, 0x63, 0x70, 0x01, 0xD0, 0x36, 0x01, -0xDF, 0x49, 0x4C, 0x05, 0x30, 0x4D, 0xC9, 0x37, 0x03, 0x1F, 0x00, 0x4D, 0x63, -0xF0, 0x11, 0x84, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x88, 0x39, 0x01, 0x6D, 0x60, 0x36, 0x13, 0x10, 0x4E, 0x40, 0xB8, 0x01, -0xE1, 0x0C, 0x84, 0x03, 0x10, 0x07, 0xC0, 0xB8, 0x04, 0xED, 0x84, 0xAC, 0x01, -0x10, 0x4E, 0x48, 0x3B, 0x04, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x48, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x01, -0xED, 0x03, 0x94, 0x07, 0x18, 0x1E, 0x50, 0x7A, 0x00, 0xC5, 0x01, 0x94, 0x17, -0x50, 0x12, 0x41, 0x78, 0x00, 0xCD, 0x01, 0xC4, 0x04, 0x92, 0x9E, 0x42, 0x7B, -0x01, 0x2D, 0x21, 0x84, 0x07, 0xD0, 0x10, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, -0x15, 0x0C, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10, 0x14, 0x41, 0x30, -0x00, 0xCD, 0x40, 0x24, 0x21, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x04, 0x04, -0x03, 0xD0, 0x8C, 0x40, 0x49, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x0A, 0x7C, 0x81, 0x38, 0x05, 0xC0, 0x16, -0x00, 0x53, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0xCC, -0x85, 0xB0, 0x05, 0xC0, 0x17, 0x10, 0x7F, 0x04, 0x4C, 0x01, 0xF0, 0x17, 0xC0, -0x5D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x07, -0x08, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x00, 0x1C, -0x00, 0xF0, 0x01, 0xC4, 0x05, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01, 0xC2, -0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x41, 0x80, 0x4A, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x40, 0x7C, -0x06, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08, 0x4C, 0x16, 0x30, 0x39, 0xC0, -0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x97, 0x08, -0x5C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x20, 0x66, 0x0E, 0x9D, 0x20, 0x74, 0x0A, 0xD2, 0x09, 0x40, -0x27, 0x00, 0x9D, 0x03, 0x44, 0x0E, 0x15, 0x08, 0x40, 0x64, 0x20, 0x9D, 0x1B, -0x70, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x11, 0x04, 0xAE, 0x10, 0x09, -0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, -0x24, 0x00, 0xDD, 0x00, 0x74, 0x62, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x02, -0x44, 0x42, 0x11, 0x09, 0x40, 0x27, 0x09, 0x9D, 0x00, 0x70, 0x42, 0xD2, 0x09, -0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x0A, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x05, 0x8D, 0x14, -0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x22, 0x8D, 0x48, 0x04, 0x02, 0x11, 0x09, -0x40, 0x21, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x40, 0x81, -0x08, 0x04, 0x92, 0x10, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F, 0x04, 0x7C, 0x50, 0x70, 0x60, -0xC1, 0x83, 0x05, 0x1F, 0x96, 0x4C, 0x50, 0x30, 0xA1, 0xD0, 0x05, 0x05, 0x1F, -0x16, 0x7C, 0x28, 0xE0, 0xE1, 0xC9, 0x07, 0x15, 0x17, 0x16, 0x5C, 0x04, 0x30, -0x11, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, -0xA8, 0x27, 0x25, 0xBF, 0x34, 0x7E, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0x9F, -0x04, 0x7D, 0x02, 0xF0, 0x1B, 0xC0, 0x26, 0x20, 0x9F, 0x04, 0xBC, 0x07, 0xF0, -0x19, 0xC0, 0x27, 0x05, 0xBF, 0x04, 0x7C, 0x22, 0xF4, 0xCB, 0xC1, 0x67, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x03, 0x93, -0x03, 0xCC, 0x12, 0x70, 0x29, 0xC0, 0xA5, 0x00, 0xBF, 0x00, 0xCC, 0x42, 0x30, -0x0B, 0xC0, 0x2E, 0x00, 0xB3, 0x00, 0xCC, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x0B, -0xB3, 0x40, 0xCC, 0x02, 0x30, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x47, 0x01, 0x1B, 0x43, 0x68, 0x28, 0x10, -0x01, 0x40, 0x84, 0x02, 0x1D, 0x0E, 0x45, 0x08, 0x10, 0x01, 0x40, 0x85, 0x02, -0x11, 0x20, 0x44, 0x00, 0x13, 0x21, 0xC0, 0x46, 0x01, 0x1B, 0x00, 0x44, 0x00, -0x10, 0x01, 0x44, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA2, 0xA3, 0x10, 0x81, 0x06, 0x04, 0x02, 0x50, 0x68, 0x40, 0x21, 0x81, -0x8D, 0x90, 0x06, 0x02, 0x10, 0x09, 0x40, 0x21, 0x40, 0x81, 0x16, 0x44, 0x02, -0x90, 0x28, 0x40, 0xA0, 0x01, 0x81, 0x40, 0x05, 0x02, 0x90, 0x08, 0x40, 0x43, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x20, -0x99, 0x02, 0x66, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8D, 0x20, 0x46, 0x02, -0x04, 0x09, 0x40, 0x25, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x18, 0x09, 0x40, 0x27, -0x20, 0x89, 0x00, 0x44, 0x02, 0x84, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x20, 0x93, 0x21, 0x4C, 0x02, -0x70, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27, -0x00, 0x93, 0x00, 0x4C, 0x02, 0xB1, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x13, 0x4C, -0x02, 0xB0, 0x09, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x00, 0x21, 0x00, 0x8F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x89, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7D, -0x26, 0xF1, 0x09, 0xC4, 0x26, 0xA8, 0x9F, 0x03, 0x3C, 0x82, 0x70, 0x09, 0xC0, -0x53, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, -0x04, 0x1F, 0x40, 0x4C, 0x10, 0xF0, 0x00, 0xC0, 0x07, 0x80, 0x13, 0x10, 0x5C, -0x84, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x20, 0x4C, 0x08, 0x30, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x26, 0x4C, 0x00, 0x30, 0x21, 0xC0, 0x53, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x5C, 0x04, 0x5D, 0x00, 0x84, -0x01, 0xD0, 0x05, 0x44, 0x17, 0x40, 0x71, 0x83, 0xF4, 0x01, 0xD0, 0x07, 0x40, -0x14, 0x00, 0x7D, 0x00, 0x84, 0xC5, 0x34, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01, -0xC4, 0x1D, 0x50, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0xA0, 0xB2, 0x20, 0xCD, 0x20, 0x24, 0x2B, 0xD1, 0x0C, 0x40, -0x33, 0x00, 0xC9, 0x08, 0x14, 0x07, 0x52, 0x0D, 0x21, 0x72, 0x80, 0xCD, 0x01, -0x04, 0x07, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x00, 0x07, 0x4F, 0x50, 0x0C, -0x46, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82, -0x38, 0x00, 0xCD, 0x04, 0xA4, 0x01, 0xD0, 0x4E, 0x40, 0x7B, 0x02, 0xE9, 0x00, -0xB4, 0x0A, 0xD0, 0x27, 0x48, 0x38, 0x04, 0xED, 0x02, 0x84, 0x03, 0x10, 0x0E, -0x40, 0x3B, 0x00, 0xED, 0x82, 0xC4, 0x03, 0x50, 0x0E, 0x40, 0x17, 0x08, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x05, -0xAD, 0x07, 0xF0, 0x5E, 0xC0, 0x7F, 0x01, 0x69, 0x41, 0x9C, 0x05, 0x70, 0x1E, -0xE0, 0x7A, 0x00, 0xFE, 0x01, 0xCD, 0x84, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xFF, -0x01, 0xCC, 0x07, 0x70, 0x9E, 0xC2, 0x57, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x42, 0x5C, 0x00, 0xF0, 0xAD, -0xC0, 0x37, 0x00, 0x57, 0x00, 0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x35, 0x00, 0x1F, -0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC1, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x4D, 0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xA0, 0x5F, 0x00, 0xF3, 0x53, 0xFC, 0x26, 0x30, 0x3F, 0xC0, 0xFF, 0x00, 0xFF, -0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC0, 0x7F, 0x22, 0xBF, 0x01, 0xCC, 0x07, 0xF0, -0x1F, 0xC1, 0x7C, 0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1F, 0xC1, 0x08, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0xBD, 0x00, 0xE1, -0x00, 0xB4, 0x0A, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x22, 0x80, 0x02, 0xD0, -0x02, 0x40, 0x3B, 0x00, 0xAD, 0x08, 0x84, 0x23, 0xD2, 0x0E, 0x60, 0x3D, 0x00, -0xEB, 0x00, 0x04, 0x15, 0x10, 0xDD, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x19, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0x94, -0x0E, 0x40, 0x3B, 0x00, 0x8D, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3B, 0x80, -0xED, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x24, 0x12, -0x10, 0x4E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x28, 0x07, 0x10, 0xD1, 0x11, 0x36, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x88, -0x9D, 0x40, 0x04, 0x02, 0xD1, 0x30, 0x40, 0x33, 0x08, 0x1D, 0x00, 0x04, 0x00, -0xD0, 0x0C, 0x40, 0x31, 0x00, 0x09, 0x05, 0x04, 0x80, 0x18, 0x3C, 0x50, 0x58, -0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x24, 0x00, -0xF3, 0x13, 0x7C, 0x02, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0x9F, 0x40, 0x4E, 0x02, -0xF0, 0x29, 0xC1, 0x37, 0x00, 0x5F, 0x00, 0x4C, 0x02, 0xD1, 0x0F, 0x40, 0x3C, -0x00, 0x13, 0x13, 0x2C, 0x03, 0x30, 0x0F, 0xC1, 0x74, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xA7, 0x00, 0xDF, 0x80, 0x7C, 0x00, -0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x42, 0x3F, 0x02, 0xF0, 0x01, 0xC0, 0x37, -0x00, 0x5F, 0x82, 0x7C, 0x00, 0xF0, 0x0D, 0xC8, 0x37, 0x10, 0x1F, 0xA2, 0x7C, -0x02, 0xF5, 0x4D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x81, 0x09, 0x2F, 0x10, 0xF3, 0x00, 0x44, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, -0x00, 0x3F, 0x08, 0xCD, 0x00, 0x30, 0x0B, 0xC1, 0x7F, 0x00, 0xFF, 0x00, 0xCC, -0x00, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0x03, 0x02, 0xCC, 0x25, 0x32, 0x0F, 0xC0, -0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66, -0x00, 0xD5, 0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x02, 0x44, -0x06, 0x50, 0x31, 0x41, 0x37, 0x00, 0x1D, 0x02, 0x44, 0x0C, 0xD0, 0x0D, 0x40, -0x37, 0x00, 0x11, 0x02, 0x44, 0x44, 0x50, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x00, 0xD1, 0x00, 0x54, -0x06, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x44, 0x10, 0x13, 0x40, -0x37, 0x12, 0x1D, 0x00, 0xE4, 0x06, 0xD0, 0x0F, 0x40, 0x37, 0x00, 0x11, 0x50, -0x44, 0x83, 0x50, 0x0D, 0x48, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC5, 0x00, 0x14, 0x02, 0xD8, 0x0C, 0x40, -0x33, 0x08, 0x4C, 0x00, 0x05, 0x00, 0x50, 0x00, 0x40, 0x33, 0x00, 0x0D, 0x00, -0x04, 0x00, 0xD0, 0x0C, 0x48, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x10, 0x51, 0x4C, -0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, -0x06, 0x00, 0xF3, 0x40, 0x5C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x1F, 0x00, -0x4C, 0x00, 0x32, 0x01, 0xC0, 0x27, 0x00, 0xCF, 0x00, 0x4C, 0x00, 0xF0, 0x0E, -0xC4, 0x37, 0x00, 0x13, 0x00, 0x4D, 0x60, 0x30, 0xAF, 0xC0, 0x07, 0xC0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x20, 0xFF, 0x00, -0xEC, 0x00, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x03, -0xC2, 0x2F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F, -0x40, 0x7C, 0x10, 0xE0, 0x6D, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x0B, 0xFF, 0x2C, 0xFC, 0x0A, 0xD0, 0x8F, -0xC0, 0x4C, 0x00, 0x3F, 0x49, 0xEC, 0x93, 0x30, 0x4F, 0xC0, 0x0F, 0x10, 0x33, -0x00, 0xFC, 0x24, 0xB0, 0x4F, 0xC0, 0x6C, 0x00, 0xF3, 0x00, 0x8C, 0x03, 0xB1, -0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x10, 0xBF, 0x01, 0xFD, 0x08, 0x74, 0x8A, 0xD0, 0x6F, 0x44, 0x64, 0x00, 0x19, -0x00, 0xF4, 0x0F, 0x51, 0xAF, 0x40, 0x27, 0x12, 0x11, 0x41, 0x74, 0x12, 0x10, -0x9F, 0x40, 0x74, 0x00, 0xF1, 0x42, 0x44, 0x87, 0x10, 0x11, 0x40, 0x0F, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA8, 0xB3, 0x01, 0xCD, -0x00, 0x36, 0x1A, 0xD0, 0x2C, 0x50, 0x20, 0x00, 0x8D, 0x44, 0x24, 0x0B, 0x11, -0x0C, 0x40, 0x01, 0x00, 0x05, 0x80, 0x74, 0x90, 0x90, 0x0C, 0x40, 0x35, 0x00, -0xC1, 0x02, 0x04, 0x07, 0x90, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xD0, -0x0D, 0x40, 0xE4, 0x00, 0x19, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x60, 0x07, 0x00, -0x31, 0x01, 0x74, 0x0E, 0x10, 0x0D, 0x00, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x87, -0x00, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA8, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x8C, 0xF0, 0x0D, 0xC0, 0xC4, 0x30, -0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC0, 0x07, 0x00, 0x12, 0x05, 0x3C, 0x0E, -0xB1, 0x0C, 0xC0, 0x60, 0x00, 0xD3, 0x00, 0x4C, 0x80, 0xB0, 0x19, 0xC0, 0x23, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, -0xFF, 0x00, 0xFC, 0x02, 0xF2, 0x0E, 0x40, 0x2F, 0x08, 0x3D, 0x40, 0xFC, 0x03, -0xB0, 0x0F, 0xC0, 0x6B, 0xD1, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x2F, -0x00, 0xEF, 0x10, 0xFD, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x08, 0xDF, 0x05, 0x7C, 0x10, -0x70, 0x0D, 0xC6, 0x25, 0x00, 0x9F, 0xC0, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, -0x09, 0x1F, 0x10, 0x7C, 0x02, 0xF0, 0x4D, 0xC0, 0x06, 0x01, 0xD7, 0x00, 0x0C, -0x01, 0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x3C, 0x20, 0xFD, 0x42, 0x74, 0x0E, 0xD0, 0x0F, 0x50, 0x64, -0x00, 0x1D, 0x80, 0xF0, 0x13, 0xD0, 0xAF, 0x40, 0xB7, 0x01, 0x9D, 0x23, 0x74, -0x02, 0xD0, 0x3F, 0x40, 0xA7, 0x80, 0xF1, 0x01, 0x54, 0x01, 0x14, 0x09, 0x41, -0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30, -0x00, 0xCD, 0x02, 0x34, 0x2C, 0x50, 0x0C, 0x48, 0x00, 0x02, 0x09, 0x40, 0x30, -0x03, 0xD0, 0x1C, 0x40, 0x13, 0x00, 0x0D, 0x0B, 0x34, 0x00, 0x90, 0x3C, 0x4C, -0xA2, 0x08, 0xCD, 0x41, 0x04, 0x03, 0x51, 0x08, 0x40, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4, -0x05, 0xD1, 0x1C, 0x40, 0xC8, 0x00, 0x2D, 0x01, 0xB6, 0x0F, 0xD0, 0x1E, 0x41, -0x7B, 0x02, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x1E, 0x40, 0x7F, 0x00, 0xE1, 0x41, -0xD4, 0x2F, 0x50, 0x16, 0x60, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x02, 0x30, 0x08, 0xCF, 0x00, 0x3C, 0x03, 0x70, 0x8C, 0xC0, -0x01, 0x00, 0x8F, 0x8A, 0x3E, 0x23, 0xF0, 0x0C, 0xC0, 0x13, 0x00, 0x4F, 0x00, -0x3C, 0x80, 0xF1, 0x0C, 0xC1, 0x32, 0x00, 0xD7, 0x10, 0x0C, 0x23, 0x70, 0x4C, -0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, -0x3D, 0x24, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x0F, 0x80, 0x1F, 0x00, 0xFF, 0x28, -0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7C, 0x03, 0xF0, 0x0F, -0xE9, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xB4, 0x0D, 0xE0, 0x0B, 0x60, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xF7, 0x04, 0xD7, 0x02, -0x7C, 0x05, 0x30, 0xCD, 0xC0, 0x07, 0x00, 0x9B, 0x00, 0x7C, 0x13, 0xF1, 0xCD, -0xD0, 0x04, 0x40, 0xD3, 0x01, 0x4D, 0x00, 0xF0, 0x6D, 0xC0, 0x27, 0x80, 0xD7, -0x02, 0x7C, 0x03, 0x34, 0x18, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0x80, 0x30, 0x00, 0xE1, 0x56, 0xB4, 0x03, 0xB0, 0x8E, -0x44, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x33, 0xD0, 0x0F, 0x41, 0x2C, 0x00, 0xE1, -0x00, 0x84, 0x01, 0xD0, 0x4E, 0x41, 0x3B, 0x80, 0xED, 0x0E, 0xB4, 0x03, 0xB0, -0x06, 0x40, 0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x00, 0x78, 0x01, 0xED, 0x01, 0x36, 0x05, 0x10, 0x5E, 0x40, 0x7B, 0x18, 0xAD, -0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x7A, 0x00, 0xC1, 0x01, 0xA4, 0x06, 0xD0, -0x1E, 0x40, 0x5B, 0x04, 0xED, 0x25, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xC9, -0x00, 0x34, 0x43, 0x98, 0x0C, 0x40, 0x33, 0x22, 0xCD, 0x0A, 0x34, 0x03, 0xD0, -0x0C, 0x40, 0xB2, 0x03, 0xC1, 0x0A, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x01, -0xCD, 0x00, 0x34, 0x03, 0x90, 0x6C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x17, 0x10, 0x5F, 0x00, 0xFC, 0x81, 0x30, -0x05, 0xE0, 0x5B, 0x00, 0x7B, 0x61, 0x3C, 0x01, 0xF2, 0x05, 0xC0, 0xDE, 0x00, -0x73, 0x01, 0xEC, 0x05, 0xF0, 0x05, 0xCA, 0x1B, 0x00, 0x5F, 0x00, 0xFC, 0x01, -0x30, 0x07, 0xD4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x00, 0x05, 0x08, 0x17, 0x00, 0x78, 0x20, 0xF0, 0x01, 0xC6, 0x47, 0x08, -0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x20, 0xC8, 0x01, 0x00, 0x1F, 0x04, 0x5C, 0x24, -0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x04, 0xF1, 0x21, 0xC0, 0x4B, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, -0x8F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9B, 0x20, 0x4C, 0x82, -0xB0, 0x19, 0x80, 0x24, 0x00, 0x91, 0x01, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE5, -0x00, 0x93, 0x00, 0x7C, 0x02, 0x32, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x45, 0x8E, -0xD0, 0x09, 0x40, 0xE7, 0x10, 0x80, 0x00, 0x44, 0x06, 0x10, 0x49, 0x50, 0x24, -0x02, 0x91, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA7, 0x00, 0x91, 0x0B, 0x34, -0x02, 0x14, 0x29, 0x44, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x18, 0x54, 0x2B, 0xD0, 0x09, 0x40, 0x27, -0x00, 0x98, 0x20, 0x44, 0x52, 0x92, 0x49, 0x48, 0x25, 0x08, 0x95, 0x38, 0x34, -0x02, 0x00, 0x09, 0x42, 0x27, 0x40, 0x91, 0x00, 0x74, 0x06, 0x1C, 0x2D, 0x40, -0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, -0x00, 0x89, 0x14, 0x14, 0x52, 0xD1, 0x88, 0x40, 0x23, 0x08, 0x91, 0x48, 0x00, -0x02, 0x00, 0x08, 0x60, 0x21, 0x00, 0x85, 0x04, 0x36, 0x22, 0x14, 0x08, 0x40, -0x23, 0x00, 0xC1, 0x14, 0x34, 0x56, 0x10, 0x48, 0x41, 0x43, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x05, 0x1F, 0x04, 0x5C, -0x10, 0xF0, 0x61, 0xC1, 0x17, 0x00, 0x1A, 0x02, 0x4C, 0x50, 0xB0, 0xE1, 0xC1, -0x85, 0x47, 0x17, 0x01, 0x7C, 0x08, 0x20, 0x41, 0xC1, 0x15, 0x00, 0x13, 0x0E, -0x7C, 0x10, 0x30, 0x41, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0xEC, 0x52, 0xF0, 0x49, 0xC2, -0x2F, 0x10, 0xBF, 0x44, 0x7D, 0x02, 0xF0, 0x19, 0xC2, 0x6E, 0x00, 0xBB, 0x08, -0xFC, 0x12, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0x9F, 0x81, 0xBC, 0x02, 0xF0, 0x0B, -0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, -0xA7, 0x10, 0xBF, 0x06, 0xCC, 0x46, 0x10, 0x29, 0xC0, 0x2D, 0x00, 0x9F, 0x82, -0xDC, 0x12, 0xF0, 0x0B, 0xC0, 0x2C, 0x05, 0xB3, 0x00, 0x7C, 0x82, 0x30, 0x4B, -0xC1, 0x2F, 0x00, 0xB3, 0x00, 0xBC, 0x93, 0x30, 0x0B, 0xC0, 0x77, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x11, 0x0A, -0x45, 0x0C, 0xB0, 0xE0, 0x40, 0x07, 0x08, 0x17, 0x00, 0x44, 0x00, 0xD0, 0xA1, -0x40, 0x84, 0x08, 0x11, 0x00, 0x74, 0x50, 0x10, 0x21, 0x40, 0x17, 0x00, 0x11, -0x00, 0x74, 0x00, 0x10, 0x01, 0x44, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x20, 0xA1, 0x01, 0x85, 0x04, 0x04, 0x52, 0x58, 0x48, -0x40, 0x23, 0x00, 0x89, 0x00, 0x14, 0x0B, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x85, -0x80, 0x34, 0x02, 0x10, 0x08, 0x42, 0x25, 0x00, 0xC1, 0x00, 0x34, 0x8A, 0x10, -0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD1, 0x09, 0x40, 0x27, 0x0C, 0x95, -0x04, 0x44, 0x02, 0xD0, 0x09, 0x10, 0x24, 0x14, 0x94, 0x04, 0x74, 0x0A, 0x14, -0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x12, 0x18, 0x49, 0x40, 0x63, 0x28, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA2, 0x27, 0x10, 0x97, -0x00, 0x48, 0x1A, 0x70, 0x09, 0xE0, 0xA5, 0x00, 0x9F, 0x93, 0x54, 0x02, 0xF0, -0x09, 0xC4, 0xE4, 0x40, 0x97, 0x00, 0x7C, 0x02, 0x33, 0x09, 0xC0, 0x67, 0x00, -0x91, 0x00, 0x7C, 0x06, 0x34, 0x49, 0x42, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x20, 0x00, 0x9F, 0x90, 0x7C, 0x12, 0xB0, -0x09, 0xC0, 0x67, 0x09, 0x97, 0x21, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x23, 0x11, -0x9B, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0xC0, 0x27, 0x41, 0x9F, 0x20, 0x7C, 0x06, -0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF2, 0x01, 0xC0, 0x86, 0x14, -0x1F, 0x02, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x86, 0x03, 0x1F, 0x28, 0x7C, 0x00, -0xF0, 0x11, 0xC4, 0x04, 0x01, 0x13, 0x10, 0x7C, 0x40, 0x30, 0x21, 0xC0, 0x50, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x00, -0x7D, 0x85, 0xC4, 0x81, 0xD0, 0x05, 0x58, 0xDC, 0x00, 0x5C, 0x00, 0xEC, 0x01, -0xD0, 0x27, 0x41, 0x1F, 0x10, 0x7D, 0x00, 0x74, 0x01, 0xD0, 0x07, 0x40, 0xD8, -0x40, 0x73, 0x02, 0xB4, 0x09, 0x15, 0x07, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xDD, 0x03, 0x74, 0x33, -0xD0, 0x0C, 0x40, 0x71, 0x00, 0xDD, 0x00, 0x04, 0x0B, 0xD0, 0x2C, 0x41, 0xB2, -0x00, 0xCC, 0x04, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC1, 0x02, 0x34, -0x03, 0x90, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x00, 0x94, 0x03, 0xD1, 0x9E, 0x40, 0x99, -0x28, 0xFD, 0x08, 0xA0, 0x03, 0xDA, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB6, -0x13, 0xD0, 0x1E, 0x50, 0x3C, 0x04, 0xA9, 0x00, 0xF4, 0x03, 0x90, 0x1C, 0x41, -0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, -0x10, 0xFF, 0x01, 0xBC, 0x07, 0xF1, 0x5E, 0xC1, 0x6B, 0x00, 0xFE, 0x11, 0x8C, -0x06, 0xC0, 0x12, 0xC0, 0x6A, 0x00, 0xEF, 0x21, 0xBC, 0x47, 0xF0, 0x1C, 0xE2, -0x58, 0x00, 0xA3, 0x01, 0xBC, 0x07, 0xB0, 0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0xB5, 0x05, 0x5F, 0x00, 0x6C, -0x01, 0xF1, 0x2D, 0xC0, 0x06, 0x00, 0xDF, 0x06, 0x7C, 0x00, 0xF0, 0x01, 0xC0, -0x27, 0x10, 0xDF, 0x00, 0x7C, 0x2B, 0xF0, 0x0D, 0xC0, 0x13, 0x00, 0x17, 0x40, -0x7C, 0x03, 0x74, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x06, 0x28, 0x7D, 0x04, 0x73, 0x01, 0xCD, 0x27, 0x30, 0x1F, 0xC2, -0x7F, 0x02, 0xF7, 0x01, 0xCC, 0x05, 0xB4, 0x9F, 0xC8, 0x5F, 0x92, 0x6F, 0x09, -0xDC, 0x07, 0xF0, 0x1F, 0xC0, 0x58, 0x40, 0xB3, 0x09, 0xCC, 0xA5, 0x30, 0x1F, -0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08, -0x39, 0xA0, 0x61, 0x00, 0xAC, 0x03, 0x10, 0x4E, 0x48, 0x2B, 0x82, 0xE1, 0x00, -0x84, 0x08, 0x10, 0x06, 0x40, 0x1B, 0x00, 0xED, 0x08, 0x84, 0x03, 0xD0, 0x06, -0x50, 0x18, 0x02, 0xA1, 0x00, 0x85, 0x33, 0xB0, 0x0A, 0xC8, 0x56, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xC1, 0x08, -0x94, 0x43, 0x18, 0x0E, 0x60, 0x2F, 0x84, 0xE5, 0x00, 0x84, 0x00, 0x10, 0x06, -0x08, 0x1B, 0x00, 0x2D, 0x00, 0x94, 0x43, 0xD0, 0x8E, 0x40, 0x0E, 0x00, 0x81, -0x80, 0xC4, 0x01, 0x18, 0x0E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x01, 0x00, 0x50, 0x02, 0x18, 0x0D, -0x44, 0x63, 0x00, 0xC5, 0x02, 0x04, 0x00, 0x10, 0x00, 0x44, 0x83, 0x00, 0x8D, -0x02, 0x04, 0x4F, 0xD0, 0x04, 0x40, 0xC2, 0x02, 0x01, 0x00, 0x44, 0x01, 0x90, -0xA8, 0x40, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xA8, 0x3D, 0x00, 0x93, 0x00, 0x54, 0x28, 0x30, 0x0F, 0xC0, 0x67, 0x00, 0xF7, -0x00, 0x4C, 0x02, 0x30, 0x09, 0x40, 0x27, 0x00, 0x9F, 0x06, 0xDC, 0x0F, 0xF0, -0x0C, 0x40, 0x62, 0x08, 0x91, 0x00, 0x4C, 0x03, 0x11, 0x3D, 0xC8, 0x54, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00, 0x9F, -0x02, 0x64, 0x02, 0xF0, 0x0D, 0xC0, 0x87, 0x28, 0xDA, 0x11, 0x7C, 0x0A, 0x70, -0x09, 0xC0, 0x87, 0x10, 0xDF, 0x10, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x05, 0x04, -0x9F, 0xC0, 0x6C, 0x03, 0xF0, 0x2D, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x00, 0xB3, 0x80, 0x7C, 0x00, 0x31, -0x0F, 0xE0, 0x0C, 0x04, 0xF7, 0x00, 0x7C, 0x02, 0xF0, 0x03, 0x40, 0x2F, 0x04, -0x37, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x0C, 0x40, 0xB2, 0x00, 0xFC, 0x02, -0x70, 0x05, 0xC1, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA1, 0x20, 0x36, 0x00, 0x91, 0x03, 0x74, 0x04, 0x10, 0x0D, 0x48, 0x44, 0x01, -0xDD, 0x00, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x4D, 0x00, 0x6C, 0x03, -0xD0, 0x09, 0x40, 0x44, 0x00, 0x11, 0x07, 0x74, 0x02, 0x10, 0x44, 0x42, 0x84, -0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, -0x11, 0x01, 0x74, 0x04, 0x10, 0x0D, 0x40, 0x64, 0x18, 0xDD, 0x00, 0x74, 0x06, -0xD0, 0x1B, 0x60, 0xCF, 0x00, 0x1D, 0x58, 0x44, 0x03, 0xD0, 0x1D, 0x70, 0xC4, -0x00, 0x35, 0x81, 0x74, 0x21, 0x50, 0x0D, 0x40, 0x05, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x01, 0x00, 0x24, 0x02, -0x10, 0x0C, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x02, -0x20, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x00, 0x40, 0x04, 0x00, 0x05, 0x00, 0x64, -0x83, 0x14, 0x08, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x10, 0x3A, 0x08, 0x93, 0x00, 0x7C, 0x00, 0x30, 0x0F, 0x40, 0x04, -0x10, 0xE7, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x60, 0xCC, -0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x71, 0x05, 0xC0, -0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x38, 0x3F, -0x20, 0xBF, 0x80, 0xFE, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x00, 0xFF, 0x00, 0xFC, -0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x83, 0xF0, 0x03, 0xC8, -0x0F, 0x00, 0x3B, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC2, 0x17, 0x62, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x7F, 0x02, 0xFB, 0x09, 0xAC, -0x07, 0xB0, 0x1F, 0xC0, 0x7A, 0x00, 0xFD, 0x21, 0xEC, 0x07, 0xB0, 0x1F, 0xC0, -0x7A, 0x08, 0xFB, 0x89, 0xCC, 0x07, 0xF2, 0x1F, 0xC0, 0x7D, 0x12, 0xFB, 0x09, -0xEC, 0x87, 0x33, 0x1E, 0xD2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x00, 0x07, 0x01, 0x11, 0x04, 0x44, 0x04, 0x30, 0x11, 0x40, -0x44, 0x00, 0x11, 0x01, 0x40, 0x00, 0x10, 0x40, 0x47, 0x44, 0x00, 0x0D, 0x00, -0x44, 0x04, 0x10, 0x11, 0xC0, 0x05, 0x39, 0x11, 0x24, 0x44, 0x10, 0xB2, 0x11, -0x44, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x35, 0x18, 0xD9, 0x60, 0x34, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xD9, 0xA0, -0x64, 0x53, 0x92, 0x0D, 0x40, 0x33, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x90, 0x0C, -0x40, 0x36, 0x00, 0xDD, 0x04, 0x34, 0x43, 0x19, 0x0C, 0x40, 0x4C, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x07, 0x08, 0x11, 0x00, -0x44, 0x00, 0xD1, 0x01, 0x40, 0x04, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, -0x40, 0x05, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x05, 0x18, 0x15, -0x00, 0x14, 0x00, 0x90, 0x01, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA0, 0x32, 0x20, 0xCB, 0x20, 0x6C, 0x03, 0xF0, 0x0D, -0xC0, 0x36, 0x80, 0xCF, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x08, 0xDB, -0x00, 0x4C, 0x03, 0xB0, 0x0C, 0x80, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x32, -0x0C, 0xC8, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x88, 0x0D, 0x00, 0x3F, 0x80, 0xF8, 0x40, 0x30, 0x03, 0xC3, 0x0D, 0x80, 0x3E, -0x00, 0xF8, 0x00, 0xF0, 0x03, 0xC0, 0x0E, 0x08, 0x3D, 0x00, 0xF8, 0x00, 0xB0, -0x03, 0x82, 0x0F, 0x00, 0x3B, 0x30, 0xE8, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD7, -0x00, 0x6C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x36, 0x04, 0xDF, 0x00, 0x5C, 0x93, 0x31, 0x0D, 0xC1, 0x34, 0x02, -0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC1, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x84, 0x06, 0x11, 0x40, 0x34, 0x4C, 0x10, -0x20, 0x41, 0x83, 0x24, 0x10, 0x00, 0x74, 0x04, 0x10, 0xB0, 0x00, 0x04, 0x00, -0x02, 0x00, 0x04, 0x0C, 0x10, 0x31, 0x42, 0x03, 0x00, 0x0C, 0x03, 0x70, 0x80, -0x10, 0x21, 0x40, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0x20, 0x70, 0x10, 0xC5, 0x80, 0x24, 0x07, 0x40, 0x0C, 0x40, 0x33, 0x01, -0xC5, 0x00, 0x24, 0x47, 0x50, 0xAC, 0x40, 0x31, 0x08, 0xC4, 0x00, 0x14, 0x0B, -0x14, 0x3C, 0x00, 0x30, 0x04, 0xCD, 0x00, 0x34, 0x03, 0x98, 0x2C, 0x40, 0x0F, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x4C, 0x0A, -0x21, 0x09, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x25, 0x37, 0xF6, 0x04, -0x12, 0x12, 0x60, 0x49, 0x02, 0x21, 0x01, 0x84, 0x04, 0x00, 0x12, 0x41, 0x4B, -0x02, 0x2D, 0x11, 0xB4, 0x24, 0x80, 0x12, 0x42, 0x3E, 0x20, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x23, -0x51, 0x8C, 0xC0, 0x33, 0x00, 0xCF, 0x08, 0x3C, 0x43, 0x70, 0x0C, 0xC4, 0x31, -0x06, 0xC7, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xCF, 0x00, 0x7C, -0x03, 0xF0, 0x0C, 0xE4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x38, 0x09, 0x20, 0x3F, 0x00, 0xF0, 0x00, 0xF0, 0x03, 0xC2, 0x0F, -0x00, 0x3B, 0x2C, 0xBC, 0x20, 0x70, 0x03, 0xC0, 0x0C, 0x02, 0x3F, 0x00, 0xBC, -0x20, 0xF8, 0x83, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0xFC, 0x00, 0x71, 0x11, 0xC8, -0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x77, -0x00, 0xC3, 0x40, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xC7, 0x01, 0x6C, -0x07, 0x36, 0x0D, 0xC4, 0x70, 0x00, 0xDB, 0x40, 0x6C, 0x03, 0xF0, 0x0C, 0xD0, -0x34, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x0D, 0x08, 0x2B, 0x00, 0x84, -0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x60, 0x84, 0x00, 0x10, 0x02, 0x42, -0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0x90, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0xB4, 0x00, 0x10, 0x02, 0x40, 0x4F, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA6, 0x07, 0xD9, 0x1E, 0x40, -0x7B, 0x00, 0xF5, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x10, 0xE9, 0x01, -0xB4, 0x07, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xE1, 0x01, 0xD4, 0x07, 0x90, 0x1E, -0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, -0x03, 0x00, 0x19, 0x00, 0x06, 0x00, 0xD0, 0x00, 0x42, 0x03, 0x00, 0x05, 0x00, -0x04, 0x00, 0x18, 0x00, 0x50, 0x01, 0x00, 0x01, 0x00, 0x14, 0x00, 0x90, 0x00, -0x60, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x5B, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5B, 0x80, -0x2C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x40, 0x6C, 0x01, 0x30, 0x05, -0xCA, 0x14, 0x10, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x10, 0x00, 0x53, -0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x08, 0x3F, 0x00, 0xFC, 0x08, 0xE0, 0x03, -0xC0, 0x0F, 0x20, 0x39, 0x20, 0xFC, 0x08, 0xF0, 0x03, 0x00, 0x0E, 0x00, 0x3F, -0x40, 0xE4, 0x80, 0xC2, 0x03, 0xC0, 0x8F, 0x00, 0x3B, 0x20, 0xFC, 0x00, 0xF0, -0x03, 0xC0, 0x4B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x22, 0x30, 0x49, 0xC0, 0x25, 0x00, 0x9F, -0xC0, 0x7C, 0x02, 0xF1, 0x09, 0x80, 0xE5, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0x70, -0x09, 0xC0, 0x24, 0x00, 0x97, 0x01, 0x7C, 0x16, 0x30, 0x09, 0x80, 0x41, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE4, 0x23, 0x9D, -0x00, 0x45, 0x0A, 0x10, 0x18, 0x80, 0x26, 0x00, 0x9C, 0x11, 0x70, 0x06, 0xD0, -0x28, 0x40, 0x64, 0x04, 0x8D, 0x80, 0x04, 0x02, 0x00, 0x09, 0x40, 0x64, 0x03, -0x91, 0x02, 0x74, 0x0E, 0x10, 0x18, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0xBD, 0x80, 0xC4, 0x02, 0x50, -0x0B, 0x40, 0x2C, 0x01, 0xBC, 0x08, 0xF0, 0x22, 0xD2, 0x0B, 0x41, 0x2D, 0x00, -0xBD, 0x00, 0xD4, 0x02, 0x42, 0x0B, 0x40, 0x2C, 0x00, 0xB5, 0x0A, 0xF4, 0xC2, -0x00, 0x4B, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x29, 0x00, 0xAD, 0x00, 0xD4, 0x03, 0x54, 0x1B, 0x40, 0x6A, 0x20, -0xAC, 0xA0, 0xB0, 0xA3, 0xD1, 0x8B, 0x40, 0x29, 0x00, 0xBD, 0x68, 0xC4, 0x02, -0x51, 0x0B, 0x40, 0x28, 0x02, 0xA1, 0x08, 0xB0, 0x22, 0x11, 0x0B, 0x44, 0x51, -0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x08, -0x1F, 0x80, 0x4C, 0x00, 0x74, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x38, 0x08, -0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x22, 0x5C, 0x00, 0x72, 0x01, 0xD0, 0x80, -0x00, 0x17, 0x02, 0x78, 0x08, 0x34, 0x03, 0xC0, 0x75, 0xC0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0x6C, 0x02, -0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x12, 0xF0, 0x49, 0x80, 0x26, -0x00, 0x9F, 0x04, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x01, 0x9F, 0x04, 0x3C, -0x12, 0xF4, 0x09, 0xC0, 0x66, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1D, 0xA8, 0xAF, 0x00, 0x9F, 0x02, 0xF4, 0x02, 0x30, 0x0B, 0xC0, 0x2B, -0x00, 0xBF, 0x80, 0xCC, 0x82, 0xF0, 0x0B, 0xD0, 0x2C, 0x00, 0x8B, 0x82, 0x8C, -0x02, 0xB0, 0x0B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xCD, 0x0A, 0xB0, 0x0A, 0xC0, -0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x47, -0x01, 0x0D, 0x05, 0x74, 0x00, 0xB0, 0x01, 0x40, 0x07, 0x08, 0x1D, 0x00, 0x6C, -0x10, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54, 0x00, 0x10, 0x01, 0x40, -0x00, 0x01, 0x1D, 0x00, 0x45, 0x10, 0x10, 0x01, 0x42, 0x70, 0x60, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x21, 0x00, 0x8D, 0x00, 0x34, -0x02, 0x10, 0x0C, 0x40, 0x23, 0x08, 0x9D, 0xA0, 0x04, 0x42, 0xD0, 0x08, 0x41, -0x24, 0x00, 0x89, 0x00, 0x64, 0x02, 0x90, 0x09, 0x40, 0x22, 0x04, 0x8D, 0x00, -0x44, 0x02, 0x90, 0x08, 0x50, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x20, 0x25, 0x10, 0x9D, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, -0x27, 0x00, 0x9D, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, -0x74, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x10, 0x09, -0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, -0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x20, -0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x20, 0x00, 0x9B, 0x00, 0x2C, 0x02, 0xB0, 0x08, -0xC0, 0x26, 0x00, 0x9E, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x14, 0x28, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F, 0x00, -0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x58, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4D, 0x10, 0xF0, 0x01, -0xC0, 0x07, 0x04, 0x17, 0x40, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x17, -0x00, 0x5C, 0x40, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x90, 0x34, -0x01, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA0, 0xDC, 0x01, 0x5D, 0x00, 0xC4, 0x05, 0xD0, 0x87, 0x48, 0x5F, 0x04, 0x71, -0x07, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x1F, 0x02, 0x51, 0x00, 0xC0, 0x11, 0x10, -0xB7, 0x40, 0x5F, 0x00, 0x70, 0x01, 0x84, 0x01, 0x10, 0x06, 0x40, 0x50, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB2, 0x08, 0xCD, -0x00, 0x14, 0x0A, 0xD8, 0x2C, 0x40, 0xB3, 0x00, 0xD4, 0x11, 0x34, 0x07, 0x10, -0x1D, 0x40, 0xA3, 0x00, 0xD5, 0x00, 0x14, 0x0E, 0x14, 0x1C, 0x40, 0x63, 0x00, -0xC4, 0x05, 0x14, 0x2B, 0x14, 0x24, 0x40, 0x51, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x01, 0x84, 0x08, 0xD1, -0x0E, 0x40, 0x7F, 0x00, 0x61, 0x80, 0xB0, 0x0F, 0x10, 0x0E, 0x4D, 0x2F, 0x00, -0xF1, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x6B, 0x04, 0xF5, 0x30, 0x84, 0x03, -0x14, 0x07, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x18, 0x59, 0x00, 0xEF, 0x09, 0x9C, 0x05, 0xF1, 0x1A, 0xC0, 0x4B, 0x00, -0xE7, 0x41, 0xFC, 0x07, 0x34, 0x16, 0xC0, 0x7B, 0x00, 0xE7, 0x77, 0x9C, 0x06, -0x30, 0x1E, 0xC2, 0x7B, 0x00, 0x67, 0xE1, 0xDC, 0x06, 0x30, 0x16, 0x80, 0x45, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, -0xDF, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC4, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x00, -0xE0, 0x05, 0xC0, 0x33, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC4, 0x17, -0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7F, 0x22, 0xFF, 0x11, 0xF8, 0x04, -0xF0, 0x9F, 0xC0, 0x7F, 0x00, 0xAF, 0x01, 0xDC, 0x86, 0x30, 0x9F, 0xC8, 0x6B, -0x00, 0xFB, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xE4, 0x6F, 0x00, 0xB3, 0x09, 0xC4, -0x07, 0x30, 0x16, 0xC8, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x00, 0x39, 0x00, 0xED, 0x04, 0xBC, 0x40, 0xD8, 0x8A, 0x40, 0x2B, -0x01, 0x2D, 0x00, 0x84, 0x22, 0x10, 0x8A, 0x42, 0x2B, 0x00, 0xE1, 0x08, 0x84, -0x42, 0xD0, 0x02, 0x40, 0x2B, 0x01, 0xBB, 0x0C, 0xC4, 0x13, 0xB0, 0x0E, 0x40, -0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x19, -0x30, 0xED, 0x40, 0xB4, 0x01, 0xD0, 0x0A, 0x48, 0x0B, 0x80, 0xED, 0x00, 0xB4, -0x03, 0x94, 0x86, 0x44, 0x3F, 0x04, 0xE9, 0x00, 0x84, 0x03, 0xD0, 0x8A, 0x41, -0x2B, 0x24, 0x21, 0x40, 0xD5, 0x00, 0x11, 0x07, 0x40, 0x22, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x83, 0x00, 0xCD, 0x09, 0x36, -0x85, 0xD0, 0xA0, 0x40, 0xE3, 0x84, 0xCD, 0x0C, 0x74, 0x08, 0x90, 0x01, 0x40, -0xD3, 0x00, 0xD1, 0x52, 0x04, 0x06, 0xD0, 0x00, 0x48, 0xD3, 0x80, 0x09, 0x03, -0x14, 0x28, 0x90, 0xAC, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xA0, 0xE5, 0x2C, 0xFF, 0x0B, 0x7C, 0x2C, 0xF0, 0x30, 0xC0, -0x67, 0x01, 0xDF, 0x02, 0x7C, 0x19, 0xB0, 0xD9, 0xC0, 0xA7, 0x02, 0xFB, 0x87, -0x4F, 0x02, 0xE0, 0x2C, 0x00, 0x07, 0x02, 0xD3, 0x11, 0x5D, 0x0D, 0x31, 0x95, -0xC0, 0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, -0xA7, 0x00, 0xDE, 0x60, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x1F, 0x02, -0x40, 0x01, 0x70, 0x25, 0xC0, 0x27, 0x20, 0xDF, 0x80, 0x7C, 0xCA, 0xF0, 0x09, -0xC9, 0x07, 0x00, 0xDF, 0x52, 0x68, 0x41, 0xF0, 0x05, 0xC0, 0xA7, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x09, 0x2F, 0x14, 0xFF, 0x00, -0xFC, 0x01, 0xF8, 0x03, 0xC1, 0x0E, 0x00, 0xFF, 0x01, 0xCC, 0x43, 0x30, 0x8B, -0xC0, 0x6C, 0x20, 0xFF, 0x00, 0xCD, 0x06, 0xF0, 0x8F, 0xC8, 0x3C, 0x00, 0x77, -0x05, 0xFC, 0x07, 0x34, 0x03, 0xC0, 0x15, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x89, 0x20, 0x66, 0x01, 0xDD, 0x00, 0x74, 0x08, 0xD8, 0x31, -0x40, 0x64, 0x00, 0x8D, 0x05, 0x44, 0x08, 0x50, 0x05, 0x40, 0x34, 0x00, 0xDE, -0x00, 0x44, 0x62, 0xD0, 0x19, 0x44, 0x90, 0x00, 0x91, 0x04, 0x74, 0x4B, 0x30, -0x00, 0x40, 0x14, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0xA0, 0x46, 0x00, 0xDD, 0x80, 0x74, 0x00, 0xD0, 0x19, 0x00, 0x46, 0x00, 0x1D, -0x08, 0x44, 0x08, 0x10, 0x09, 0x41, 0x25, 0x02, 0xD9, 0x00, 0x64, 0x03, 0xD0, -0x09, 0x40, 0x84, 0x30, 0x95, 0x00, 0x30, 0x20, 0x02, 0x45, 0x40, 0x05, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, -0x00, 0x34, 0x00, 0xD0, 0x08, 0x44, 0x40, 0x00, 0x0D, 0x00, 0x05, 0x00, 0x50, -0x00, 0x50, 0x20, 0x10, 0xC5, 0x00, 0x04, 0x01, 0xD0, 0x01, 0x10, 0x04, 0x88, -0x41, 0x00, 0x34, 0x00, 0x11, 0x0C, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x19, 0x06, 0x00, 0xFF, 0x00, 0x7C, 0x01, 0xD0, -0x09, 0xC0, 0x06, 0x00, 0x5F, 0x00, 0x0C, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x10, -0xED, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x20, 0x20, 0x17, 0x00, 0x7C, 0x00, -0x34, 0x01, 0xC0, 0x05, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xB8, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x00, -0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x01, -0xF1, 0x03, 0xE0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x0B, 0xD0, 0x17, -0x24, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x2F, 0x04, -0xFF, 0x01, 0xEC, 0x52, 0xD0, 0x1F, 0xC0, 0x3E, 0x21, 0x2F, 0x01, 0xFC, 0x13, -0x30, 0x0D, 0xC0, 0x57, 0x00, 0x8B, 0x21, 0xCE, 0x23, 0xB0, 0x6F, 0xC0, 0xBC, -0x09, 0x3F, 0x04, 0xCC, 0x93, 0x33, 0x03, 0xC2, 0x0F, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x87, 0x10, 0xDD, 0x00, 0x74, 0x0E, -0xD8, 0x1D, 0x40, 0x7F, 0x0A, 0x9D, 0x01, 0xF4, 0x2F, 0x10, 0x2F, 0x44, 0x57, -0x10, 0x91, 0x00, 0x44, 0x33, 0x10, 0x2F, 0x40, 0xBC, 0x01, 0x5D, 0x09, 0xC4, -0xDB, 0x10, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x03, 0x05, 0xCD, 0x54, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33, -0x00, 0xCD, 0x01, 0x34, 0x03, 0x18, 0x2C, 0x40, 0x14, 0x00, 0xDD, 0x00, 0x15, -0x13, 0xD0, 0x6C, 0x40, 0xB1, 0x08, 0x8D, 0x00, 0x54, 0x23, 0x10, 0x00, 0x40, -0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x45, -0x00, 0xDD, 0x04, 0x74, 0x84, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0xDC, 0x00, 0x74, -0x03, 0x10, 0x0D, 0x40, 0x17, 0x00, 0x95, 0x00, 0x64, 0x03, 0x50, 0x0D, 0x4A, -0x35, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0xDF, 0x20, 0x6C, -0x14, 0xD0, 0x0D, 0xC0, 0x36, 0x00, 0x5F, 0xE8, 0x7C, 0x03, 0x31, 0x0D, 0xC0, -0x42, 0x00, 0x8B, 0x40, 0x4C, 0x03, 0xF0, 0x0D, 0x40, 0x35, 0x10, 0x4E, 0x52, -0x1C, 0x03, 0x14, 0x19, 0xC0, 0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0F, 0x80, 0x05, 0x00, 0xFF, 0x41, 0xFC, 0x02, 0xF2, 0x2F, 0xC1, -0x3F, 0x0C, 0x7F, 0x01, 0xB0, 0x03, 0xF0, 0x0F, 0xC0, 0x4F, 0x02, 0xB8, 0x40, -0xD8, 0x03, 0xB0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF, 0x03, 0xEC, 0x23, 0xF4, 0x03, -0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, -0x65, 0x01, 0xD3, 0x00, 0x7C, 0x0C, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x5B, 0x00, -0x4C, 0x43, 0xF0, 0x8D, 0xC0, 0x97, 0x00, 0xDF, 0x08, 0x5C, 0x03, 0xF1, 0x0D, -0xC0, 0x37, 0x00, 0x5F, 0x00, 0x5C, 0x43, 0xF0, 0x89, 0xC0, 0x2B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0xD1, 0x0B, -0x74, 0x00, 0xD0, 0x3D, 0x40, 0xBF, 0x24, 0x51, 0x0A, 0xC4, 0x1B, 0xD0, 0xBF, -0x40, 0x17, 0x06, 0x9C, 0x00, 0xC4, 0x03, 0xD0, 0x0F, 0x04, 0x3C, 0x10, 0xDC, -0x01, 0x40, 0x0B, 0x10, 0xB9, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0x20, 0xA0, 0x00, 0xC1, 0x01, 0x24, 0x02, 0xD0, 0x1C, -0x40, 0x33, 0x00, 0x09, 0x0B, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x83, 0x08, 0x88, -0x01, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0x4D, 0x13, 0x10, 0x2F, 0x50, -0x08, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, -0x00, 0x78, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x49, 0x7B, 0x00, 0xB5, -0x09, 0xA4, 0x87, 0xD0, 0x5E, 0x40, 0x4B, 0x09, 0xAD, 0x25, 0x80, 0x07, 0xD0, -0x1C, 0x40, 0x78, 0x00, 0xCD, 0x21, 0xC0, 0x27, 0x00, 0x12, 0x40, 0x3F, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x10, 0x02, 0xC3, -0x18, 0x3C, 0x23, 0xF8, 0x0C, 0xC0, 0x33, 0x01, 0x8B, 0x08, 0x2C, 0x03, 0xF0, -0x5C, 0x80, 0x43, 0x01, 0xCF, 0x05, 0x1C, 0x03, 0xF0, 0x4C, 0xC0, 0x31, 0x00, -0x4F, 0x10, 0x5C, 0x37, 0x70, 0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0xFF, 0x08, 0xFC, 0x23, 0xF0, -0x0F, 0xC8, 0x3B, 0x00, 0xFB, 0x68, 0xDC, 0x23, 0xF0, 0x2F, 0xC1, 0x0F, 0x20, -0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x08, 0x7C, 0xAB, -0x52, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x78, 0x01, 0xF0, 0x0D, 0xC0, 0x36, 0x04, -0x1F, 0x00, 0x4C, 0x63, 0xF0, 0x4D, 0xC8, 0x06, 0x08, 0x93, 0x00, 0x7C, 0x03, -0xF1, 0xFD, 0xC0, 0xB6, 0x01, 0x5F, 0x01, 0x6C, 0x0A, 0x30, 0x0D, 0xC0, 0x40, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x90, 0x39, 0x00, -0xED, 0x80, 0xB4, 0x03, 0xC1, 0x0E, 0xC0, 0x39, 0x01, 0xED, 0x00, 0x84, 0x03, -0xD1, 0x4E, 0x42, 0x0A, 0x00, 0xA5, 0x00, 0xB4, 0x13, 0xD1, 0x0E, 0x41, 0x38, -0x0D, 0xED, 0x00, 0x84, 0x02, 0x12, 0x06, 0xC0, 0x4E, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x28, 0xED, 0x21, 0xB0, 0x07, -0xD9, 0x1E, 0x40, 0x7B, 0x03, 0xAD, 0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x4A, -0x08, 0xE1, 0x21, 0xB4, 0x27, 0xD0, 0x1C, 0x40, 0x7A, 0x02, 0x7D, 0x01, 0xA4, -0x06, 0x10, 0x1C, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x16, 0x00, 0x37, 0x04, 0x9D, 0x41, 0x34, 0x47, 0xD0, 0x08, 0x40, 0x31, -0x00, 0xCD, 0x08, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x62, 0x80, 0x85, 0x00, 0x34, -0x03, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0x2D, 0x40, -0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x9F, -0x00, 0x5D, 0x01, 0xFE, 0x1D, 0xF0, 0x15, 0xE1, 0x16, 0x00, 0x6F, 0x03, 0x6F, -0x01, 0xF0, 0x05, 0xC0, 0x5A, 0x04, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, -0x16, 0x00, 0x7F, 0x10, 0x6C, 0x45, 0x30, 0x47, 0xC0, 0x5C, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x05, 0x00, 0x1F, 0x08, 0x7E, -0x00, 0xF0, 0x01, 0xA0, 0x07, 0x00, 0x1F, 0x04, 0x5E, 0x00, 0xF0, 0x20, 0x08, -0x07, 0x01, 0x1F, 0x80, 0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x03, 0x20, 0x1D, 0x24, -0x7C, 0x00, 0xF0, 0x21, 0xD8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0xC1, 0x2C, 0x82, 0xE1, 0x19, 0xC0, -0x25, 0x09, 0x9F, 0x00, 0x4C, 0x92, 0xD0, 0x19, 0xC0, 0x64, 0x10, 0x93, 0x08, -0x3C, 0x02, 0x40, 0x09, 0xC4, 0x27, 0x00, 0x93, 0x80, 0x7C, 0x02, 0x75, 0x09, -0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, -0x66, 0x00, 0x91, 0x81, 0x4C, 0x02, 0x10, 0x98, 0x00, 0xA5, 0x00, 0x9D, 0x18, -0x45, 0x0A, 0xD0, 0xA9, 0x50, 0x24, 0x03, 0x95, 0x00, 0x74, 0x02, 0x13, 0x09, -0x44, 0x27, 0x00, 0x91, 0x1B, 0x34, 0x06, 0x12, 0x69, 0x50, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34, 0x82, 0x99, 0x08, -0x64, 0x06, 0x10, 0x09, 0x00, 0xA4, 0x00, 0x99, 0x00, 0x54, 0x42, 0xD2, 0x09, -0x45, 0x34, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x40, 0x91, -0x00, 0x74, 0x12, 0x51, 0x0D, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x22, 0x30, 0x15, 0xC1, 0x00, 0x04, 0x52, 0x12, 0x19, -0x42, 0x21, 0x80, 0x8D, 0x40, 0x06, 0x82, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x85, -0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x23, 0x02, 0x81, 0x00, 0x70, 0xD2, 0x10, -0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0x38, 0x07, 0x01, 0x1B, 0x00, 0x6C, 0x10, 0x70, 0x01, 0xC0, 0x05, 0x05, 0x1B, -0x40, 0x48, 0xD0, 0xF0, 0xE1, 0xC1, 0x04, 0x00, 0x53, 0x0A, 0x7C, 0x58, 0x71, -0x61, 0xC1, 0x87, 0x05, 0x13, 0x14, 0x38, 0x11, 0x70, 0x41, 0xC0, 0x74, 0xE0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2D, 0x45, 0xBF, -0x14, 0xDC, 0x02, 0xB4, 0x0B, 0xC0, 0x27, 0x00, 0xAC, 0x00, 0x7C, 0x02, 0xF0, -0x19, 0xC0, 0x2B, 0x08, 0xBF, 0x01, 0x7C, 0x12, 0xB1, 0x49, 0xC0, 0x27, 0x11, -0xAF, 0x00, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xBF, 0x00, 0xB3, 0x00, 0xFC, 0x52, 0xF0, -0x0B, 0xC0, 0x2D, 0x05, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C, 0x00, -0xBF, 0x80, 0x6C, 0x02, 0x10, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02, -0x32, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x87, 0x00, 0x1B, 0xA4, 0x74, 0x08, 0xD0, 0x01, 0x40, 0x84, 0x48, -0x11, 0x20, 0x44, 0x00, 0xD2, 0xA1, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x40, 0x90, -0x10, 0x41, 0x40, 0x04, 0x01, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x60, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1, 0x21, -0x81, 0x10, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x21, 0x00, 0xD5, 0x00, 0x04, 0x0B, -0xD0, 0x0D, 0x40, 0x20, 0x00, 0x8D, 0x80, 0x30, 0x4A, 0x11, 0x28, 0x41, 0xA2, -0x04, 0x8D, 0x00, 0x05, 0x82, 0x14, 0x08, 0x40, 0x49, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x99, 0x04, 0x74, 0x02, -0xD0, 0x49, 0x40, 0x26, 0x08, 0x95, 0x00, 0x44, 0x02, 0xC0, 0x09, 0x40, 0x25, -0x0D, 0x9D, 0x80, 0x14, 0x02, 0x10, 0x08, 0x46, 0x26, 0x00, 0x9D, 0x10, 0x44, -0x02, 0x10, 0x0D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0x20, 0xE5, 0x06, 0x93, 0x40, 0x78, 0x1A, 0xD1, 0x09, 0xC0, 0x25, -0x00, 0x97, 0x0F, 0x45, 0x02, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x8F, 0x81, 0x7E, -0x02, 0x34, 0x09, 0xD0, 0x26, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x49, 0xC0, -0x15, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x24, -0x00, 0x9F, 0xC0, 0x7C, 0x12, 0xF0, 0x09, 0xC8, 0x25, 0x00, 0x9B, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0, -0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x5B, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x10, 0x78, -0x08, 0xF0, 0x01, 0xC1, 0x01, 0x04, 0x1F, 0x04, 0x7C, 0x90, 0xB0, 0x01, 0xC0, -0x84, 0x00, 0x1F, 0x10, 0x4C, 0x00, 0xF1, 0x01, 0xC0, 0x07, 0x10, 0x07, 0x10, -0x3C, 0x04, 0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0xDC, 0x01, 0x7D, 0x07, 0x74, 0x01, 0x10, 0x26, 0x40, -0x1F, 0x19, 0x6D, 0x00, 0xF4, 0x09, 0x10, 0x07, 0x40, 0xDC, 0x02, 0x7D, 0x03, -0x44, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x71, 0x45, 0xF4, 0x41, 0x11, 0x27, -0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, -0xF6, 0x01, 0xCD, 0x03, 0x34, 0x22, 0x58, 0x2C, 0x48, 0x73, 0x00, 0xCC, 0x00, -0x34, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xCD, 0x0A, 0x32, 0x03, 0xD0, 0x0C, -0x40, 0x33, 0x80, 0xC5, 0x00, 0x34, 0x04, 0x90, 0xAD, 0x40, 0x40, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0x6D, 0x00, -0xB4, 0x07, 0x5A, 0x2A, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB0, 0x07, 0x52, 0x0A, -0x40, 0x98, 0x00, 0xED, 0x00, 0x84, 0x13, 0xD0, 0x4E, 0x40, 0x7B, 0x81, 0xE1, -0x00, 0xB4, 0x02, 0x90, 0x04, 0x44, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x08, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E, -0xC0, 0x5B, 0x00, 0xEE, 0x01, 0xBC, 0x06, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xBF, -0x01, 0x9C, 0x07, 0xF0, 0xBE, 0xC4, 0x7F, 0x21, 0xE7, 0x01, 0xFC, 0x04, 0xB0, -0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xB2, 0x35, 0x00, 0x5F, 0x60, 0x3C, 0x03, 0x38, 0x01, 0xC8, 0x07, 0x00, 0xDF, -0x00, 0x3C, 0x00, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x20, 0x7C, 0x2B, 0xF0, -0x6D, 0xC8, 0xB7, 0x20, 0x9D, 0x00, 0x7C, 0x82, 0x71, 0x05, 0xC0, 0x43, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x02, 0xFF, -0x81, 0xCC, 0x17, 0x71, 0x17, 0xC0, 0x6F, 0x02, 0xFF, 0x81, 0xFC, 0x85, 0xF0, -0x9F, 0x40, 0x78, 0x02, 0xB3, 0x29, 0xFE, 0x2F, 0xB0, 0x1F, 0xE0, 0xFF, 0x04, -0x73, 0x09, 0xFC, 0x27, 0xF1, 0x5F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x26, 0x6D, 0x08, 0xAC, 0x83, 0xD0, -0x22, 0x40, 0x8B, 0x00, 0x2D, 0x00, 0xB4, 0x08, 0xD0, 0x1A, 0x40, 0x98, 0x00, -0xA1, 0x01, 0xB4, 0x03, 0xD0, 0x0E, 0xC0, 0x39, 0x01, 0xEB, 0x00, 0x34, 0x07, -0xD0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x48, 0x08, 0x39, 0x18, 0xFD, 0x00, 0xA4, 0x13, 0xD0, 0x02, 0x40, 0x0B, 0x00, -0xED, 0x10, 0xB4, 0x20, 0xD0, 0x0E, 0x40, 0x2B, 0x40, 0x21, 0x00, 0xB4, 0x83, -0x91, 0x0E, 0x40, 0x39, 0x10, 0x61, 0x10, 0xB4, 0x02, 0xD0, 0x4E, 0x40, 0x23, -0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x21, 0x00, -0x1D, 0x01, 0x26, 0x07, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x03, 0x34, 0x80, -0xD0, 0x00, 0x40, 0xA3, 0x00, 0x01, 0x01, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x31, -0x80, 0x85, 0x00, 0x34, 0x81, 0xD0, 0x29, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x04, 0x00, 0x9F, 0x01, 0x64, 0x0B, -0x71, 0x09, 0xC0, 0x27, 0x90, 0x1F, 0x03, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x27, -0x20, 0xD3, 0x11, 0xFC, 0x03, 0xB0, 0x0F, 0xC0, 0x3D, 0x00, 0x81, 0x01, 0x7C, -0x01, 0xD0, 0x29, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0D, 0x00, 0x87, 0x01, 0x9F, 0x08, 0x7C, 0x23, 0xF0, 0x19, 0xC0, 0x27, -0x00, 0x1F, 0x32, 0x3E, 0x0A, 0xF0, 0x01, 0x40, 0x14, 0xA1, 0x9F, 0x00, 0x70, -0x03, 0xD0, 0x0D, 0xC8, 0x35, 0x40, 0x9B, 0x10, 0x74, 0x01, 0xE0, 0x21, 0xC0, -0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x08, 0x0B, -0x00, 0xBB, 0x00, 0x8C, 0x43, 0xB0, 0x0B, 0xC4, 0x2B, 0x00, 0xF3, 0x00, 0xFC, -0x02, 0x32, 0x01, 0xC4, 0x2F, 0x01, 0xBF, 0x40, 0xEC, 0x03, 0xF0, 0x0F, 0xC4, -0x3B, 0x00, 0x37, 0x05, 0x94, 0x81, 0x33, 0x03, 0x81, 0x04, 0x28, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x21, 0x91, 0x07, 0x44, -0x83, 0xB0, 0x31, 0x40, 0xE7, 0x00, 0xD1, 0x06, 0x74, 0x04, 0x10, 0x31, 0x48, -0x77, 0x10, 0x9C, 0x01, 0x74, 0x03, 0x71, 0x0D, 0x40, 0x37, 0x00, 0x11, 0x32, -0x44, 0x0B, 0x10, 0x31, 0x40, 0x85, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xA0, 0x64, 0x00, 0x19, 0x01, 0x54, 0x07, 0x90, 0x19, 0x00, -0x66, 0x00, 0x11, 0x01, 0x74, 0x06, 0x10, 0x13, 0x41, 0x07, 0x00, 0xB9, 0x01, -0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x55, 0x00, 0x54, 0x47, 0x50, 0x19, -0x40, 0x05, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x00, 0x00, 0x01, 0x20, 0x14, 0x03, 0x90, 0x08, 0x62, 0x03, 0x00, 0x00, 0x00, -0x34, 0x02, 0x14, 0x40, 0x40, 0x13, 0x00, 0x8D, 0x04, 0x34, 0x03, 0x50, 0x0C, -0x40, 0x33, 0x08, 0xC1, 0x00, 0x14, 0x20, 0x10, 0x08, 0x42, 0x41, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x08, 0x9B, 0x00, -0x5E, 0x03, 0xB1, 0x09, 0xC0, 0x27, 0x40, 0xD1, 0x00, 0x7C, 0x02, 0x30, 0x41, -0xC0, 0x07, 0x10, 0x1F, 0x1C, 0xEC, 0x03, 0xF1, 0x0F, 0xE4, 0x3B, 0x00, 0x57, -0x00, 0x5C, 0x12, 0x34, 0x01, 0xC0, 0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x45, 0xA8, 0x2F, 0x00, 0xAF, 0x00, 0xEC, 0x03, 0x70, 0x03, -0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0xC1, 0xC1, 0x0F, 0x04, 0x1F, -0x04, 0xFC, 0x03, 0x72, 0x0F, 0xC4, 0x3F, 0x00, 0x3F, 0x00, 0x6C, 0x30, 0xF0, -0x03, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA0, 0x2D, 0x11, 0xBF, 0x00, 0xFC, 0x13, 0xB2, 0x93, 0xC8, 0x3D, 0x11, 0x13, -0x08, 0xDC, 0x22, 0x32, 0x4F, 0xC8, 0x0F, 0x20, 0x7B, 0x41, 0xEC, 0x03, 0xF0, -0x17, 0xC0, 0x3C, 0x00, 0xBF, 0x01, 0xEC, 0x00, 0x30, 0x03, 0xC4, 0x0C, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x47, 0x02, 0x9C, -0x8C, 0xF4, 0x27, 0x04, 0x09, 0x4C, 0x7D, 0x22, 0x1D, 0x04, 0x74, 0x12, 0x50, -0xAF, 0x42, 0x07, 0x00, 0x99, 0x81, 0x44, 0x0B, 0xD0, 0x09, 0x40, 0x3C, 0x10, -0x9D, 0x40, 0x44, 0x00, 0x10, 0x11, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x21, 0x08, 0x0D, 0x50, 0x34, 0x03, 0x18, -0x51, 0x44, 0x31, 0x00, 0x0D, 0x20, 0x74, 0x02, 0x10, 0x0C, 0x64, 0x01, 0x00, -0x89, 0x00, 0x24, 0x0B, 0xD0, 0x01, 0x50, 0x30, 0x00, 0x9D, 0x00, 0x24, 0x00, -0x10, 0x00, 0x40, 0x4C, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA8, 0x47, 0x80, 0x1D, 0x51, 0x74, 0x03, 0x10, 0x11, 0x40, 0x35, 0x00, -0x3D, 0x02, 0xF4, 0x02, 0x50, 0x0D, 0x00, 0x4F, 0x08, 0x89, 0x08, 0x44, 0x03, -0xD2, 0x19, 0x00, 0x3C, 0x00, 0x9D, 0x01, 0x44, 0x04, 0x10, 0x11, 0x42, 0x0C, -0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x67, 0x00, -0x9F, 0x03, 0x7C, 0x03, 0x30, 0x18, 0xCC, 0x35, 0x18, 0x1B, 0x01, 0x5E, 0x06, -0x20, 0x0D, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x03, 0xF0, 0x1C, 0xC0, 0x34, -0x20, 0xCF, 0x01, 0x6C, 0x84, 0x30, 0x11, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xBF, 0x80, 0xBC, 0x03, -0xF0, 0x0B, 0xC0, 0x3E, 0x80, 0x1D, 0x03, 0xFC, 0x26, 0xF0, 0x0F, 0xC0, 0x2F, -0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF2, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, -0x00, 0xF4, 0x09, 0xD0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x08, 0x25, 0x18, 0x93, 0x01, 0x7C, 0xA3, 0xF0, 0x01, 0xC0, 0x77, -0x00, 0x1B, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x87, 0x00, 0x9F, 0x00, 0x7C, -0x03, 0x30, 0x09, 0x80, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC1, -0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x64, -0x04, 0x91, 0x02, 0xF4, 0x2F, 0xD0, 0x01, 0x40, 0xBF, 0x00, 0x11, 0x80, 0x45, -0x47, 0xD1, 0x0F, 0x44, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40, -0x3F, 0x00, 0x5D, 0x00, 0x34, 0x44, 0x10, 0x38, 0x58, 0x6C, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x00, 0x60, 0x08, 0x30, 0x36, -0x0F, 0xD8, 0x00, 0x40, 0x33, 0x01, 0x09, 0x00, 0x50, 0x0E, 0xD0, 0x9C, 0x22, -0x43, 0x02, 0x4C, 0x80, 0x34, 0x03, 0x10, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x06, -0x34, 0x00, 0x14, 0xA0, 0x40, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0F, 0x00, 0x58, 0x02, 0xE9, 0x81, 0xB4, 0x07, 0xD0, 0x1A, 0x40, -0x7B, 0x00, 0x21, 0x09, 0x84, 0x06, 0xD1, 0x9E, 0x40, 0x5B, 0x00, 0xAD, 0x01, -0xB4, 0x07, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x41, 0xB4, 0x07, 0x18, 0x9A, -0x40, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A, -0x30, 0x00, 0x4B, 0x08, 0x3C, 0x03, 0xF0, 0x80, 0xC0, 0x33, 0x00, 0x0B, 0x05, -0x0C, 0x02, 0xF0, 0x0C, 0xC0, 0x43, 0x01, 0xCF, 0x00, 0x7C, 0x23, 0x34, 0x00, -0x40, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x04, 0xC8, 0x48, 0x68, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x19, 0x00, 0xF0, 0x60, -0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xF0, 0x23, 0xF0, 0x0F, -0xC4, 0x1F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0xF0, 0x0B, 0xC0, 0xBF, 0x10, 0xFF, -0x00, 0xBC, 0x03, 0xF1, 0x0D, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x17, 0x10, 0x53, 0x00, 0x74, 0x5F, 0x34, 0x09, -0xC0, 0x37, 0x00, 0x1F, 0x00, 0x4C, 0x02, 0x31, 0x9D, 0x80, 0x74, 0x00, 0xD3, -0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x82, 0xCF, 0x00, 0x2C, 0x02, 0x30, -0x15, 0xD0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0x8A, 0x39, 0x00, 0xE1, 0x00, 0x34, 0x13, 0x10, 0x0A, 0x40, 0xBB, 0x03, 0x8D, -0x80, 0x84, 0x02, 0x12, 0x8C, 0x42, 0x3C, 0x08, 0xA1, 0x00, 0xB4, 0x13, 0xD0, -0x0A, 0x40, 0x3A, 0x80, 0xED, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x40, 0x4C, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x40, 0x69, -0x01, 0xB4, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x11, 0x94, 0x46, 0x90, -0x5E, 0x40, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x37, 0x90, 0x1E, 0x40, 0x7B, 0x00, -0x7D, 0x61, 0xA4, 0x07, 0x14, 0x14, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x00, 0xC9, 0x01, 0x34, 0x03, 0x50, -0x8C, 0x40, 0x33, 0x00, 0xCD, 0xC3, 0x54, 0x07, 0x90, 0x0C, 0x50, 0x70, 0x01, -0x81, 0x00, 0x34, 0x03, 0xD0, 0x48, 0x40, 0x36, 0x00, 0x4D, 0x09, 0x04, 0x03, -0x10, 0x1C, 0x41, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x17, 0xA0, 0x1F, 0x20, 0x7B, 0x85, 0x7C, 0x01, 0x78, 0x17, 0xC6, 0x17, 0x08, -0x7F, 0x03, 0x5C, 0x05, 0xB6, 0x05, 0xC0, 0x5C, 0x01, 0x73, 0x02, 0x7C, 0x01, -0xB0, 0x37, 0xC1, 0x17, 0x00, 0x7F, 0x09, 0xAC, 0x01, 0x30, 0x77, 0xC0, 0x5C, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x05, 0x24, -0x17, 0x46, 0x7C, 0x00, 0xA0, 0x01, 0xE0, 0x83, 0x20, 0x1E, 0xA0, 0x6C, 0x00, -0x70, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x06, -0x00, 0x1F, 0x02, 0x7C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0xA1, 0x00, 0x93, 0x08, 0x7C, 0x86, -0xF0, 0x09, 0xC1, 0x25, 0x08, 0x93, 0x10, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x67, -0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x48, -0x16, 0x30, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x20, 0x26, 0x00, 0x95, 0x03, 0x74, 0x66, 0xD0, 0x09, 0x40, 0x27, -0x20, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x39, 0x44, 0xA7, 0x02, 0x8D, 0x20, 0x44, -0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x85, 0x40, 0x44, 0x42, 0x10, 0x49, 0x40, -0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34, -0x00, 0x91, 0x82, 0x74, 0x82, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x81, 0x00, 0x54, -0x0A, 0x10, 0x49, 0x49, 0xB7, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40, -0x27, 0x00, 0x91, 0x00, 0x55, 0x03, 0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0xA5, 0x85, 0x14, 0x34, -0x82, 0xD0, 0x88, 0x40, 0x33, 0x60, 0x81, 0x4C, 0x04, 0x32, 0x18, 0x08, 0x40, -0x23, 0x01, 0x9D, 0x02, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x00, -0x14, 0xD2, 0x10, 0x48, 0x41, 0x43, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xB0, 0x07, 0x01, 0x13, 0x24, 0x7C, 0x50, 0xF0, 0x21, 0xC4, -0x05, 0x05, 0x13, 0x03, 0x09, 0x0C, 0x30, 0xE1, 0xC1, 0xC7, 0x02, 0x1F, 0x00, -0x4D, 0x78, 0xF0, 0xA1, 0xC8, 0xC7, 0x0A, 0x53, 0x00, 0x5C, 0x10, 0x32, 0x41, -0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, -0x2B, 0x00, 0xBF, 0x14, 0x7C, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xBF, 0x0C, -0xFC, 0x32, 0xF4, 0x19, 0xC2, 0x6F, 0x02, 0xBD, 0x01, 0x7C, 0x06, 0xF0, 0x1B, -0xC0, 0x67, 0x02, 0xFF, 0x14, 0xE4, 0x52, 0xF4, 0x0B, 0xC0, 0x77, 0x40, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x7F, 0x04, 0xBF, 0x02, -0xFC, 0x02, 0xF0, 0x29, 0xC0, 0x2D, 0x20, 0x9F, 0x00, 0xFC, 0x0A, 0x30, 0x4B, -0xC0, 0x2C, 0x00, 0x93, 0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0xB3, -0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x08, 0x17, 0x00, 0x1D, 0x02, 0x74, 0x28, 0xD0, 0x00, -0x48, 0x87, 0x02, 0x1D, 0x04, 0x5C, 0x10, 0x14, 0xA1, 0x50, 0x04, 0x00, 0x15, -0x01, 0x74, 0x28, 0x10, 0x01, 0x40, 0x05, 0x00, 0x1B, 0x00, 0x74, 0x10, 0x10, -0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x00, 0x21, 0x20, 0x8D, 0x86, 0x34, 0x02, 0xC0, 0x08, 0x40, 0x23, 0x00, 0x8D, -0x10, 0x30, 0x12, 0x18, 0x08, 0x40, 0x24, 0x00, 0x81, 0x01, 0x34, 0x02, 0x14, -0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x44, 0x48, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xDD, -0x0A, 0x74, 0x02, 0xC0, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x14, 0x22, 0x10, -0x09, 0x40, 0x24, 0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x49, 0x44, 0x25, 0x00, -0x99, 0x00, 0x34, 0x06, 0x14, 0x49, 0x40, 0x62, 0x20, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xE0, -0x29, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x08, 0xC6, 0x64, 0x02, -0xB3, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x06, -0x30, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x16, 0x00, 0xA5, 0x20, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x04, -0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, -0xF2, 0x19, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x08, 0xC0, 0x5B, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, -0x1F, 0x04, 0x6C, 0x00, 0x70, 0x21, 0xC0, 0x04, 0x02, 0x1F, 0x02, 0x7C, 0x00, -0x31, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, -0x08, 0x13, 0x0A, 0x7C, 0x04, 0x30, 0xC1, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC, 0x0E, 0x7D, 0x06, 0xF4, 0x41, -0x10, 0x05, 0x80, 0x5E, 0x00, 0x5D, 0x60, 0xF4, 0x6D, 0x10, 0x37, 0x40, 0x1C, -0x00, 0x51, 0x00, 0x6C, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x75, 0x40, 0xF4, -0x01, 0x10, 0x17, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA0, 0xE2, 0x00, 0xCD, 0x41, 0x24, 0x17, 0x80, 0x0C, 0x58, 0xF0, -0x20, 0xCD, 0x00, 0x34, 0x0F, 0x90, 0x2C, 0x41, 0x74, 0x04, 0xC1, 0x00, 0x04, -0x03, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0x81, 0x10, 0x34, 0x03, 0x10, 0x2C, 0x40, -0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88, 0x29, -0x80, 0xED, 0x80, 0xB4, 0x07, 0x94, 0xDE, 0x40, 0x28, 0x20, 0xEC, 0x08, 0x34, -0x03, 0x90, 0x2C, 0x50, 0x20, 0x04, 0xF1, 0x45, 0xA4, 0x23, 0xD0, 0x0E, 0x40, -0x3B, 0x00, 0x25, 0x00, 0x34, 0x03, 0x12, 0x0A, 0x40, 0x13, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x79, 0x00, 0xEF, 0x01, 0xAC, -0x05, 0xB1, 0x5E, 0x41, 0x78, 0x00, 0xEF, 0x05, 0xBC, 0x05, 0xB0, 0x1A, 0xC0, -0x78, 0x00, 0xF3, 0x43, 0x8C, 0x57, 0xF0, 0x1E, 0xC3, 0x73, 0x00, 0xA3, 0x01, -0xBC, 0x07, 0x34, 0x12, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA8, 0x35, 0x00, 0x5F, 0x40, 0x3C, 0x00, 0x31, 0x4D, 0xC8, -0x27, 0x08, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x09, 0xC8, 0x37, 0x40, 0xDF, 0x00, -0x7C, 0x13, 0xF0, 0xCD, 0xC0, 0xB7, 0x02, 0x1F, 0x00, 0x7C, 0x03, 0xB4, 0x09, -0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, -0x6D, 0x00, 0xFF, 0x01, 0xCC, 0x06, 0xF0, 0x9F, 0xC0, 0x5F, 0x02, 0xFF, 0x09, -0xCC, 0x27, 0xF0, 0x1B, 0xC0, 0x7D, 0x00, 0xEF, 0x41, 0xCC, 0x87, 0x70, 0x1F, -0xC0, 0xFC, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC8, 0x1B, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x20, 0xFD, 0x00, -0xAC, 0x1A, 0xD2, 0xCE, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84, 0x04, 0xD0, 0x0F, -0xC0, 0x20, 0x01, 0xED, 0x25, 0xC4, 0x07, 0x50, 0x0E, 0xC1, 0x3A, 0x20, 0x6B, -0x00, 0x94, 0x03, 0xB0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0E, -0x60, 0x0B, 0x20, 0xED, 0x00, 0x96, 0x03, 0xD0, 0x02, 0x40, 0x1B, 0x80, 0xFD, -0x05, 0xC4, 0x03, 0x11, 0x8E, 0x40, 0x38, 0x00, 0xF1, 0x00, 0x84, 0x43, 0x10, -0x2E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x28, 0xF1, 0x04, 0x8D, 0x13, 0x34, 0x02, 0xD0, 0x2D, 0x40, 0x23, 0x00, 0xC9, -0x03, 0x54, 0x04, 0xD0, 0x00, 0x40, 0xC0, 0x10, 0xCD, 0x04, 0x04, 0x03, 0x58, -0x3C, 0x41, 0x32, 0x00, 0x59, 0x00, 0x14, 0x07, 0x91, 0x0C, 0x40, 0x0B, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x10, 0x1F, -0x12, 0x7C, 0x02, 0xF0, 0x2F, 0xC0, 0x27, 0x00, 0xFF, 0x05, 0x5C, 0x46, 0xF0, -0x05, 0xC0, 0x07, 0x01, 0xDF, 0x07, 0xCD, 0x03, 0x32, 0x0F, 0x40, 0x3C, 0x00, -0x53, 0x00, 0x4C, 0x07, 0x30, 0x25, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x27, 0x02, 0x9F, 0x00, 0x64, 0x08, 0xF0, -0xCD, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0x87, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03, -0xF0, 0x01, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x89, 0x09, 0x3F, 0x10, 0x2F, 0x00, 0xCC, 0x80, 0xF0, 0x0F, 0xC0, 0x08, 0x00, -0xF3, 0x10, 0xFC, 0x20, 0x30, 0x03, 0xC0, 0x0F, 0x04, 0xFF, 0x00, 0xBC, 0x03, -0x10, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x01, 0x4C, 0x65, 0xF0, 0x97, 0xC0, 0x07, -0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xB6, 0x00, -0x1D, 0x21, 0x54, 0x04, 0xD0, 0x0D, 0x40, 0xC4, 0x00, 0xD1, 0x40, 0x74, 0x00, -0x10, 0x21, 0x40, 0xC6, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xB0, 0x0D, 0xC0, 0x35, -0x00, 0xDD, 0x0B, 0x54, 0x00, 0xD0, 0x2D, 0x44, 0x87, 0x02, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x24, 0x14, 0x1D, 0x01, 0x46, 0x06, -0xD0, 0x0D, 0x40, 0x44, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x13, 0x41, 0x4F, -0x80, 0xDD, 0x00, 0xF4, 0x03, 0x50, 0x0F, 0x40, 0x3F, 0x00, 0x9D, 0x10, 0x44, -0x03, 0x90, 0x25, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x22, 0x20, 0x00, 0x8D, 0x80, 0x14, 0x00, 0xD8, 0x0C, 0x40, 0x20, -0x00, 0xC1, 0x22, 0x34, 0x40, 0x14, 0x00, 0x40, 0x03, 0x00, 0xCD, 0x04, 0x34, -0x13, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x14, 0x07, 0xD0, 0x00, 0x40, -0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0x06, -0x00, 0x1F, 0x00, 0x4C, 0x02, 0xF0, 0x0F, 0xC0, 0x04, 0x00, 0xF1, 0x02, 0x74, -0x13, 0x30, 0x01, 0xC0, 0x87, 0x02, 0xFF, 0x10, 0xFC, 0x53, 0x70, 0x0E, 0xC0, -0x3B, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB0, 0x1F, 0x00, 0xBF, 0x80, 0xF8, -0x00, 0xF0, 0x0F, 0xC2, 0x0F, 0x00, 0xFF, 0x20, 0x7C, 0x00, 0xF0, 0x03, 0xC0, -0x0E, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB1, 0x0F, 0xC0, 0x3D, 0x00, 0xBF, 0x00, -0xFC, 0x83, 0xF0, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x02, 0x30, 0x4B, 0xC1, -0x3F, 0x13, 0xFF, 0x00, 0xCC, 0x13, 0x70, 0x83, 0xC0, 0x3C, 0x40, 0xF3, 0x00, -0xBC, 0x06, 0xB0, 0x0F, 0xC0, 0x2C, 0x17, 0x3B, 0x0C, 0xCC, 0x00, 0xB0, 0x03, -0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, -0x37, 0x01, 0xCD, 0x04, 0x74, 0xEA, 0x10, 0x69, 0xC8, 0xBD, 0x22, 0xFD, 0xDE, -0xD4, 0x2F, 0x10, 0x01, 0x40, 0xFC, 0x00, 0xD1, 0x02, 0x44, 0x87, 0x10, 0x1F, -0x40, 0xA5, 0x01, 0x11, 0x0E, 0x44, 0x08, 0x10, 0x01, 0x40, 0x0F, 0x60, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x04, 0xCD, 0x00, -0x34, 0x10, 0x50, 0x00, 0x41, 0x33, 0x09, 0xCD, 0x44, 0x14, 0x03, 0x10, 0x50, -0x60, 0xB1, 0x00, 0xC5, 0x02, 0x14, 0x82, 0x90, 0x0D, 0x60, 0x34, 0x01, 0xC9, -0x00, 0x04, 0x08, 0x12, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04, 0x36, 0x0E, 0x54, 0x19, -0x42, 0x37, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x12, 0x40, 0x35, 0x00, 0xD5, -0x20, 0x55, 0x03, 0x10, 0x0F, 0x40, 0x55, 0x00, 0xC1, 0x18, 0x45, 0x63, 0x10, -0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xA8, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x06, 0x70, 0x31, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x4C, 0x03, 0x30, 0x11, 0x40, 0x35, 0x00, 0xD6, 0x00, 0x7C, 0x02, 0xB0, -0x0D, 0xC0, 0x64, 0x80, 0x1B, 0x03, 0x4E, 0x07, 0x30, 0x19, 0xC0, 0x2B, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0xFD, 0x20, 0xFF, -0x81, 0x7E, 0x02, 0xB0, 0x01, 0xC4, 0x3D, 0x00, 0xDF, 0x00, 0xBC, 0x43, 0xB0, -0x0B, 0xC0, 0x3E, 0x10, 0xFA, 0x00, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, -0xFF, 0x80, 0x7C, 0x01, 0x70, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x4C, 0x08, 0x38, -0x21, 0xC0, 0x34, 0x08, 0xD7, 0xC0, 0x4C, 0x03, 0x70, 0x01, 0xD1, 0x30, 0x00, -0xDF, 0x84, 0x4D, 0x42, 0x32, 0x4D, 0xC0, 0x27, 0x00, 0x1B, 0x12, 0x3C, 0x02, -0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1B, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x6C, 0x82, 0x10, 0x19, 0x41, 0x3C, 0x00, -0xF1, 0x00, 0xC4, 0x4B, 0xD0, 0x19, 0x40, 0x3C, 0x01, 0xE7, 0x01, 0x04, 0x46, -0x12, 0x3F, 0xC0, 0x11, 0x00, 0xDD, 0x00, 0x74, 0x1B, 0x10, 0xB9, 0x41, 0x4F, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x32, 0x00, -0xCD, 0x00, 0x24, 0x00, 0x10, 0x58, 0x40, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x0B, -0x50, 0x20, 0x40, 0x32, 0x00, 0xC8, 0x2B, 0x04, 0x0A, 0x12, 0x0D, 0x44, 0x23, -0x10, 0x09, 0x08, 0x34, 0x40, 0x90, 0x18, 0x40, 0x0E, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xED, 0x01, 0xA4, 0x05, -0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x41, 0x78, -0x80, 0xE5, 0x01, 0xC4, 0x07, 0x10, 0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0xB4, -0x15, 0x90, 0x12, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x10, 0x32, 0x00, 0xCE, 0x40, 0x2C, 0x21, 0x10, 0x84, 0xC0, 0x34, -0x02, 0xC7, 0x08, 0x06, 0x03, 0x70, 0x05, 0xC0, 0x32, 0x00, 0xCF, 0x40, 0x0C, -0x02, 0x30, 0x0C, 0xC1, 0x23, 0x00, 0x0B, 0x04, 0x3C, 0x02, 0xB0, 0x0C, 0xC0, -0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x3D, -0x20, 0xFF, 0x80, 0xDD, 0x81, 0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFE, -0x03, 0xF0, 0x0F, 0xC0, 0xBD, 0x04, 0xEF, 0x00, 0xFC, 0x03, 0xF5, 0x0F, 0xC0, -0x1F, 0x00, 0xDF, 0x00, 0x7C, 0x13, 0x72, 0x0F, 0xC0, 0x0B, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x20, 0xDF, 0x00, 0x7C, -0x03, 0x70, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x04, 0x7C, 0x13, 0xD1, 0x11, 0xD0, -0x30, 0x01, 0xD3, 0x08, 0x4C, 0x06, 0x30, 0x5D, 0xC8, 0x20, 0x00, 0x17, 0x00, -0x5C, 0x00, 0xB4, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0x88, 0x38, 0x10, 0xED, 0x20, 0xB6, 0x03, 0xD0, 0x0E, 0x40, -0xBB, 0x03, 0xED, 0x28, 0xB4, 0x23, 0xD0, 0x0B, 0x40, 0x38, 0x00, 0xE1, 0x00, -0xAC, 0x02, 0x50, 0xAE, 0x40, 0x38, 0x00, 0xE1, 0x40, 0xB4, 0x01, 0x10, 0x06, -0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, -0x79, 0x80, 0xED, 0x81, 0x94, 0x07, 0xD8, 0x16, 0x40, 0x7B, 0x00, 0xED, 0x09, -0xB4, 0x27, 0xD0, 0x16, 0x49, 0x78, 0x01, 0xE1, 0x05, 0x94, 0x06, 0x90, 0x5E, -0x58, 0x6C, 0x40, 0x21, 0x03, 0x34, 0x06, 0x50, 0x1C, 0x40, 0x10, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x80, 0x8D, 0x00, -0x34, 0x07, 0xD8, 0xAC, 0x40, 0x33, 0x10, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C, -0x40, 0x30, 0x80, 0xC1, 0x00, 0x34, 0x86, 0xD0, 0x0C, 0x40, 0x10, 0x00, 0xC1, -0x10, 0x74, 0x2F, 0x50, 0x2D, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x01, 0x5F, 0x00, 0xFC, 0x0D, 0x72, 0x17, -0xCA, 0x17, 0x08, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0x48, 0x14, 0x00, 0x43, -0x00, 0x54, 0x01, 0xB0, 0x05, 0xC4, 0x1C, 0x01, 0x73, 0x03, 0xDC, 0x2D, 0x70, -0x47, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x00, 0x05, 0x20, 0x1F, 0x00, 0x7C, 0x60, 0xF8, 0x01, 0xC1, 0x07, 0x00, 0x0F, -0x00, 0x7C, 0x08, 0xF0, 0x41, 0xC8, 0x03, 0x40, 0x1F, 0x00, 0x64, 0x20, 0x73, -0x01, 0xC0, 0x07, 0x20, 0x19, 0x02, 0x7C, 0x00, 0xB0, 0x21, 0xD0, 0x4B, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, -0x00, 0x78, 0x02, 0xF0, 0x89, 0xC2, 0x27, 0x00, 0x9B, 0x00, 0x4C, 0x06, 0xF0, -0x09, 0xC0, 0x25, 0x01, 0x93, 0x09, 0x5C, 0x02, 0xF0, 0x99, 0xC0, 0x23, 0x00, -0x97, 0x28, 0x44, 0x82, 0x31, 0x09, 0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, -0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x0E, 0xD0, 0x29, 0x40, 0x27, 0x00, -0x91, 0x03, 0x44, 0x02, 0xD0, 0x39, 0x40, 0x27, 0x00, 0x91, 0x07, 0x44, 0x0A, -0x10, 0x29, 0x51, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00, -0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x29, 0x00, 0x27, 0x40, 0x91, 0x02, 0x54, 0x02, -0xD8, 0x09, 0x41, 0x27, 0x00, 0x85, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x70, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x20, 0x00, -0x8D, 0x00, 0x34, 0x52, 0xD0, 0x4C, 0x41, 0x23, 0x02, 0x8D, 0x08, 0x04, 0x82, -0xD0, 0xC8, 0x40, 0x23, 0x00, 0x81, 0x14, 0x04, 0x03, 0xD9, 0x48, 0x40, 0x23, -0x00, 0x81, 0x08, 0x14, 0x82, 0x14, 0x48, 0x41, 0x50, 0xA0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x40, 0x7C, 0x10, -0xF0, 0x41, 0xC0, 0x87, 0x05, 0x1B, 0x16, 0x4C, 0x50, 0xF0, 0x31, 0xC0, 0x05, -0x05, 0x03, 0x0E, 0x5C, 0x00, 0xF0, 0x11, 0xC0, 0x87, 0x05, 0x17, 0x16, 0x5D, -0x51, 0x30, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x19, 0xB8, 0x2F, 0x0D, 0xBF, 0x34, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x27, -0x01, 0x9F, 0x04, 0x7D, 0x82, 0xF0, 0xCB, 0x80, 0x27, 0x00, 0x9F, 0x01, 0xBC, -0x02, 0xF0, 0x88, 0xC0, 0x2F, 0x04, 0xBF, 0x04, 0xEC, 0x52, 0xF8, 0x4B, 0xC1, -0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0xA7, -0x00, 0xDF, 0x02, 0x54, 0x1E, 0xF0, 0x2B, 0xC0, 0x25, 0x01, 0x9F, 0x54, 0xFC, -0x12, 0x30, 0x8B, 0xC0, 0x2E, 0x05, 0xB3, 0x01, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, -0xA4, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0x32, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x03, 0x20, 0x1D, 0x01, 0x6E, -0x08, 0x10, 0x85, 0x40, 0x00, 0x05, 0x0D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x50, -0x84, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x54, 0x01, 0x1D, 0x40, -0x44, 0x00, 0xBA, 0x05, 0xC0, 0x72, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0xA0, 0x21, 0x81, 0x9D, 0x00, 0x04, 0xB2, 0x58, 0x48, 0x40, -0x21, 0x02, 0x8D, 0x14, 0x34, 0x0A, 0x12, 0x48, 0x44, 0x20, 0x00, 0x81, 0x22, -0x04, 0x02, 0xD0, 0x08, 0x50, 0x21, 0x01, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08, -0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, -0x25, 0x80, 0x9D, 0x00, 0x64, 0x62, 0x58, 0x0D, 0x40, 0x24, 0x00, 0x9C, 0x00, -0x70, 0x02, 0x00, 0x0C, 0x60, 0x24, 0x40, 0x91, 0x00, 0x45, 0x02, 0xD0, 0x0D, -0x40, 0x25, 0x22, 0x9D, 0x80, 0x54, 0x2A, 0x90, 0x09, 0x40, 0x62, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0x8D, 0x40, -0x44, 0x06, 0x68, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x19, -0xC4, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x25, 0x00, 0x9D, -0x0F, 0x5C, 0x06, 0x30, 0x29, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x80, 0x24, 0x01, 0x9F, 0x04, 0x3C, 0x02, 0xB0, 0x59, -0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7E, 0x02, 0xF4, 0x49, 0xC0, 0x21, 0x00, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x66, 0x00, 0x9F, 0x11, 0x6D, 0x42, 0xF2, -0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x05, 0x48, 0x1B, 0x00, 0x7C, 0x00, 0xB8, 0x21, 0xC1, 0x07, 0x00, 0x17, -0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x5C, 0x20, 0xF0, -0x11, 0xC0, 0x05, 0x00, 0x07, 0x22, 0x4C, 0x08, 0xE0, 0x21, 0xD0, 0x40, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x51, -0x00, 0x74, 0x01, 0xB8, 0x07, 0x40, 0x17, 0x00, 0x51, 0x00, 0xC4, 0x09, 0xD0, -0x17, 0xC0, 0x14, 0x00, 0x73, 0x81, 0xC4, 0x29, 0xD0, 0x07, 0x40, 0x14, 0x00, -0x71, 0x02, 0xC0, 0x45, 0xD1, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x03, 0x93, -0x8D, 0x46, 0x33, 0x00, 0xC5, 0x00, 0x14, 0x17, 0xD0, 0x0C, 0x40, 0x22, 0x30, -0x59, 0x8F, 0x14, 0x02, 0xC8, 0x1C, 0x40, 0x31, 0x80, 0xC5, 0x03, 0x45, 0x0B, -0xD0, 0x8D, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x88, 0x78, 0x09, 0xE1, 0x00, 0xB4, 0x13, 0x10, 0x0E, 0x40, 0x7B, 0x03, -0xE4, 0x0D, 0x91, 0x43, 0xD0, 0x28, 0x40, 0x30, 0x00, 0x01, 0x00, 0xA4, 0x01, -0xD1, 0x0E, 0x41, 0x78, 0x00, 0xE1, 0x02, 0x84, 0x03, 0xD0, 0x04, 0x40, 0x04, -0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x04, -0xE3, 0x0D, 0xB4, 0x0F, 0x90, 0x1E, 0xC0, 0x7B, 0x04, 0xE7, 0x15, 0x9C, 0x07, -0xF0, 0x16, 0xE0, 0x6A, 0x00, 0x2B, 0x01, 0x9C, 0x04, 0xF0, 0x1E, 0xC0, 0x7D, -0x00, 0x77, 0x01, 0x8D, 0x07, 0xF0, 0x1E, 0xC4, 0x44, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x23, 0xD7, 0x80, 0x7C, 0x43, -0xF0, 0x0D, 0xC0, 0xB7, 0x01, 0xDB, 0x04, 0x6C, 0x03, 0xF0, 0x01, 0xC2, 0x27, -0x40, 0x1F, 0x22, 0x5C, 0x01, 0xF0, 0x08, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x7C, -0x01, 0xF2, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x20, 0x7D, 0x00, 0xF3, 0x19, 0xF8, 0x27, 0x78, 0x9F, 0xC0, 0x7D, -0x00, 0xF3, 0x01, 0xBC, 0x06, 0x30, 0x1F, 0xC0, 0x6F, 0x00, 0x63, 0x83, 0xCC, -0x04, 0xF0, 0x17, 0xC4, 0x78, 0x00, 0xB3, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0, -0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, -0x1A, 0xEB, 0x38, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x38, 0x02, 0xE1, 0x00, 0xB4, -0x80, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0x65, 0x00, 0x84, 0x08, 0xD0, 0x56, 0x40, -0x39, 0x00, 0xA1, 0x02, 0x84, 0x28, 0x10, 0x62, 0xC0, 0x56, 0x60, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x04, 0xE1, 0x88, 0xB4, -0x03, 0xD8, 0x06, 0x45, 0x31, 0x40, 0xE9, 0x00, 0xB4, 0x23, 0x90, 0x06, 0x40, -0x23, 0x80, 0xA9, 0x00, 0x84, 0x00, 0xD0, 0x4C, 0x40, 0x3E, 0x00, 0x05, 0x08, -0x05, 0x81, 0x10, 0x06, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x20, 0x75, 0x00, 0xD8, 0x00, 0x74, 0x07, 0xDA, 0x19, 0x41, -0x30, 0x00, 0xC9, 0x00, 0x34, 0x01, 0x93, 0x25, 0x40, 0x27, 0x00, 0x1D, 0x00, -0x04, 0x20, 0xD0, 0x08, 0x40, 0x71, 0x40, 0x45, 0x01, 0x44, 0x80, 0x18, 0x21, -0x40, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, -0x7D, 0x00, 0xF3, 0x01, 0xFC, 0x13, 0xF0, 0x01, 0xC4, 0x3D, 0x00, 0xFB, 0x80, -0x7E, 0x01, 0xB0, 0x5D, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x4D, 0x84, 0xF0, 0x09, -0xC0, 0x7C, 0x04, 0xD5, 0x13, 0x4C, 0x3E, 0x36, 0x29, 0xC0, 0x55, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x40, -0x7C, 0x43, 0x70, 0x01, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x3E, 0x08, 0x72, 0x01, -0xC0, 0x37, 0x00, 0x17, 0x02, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x37, 0x0C, 0xDA, -0x04, 0x7C, 0x0A, 0xF0, 0x29, 0x80, 0x06, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xCE, 0x83, 0x30, 0x01, -0xC0, 0x38, 0x00, 0xF3, 0x00, 0xFE, 0x83, 0x32, 0x1F, 0xC1, 0x2C, 0x10, 0x33, -0x00, 0xCC, 0x14, 0xF0, 0x0B, 0x80, 0x3B, 0x00, 0x63, 0x08, 0xCC, 0x02, 0xF0, -0x09, 0xD1, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, -0x20, 0x36, 0x00, 0xD1, 0x20, 0x44, 0x03, 0x18, 0x11, 0x40, 0x35, 0x00, 0xD1, -0x00, 0x74, 0x12, 0x50, 0x21, 0xC0, 0x26, 0x00, 0x1B, 0x23, 0x6C, 0x09, 0xD0, -0x21, 0x00, 0x37, 0x00, 0x91, 0x02, 0x44, 0x04, 0x10, 0x19, 0x40, 0x14, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0xD1, -0x00, 0x44, 0x03, 0x10, 0x19, 0x40, 0x34, 0x40, 0xD1, 0x00, 0x54, 0x10, 0x50, -0x49, 0x40, 0x24, 0x00, 0x31, 0x11, 0x44, 0x00, 0xD0, 0x15, 0x40, 0x37, 0x00, -0x91, 0x00, 0x44, 0x86, 0x50, 0x19, 0x40, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x83, 0x10, -0x08, 0x48, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x36, 0x80, -0x19, 0x00, 0x20, 0x01, 0xD0, 0x44, 0x44, 0x33, 0x00, 0x01, 0x60, 0x04, 0x82, -0x12, 0x08, 0x40, 0x40, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x30, 0x3C, 0x08, 0xF3, 0x00, 0xC4, 0x03, 0x10, 0x01, 0x40, 0x3C, 0x00, -0xF3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x24, 0x00, 0x33, 0x00, 0x4C, 0x00, -0xF1, 0x4D, 0xC1, 0x37, 0x40, 0x13, 0x00, 0x4D, 0x02, 0x70, 0x01, 0xC0, 0x00, -0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xA8, 0x3B, 0x00, -0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x40, 0xF4, 0x00, -0xF1, 0x03, 0xC8, 0x2F, 0x00, 0x3E, 0x20, 0xFC, 0x81, 0xF0, 0x01, 0xC0, 0x3F, -0x20, 0x3F, 0x00, 0xFD, 0x00, 0xE0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3B, 0x04, 0xFF, 0xC0, 0xFC, 0x43, -0xB2, 0x4F, 0xC0, 0x3D, 0x00, 0xEF, 0x04, 0xEC, 0x23, 0xF1, 0x12, 0xC0, 0x35, -0x03, 0x7B, 0x01, 0xFC, 0x42, 0xB0, 0x13, 0xC0, 0x2E, 0x00, 0xBB, 0x01, 0xEC, -0x86, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x08, 0xFF, 0x00, 0xFD, 0x0C, 0xF4, 0x8F, 0xD0, 0x9F, 0x48, 0xFC, -0x22, 0xDD, 0x03, 0xC4, 0x3B, 0xD2, 0x19, 0x40, 0xB4, 0x01, 0x91, 0xE1, 0x74, -0x0E, 0x10, 0x05, 0x43, 0x74, 0x00, 0x91, 0x01, 0x44, 0x03, 0x13, 0x11, 0x48, -0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, -0x18, 0xCD, 0x50, 0x34, 0x03, 0xC0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x42, 0x24, -0x13, 0xD2, 0x01, 0x60, 0xB1, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x41, 0x40, -0x22, 0x00, 0x4D, 0x00, 0x74, 0x04, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x08, 0xDD, 0x00, 0x74, -0x83, 0xD0, 0x0D, 0x40, 0x36, 0x08, 0xDD, 0x00, 0x44, 0x83, 0xD0, 0x11, 0x48, -0x34, 0x08, 0x99, 0x00, 0x74, 0x07, 0x51, 0x81, 0x41, 0x34, 0x00, 0xD5, 0x08, -0x56, 0x91, 0x10, 0x19, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xA0, 0x0D, 0xC0, -0x36, 0x20, 0xDF, 0x20, 0x6C, 0x03, 0xF2, 0x38, 0xC8, 0x35, 0x30, 0xDB, 0x08, -0x7C, 0x02, 0xF0, 0x35, 0x86, 0x62, 0x00, 0xCF, 0x03, 0x3C, 0x07, 0x30, 0x11, -0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, -0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x00, -0xFC, 0x03, 0xE0, 0x0B, 0x80, 0x36, 0x00, 0xB5, 0x00, 0xBC, 0x43, 0xB0, 0x17, -0xC0, 0x7F, 0x0A, 0xFB, 0x00, 0xEC, 0x01, 0xF2, 0x0B, 0xC0, 0x1F, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x04, -0x7C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x21, -0xC0, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x22, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x5F, -0x00, 0x7C, 0x11, 0x30, 0x81, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x82, 0xF4, 0x8F, 0x18, 0x5E, -0x44, 0xFF, 0x24, 0xED, 0x02, 0xC4, 0x03, 0xD2, 0x81, 0x41, 0x7C, 0x00, 0x9B, -0x00, 0x74, 0x0F, 0xC0, 0x00, 0x40, 0x37, 0x00, 0xDC, 0x09, 0x40, 0x09, 0x10, -0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0xA0, 0xF2, 0x00, 0xC5, 0x01, 0x34, 0x17, 0x51, 0x0C, 0x40, 0xB2, 0x04, 0xCD, -0x10, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x37, 0x02, 0x05, 0x00, 0x34, 0x0B, 0xC0, -0x00, 0x4A, 0x33, 0x10, 0x4C, 0x01, 0x14, 0x03, 0x10, 0x00, 0x41, 0x1F, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x06, 0xE1, -0xB1, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x89, 0x94, 0x07, 0xD0, -0x1E, 0x42, 0x7A, 0x01, 0xA9, 0x81, 0xB4, 0x87, 0xD0, 0x16, 0x40, 0x6B, 0x00, -0x6D, 0x31, 0xC0, 0x07, 0x10, 0x12, 0x40, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x3C, 0x43, 0x50, -0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x20, 0x1C, 0x03, 0xF0, 0x40, 0xC0, 0x73, 0x81, -0xC7, 0x00, 0x3C, 0x32, 0xF0, 0x40, 0xC0, 0x33, 0x00, 0x4F, 0x22, 0x1C, 0x12, -0x30, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x40, 0xBC, 0x2B, 0xB1, 0x0F, 0xC0, 0x3F, 0x00, -0xFF, 0x90, 0xE4, 0x03, 0xF0, 0x0B, 0xC0, 0x3D, 0x00, 0xB7, 0x00, 0xFC, 0x63, -0xF0, 0x07, 0xC0, 0x2F, 0x02, 0x6F, 0x00, 0x1C, 0x03, 0xF0, 0x8D, 0xC2, 0x0B, -0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x73, 0x01, -0xDB, 0x0A, 0x7C, 0x97, 0x39, 0x6D, 0xC1, 0xB7, 0x01, 0xDF, 0x00, 0x5C, 0x4B, -0x71, 0x18, 0xC0, 0x36, 0x20, 0x9F, 0x20, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x32, -0x00, 0x5B, 0x00, 0x7C, 0x03, 0x36, 0x05, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9, 0x05, 0xE1, 0x54, 0xB4, 0x13, -0x18, 0x2E, 0x60, 0xBB, 0x03, 0xED, 0x04, 0x04, 0x03, 0x10, 0x0E, 0x60, 0x38, -0x01, 0xA7, 0x00, 0xB4, 0x13, 0xD0, 0x07, 0x42, 0x28, 0x10, 0x61, 0x20, 0xB4, -0x01, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x00, 0x79, 0x00, 0xE9, 0x05, 0x34, 0x27, 0x12, 0x5E, 0x40, 0x7B, -0x00, 0xCD, 0x05, 0x94, 0x27, 0x52, 0x1A, 0x64, 0x7A, 0x02, 0xED, 0x01, 0xB4, -0x0E, 0xD0, 0x1E, 0x40, 0x7A, 0x20, 0x6D, 0x21, 0xF4, 0x07, 0x10, 0x16, 0x40, -0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33, -0x08, 0xC1, 0x00, 0x34, 0x83, 0x10, 0x0C, 0x40, 0x33, 0x10, 0xCD, 0x20, 0x04, -0x03, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x00, 0x34, 0x03, 0xD0, 0x25, 0x41, -0x20, 0x00, 0x45, 0x08, 0x34, 0x8F, 0x10, 0xEC, 0x40, 0x4B, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x5B, 0x20, 0x7C, -0x01, 0x35, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC2, -0x16, 0x00, 0x7F, 0x22, 0x7C, 0x01, 0xF8, 0x27, 0xD3, 0x16, 0x20, 0x6F, 0x20, -0xF4, 0x0D, 0x30, 0x17, 0xC2, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC4, -0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x05, 0x00, 0x17, 0x04, -0x7C, 0x08, 0xF2, 0x01, 0xC0, 0x87, 0x00, 0x1A, 0x02, 0x74, 0x60, 0xF0, 0x01, -0xC0, 0x4B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x27, 0x02, 0x9F, 0x09, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x67, 0x80, 0x83, 0x08, -0x5C, 0x02, 0x30, 0x99, 0xC3, 0x23, 0x00, 0x92, 0x00, 0x0C, 0x86, 0x70, 0x09, -0xC0, 0x21, 0x01, 0x93, 0x04, 0x5C, 0x06, 0x32, 0x08, 0xC2, 0x40, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x9D, 0x03, -0x74, 0x02, 0xD0, 0xA9, 0x41, 0xE3, 0x04, 0x9B, 0x01, 0x44, 0x02, 0x10, 0x09, -0x40, 0x27, 0x00, 0x81, 0x00, 0xC4, 0x0A, 0xB0, 0x09, 0x40, 0xA4, 0x00, 0x95, -0x00, 0x04, 0x0E, 0x10, 0x09, 0x40, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x88, 0x24, 0x04, 0x9D, 0x10, 0x74, 0x22, 0xD0, 0x09, -0x40, 0x27, 0x01, 0x91, 0x00, 0x14, 0x02, 0x14, 0x0D, 0x41, 0x27, 0x41, 0x95, -0x00, 0x54, 0x12, 0x50, 0x09, 0x40, 0xA5, 0x00, 0x91, 0x00, 0x54, 0x12, 0x14, -0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x20, 0x20, 0x05, 0x8D, 0x34, 0x36, 0x52, 0xD2, 0x08, 0x40, 0x23, 0x40, 0x89, -0xC0, 0x04, 0x22, 0x10, 0x08, 0x40, 0xA3, 0x00, 0x95, 0x02, 0x14, 0x03, 0x90, -0x88, 0x40, 0x20, 0x05, 0x94, 0x00, 0x44, 0x06, 0x10, 0x48, 0x41, 0x41, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F, -0x24, 0x7C, 0x91, 0xF0, 0x41, 0xC1, 0x07, 0x05, 0x11, 0x54, 0x5C, 0x58, 0x30, -0x01, 0xCA, 0x07, 0x05, 0x17, 0x00, 0x5D, 0x04, 0x70, 0x21, 0xC0, 0x05, 0x01, -0x53, 0x00, 0x5C, 0x00, 0x30, 0x45, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x54, 0x7C, 0x02, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x12, 0xF2, 0x0B, 0xC0, 0x67, 0x00, -0xBB, 0x01, 0xEC, 0x0A, 0x70, 0x4B, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xAE, 0x52, -0xF4, 0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x19, 0xA8, 0x6F, 0x04, 0xBF, 0x36, 0xFC, 0x42, 0xF0, 0x0A, 0xC0, 0x2C, 0x00, -0xBF, 0x90, 0x7F, 0x32, 0xF0, 0x0F, 0xC0, 0xAF, 0x04, 0x9F, 0x02, 0xCD, 0x86, -0x34, 0x89, 0xC0, 0x2F, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, -0x1D, 0x02, 0x74, 0x08, 0xD0, 0xA1, 0x52, 0x84, 0x02, 0x1D, 0x02, 0x44, 0x00, -0x70, 0x05, 0x40, 0xC7, 0x00, 0x1D, 0x01, 0x44, 0x88, 0x10, 0x05, 0x48, 0x04, -0x00, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02, -0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x1A, 0xD0, 0x08, 0x62, 0x23, -0x00, 0x8D, 0x00, 0x04, 0x0A, 0x10, 0x48, 0x40, 0x22, 0x00, 0x8D, 0x00, 0x74, -0x03, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0xA0, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, -0x20, 0x9D, 0x00, 0x44, 0x02, 0x50, 0x09, 0x48, 0x27, 0x00, 0x8D, 0x00, 0x44, -0x02, 0x11, 0x89, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40, -0x60, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, -0x10, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x08, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0x40, 0x2F, 0x00, 0xBE, 0x07, 0x4C, 0x02, 0x31, 0x39, 0xC2, -0x27, 0x00, 0x9F, 0x00, 0x3C, 0x16, 0x20, 0x09, 0xD0, 0x14, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x24, 0x00, 0x9F, 0x80, 0x7C, -0x42, 0xF0, 0x08, 0xE0, 0x27, 0x0C, 0x8F, 0x10, 0x7D, 0x02, 0xF0, 0x39, 0xC0, -0x27, 0x00, 0x9F, 0x02, 0x7C, 0x4A, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x23, -0x7C, 0x16, 0xF4, 0x59, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4C, 0x20, 0x30, 0x41, 0xC0, -0x04, 0x00, 0x12, 0x00, 0x5C, 0x80, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02, -0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x24, 0x1F, 0x22, 0x5C, 0x00, 0x30, 0x41, -0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, -0xDC, 0x04, 0x7D, 0x00, 0xC4, 0x09, 0xF0, 0x17, 0x44, 0xDD, 0x4C, 0x71, 0x03, -0x44, 0x01, 0x10, 0x77, 0xC0, 0x55, 0x00, 0x5B, 0x00, 0xB4, 0x11, 0xD0, 0x05, -0x40, 0x5F, 0x00, 0x7D, 0x03, 0xC4, 0x01, 0x50, 0x36, 0x40, 0x50, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xCD, 0x45, -0x14, 0x0A, 0x10, 0x24, 0x40, 0x70, 0x80, 0x81, 0x00, 0x14, 0x03, 0x10, 0x48, -0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0D, 0x42, 0xA3, 0x00, 0x8D, -0x12, 0x14, 0x03, 0x10, 0x8C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x03, 0x94, 0x05, 0x51, 0x22, -0x40, 0x61, 0x00, 0x81, 0x10, 0x84, 0x17, 0x14, 0x0A, 0x40, 0xFD, 0x01, 0xED, -0x04, 0xB4, 0x02, 0xD0, 0x4E, 0x00, 0x2B, 0x04, 0xBD, 0x11, 0x84, 0x03, 0x52, -0x00, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x10, 0x68, 0x00, 0xCF, 0x01, 0x15, 0x04, 0x10, 0x16, 0xE0, 0x78, 0x88, 0xA3, -0x01, 0xDC, 0x47, 0x30, 0x1E, 0xE8, 0x7F, 0x01, 0xE7, 0x03, 0xBC, 0x06, 0xF0, -0x1E, 0xC0, 0x6B, 0x00, 0xAF, 0x41, 0xDC, 0x07, 0x32, 0x1E, 0xC0, 0x50, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x5F, -0x00, 0x6C, 0x01, 0xF0, 0x01, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x7E, 0x23, 0xF0, -0x09, 0xC0, 0x37, 0x12, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x40, 0x73, 0x81, 0xE4, 0x04, 0xF1, -0x17, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x6F, 0x80, -0xE7, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC2, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x07, -0x30, 0x17, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x88, 0x29, 0x00, 0x61, 0x00, 0x84, 0x10, 0x70, 0x02, 0x40, 0x98, 0x02, -0xE1, 0x80, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x81, 0xE1, 0x00, 0x84, 0x02, -0xD0, 0x8E, 0xC0, 0x3A, 0x00, 0xED, 0x00, 0xF4, 0x23, 0x18, 0x26, 0x40, 0x54, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x00, -0xE1, 0x00, 0x84, 0x00, 0xD1, 0x08, 0x40, 0x38, 0x00, 0xE1, 0x08, 0xB4, 0x03, -0xD0, 0x0E, 0x41, 0x2B, 0x30, 0xF5, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x28, -0x04, 0xAD, 0x00, 0xB4, 0x02, 0x50, 0x26, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x13, 0x00, 0x11, 0x40, 0x04, 0x01, -0x50, 0x08, 0x4C, 0x10, 0x00, 0xC9, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40, 0x23, -0x00, 0xC1, 0x04, 0x04, 0x05, 0xD0, 0x2C, 0x40, 0x22, 0x80, 0x4D, 0x00, 0x36, -0x0C, 0x50, 0x0C, 0x52, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0xA8, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x05, 0xC4, 0x14, -0x00, 0x93, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC4, 0x37, 0x00, 0xD7, 0x04, 0x4D, -0x12, 0xF0, 0x3F, 0xC1, 0x24, 0x00, 0x9F, 0x0A, 0x7C, 0x0C, 0x70, 0x29, 0xC0, -0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, -0x10, 0x9F, 0x82, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x03, 0x00, 0x97, 0x80, 0x7E, -0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC1, -0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x60, 0xB4, 0x29, 0xC0, 0x27, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x0A, 0x2B, 0x20, 0x93, 0x80, 0xCC, -0x00, 0x30, 0x07, 0xC0, 0xAF, 0x00, 0xA3, 0x09, 0x8D, 0x03, 0x32, 0x0F, 0xC1, -0x77, 0x00, 0xFB, 0x00, 0xCC, 0x02, 0x34, 0x0F, 0x00, 0x2E, 0x00, 0xBF, 0x00, -0xFC, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x21, 0x36, 0x00, 0x91, 0x11, 0x14, 0x41, 0x51, 0x95, 0x40, -0xA7, 0x00, 0x91, 0x02, 0x44, 0x03, 0x10, 0x09, 0x44, 0x67, 0x02, 0xDD, 0x00, -0x04, 0x02, 0x30, 0x0D, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x34, 0x1C, 0x10, 0xBD, -0x44, 0x87, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, -0x24, 0x10, 0x11, 0x81, 0x64, 0x80, 0x18, 0x05, 0x40, 0x17, 0x00, 0x91, 0x02, -0x44, 0x03, 0x14, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x10, 0x0D, -0x40, 0x36, 0x02, 0xDD, 0x00, 0x74, 0x04, 0x10, 0x01, 0x40, 0x07, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0x01, 0x00, -0x16, 0x80, 0x50, 0x04, 0x40, 0x13, 0x00, 0x01, 0x00, 0x04, 0x03, 0x10, 0x08, -0x48, 0xB3, 0x20, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xCD, -0x00, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xB0, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x00, 0x30, 0x09, -0xC0, 0x27, 0x00, 0xD1, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x27, 0x08, 0xFB, -0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x16, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x30, -0x01, 0xC4, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xA8, 0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0x7F, -0x40, 0xFC, 0x03, 0xF1, 0x07, 0xC0, 0x2F, 0x01, 0xFF, 0x00, 0xFC, 0x01, 0x70, -0x0E, 0xC0, 0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x17, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x7B, 0x22, 0xFB, -0x29, 0xEC, 0x27, 0xF0, 0x9F, 0xC4, 0x7C, 0x02, 0xEF, 0x09, 0xCC, 0x07, 0x30, -0x9F, 0xC0, 0x7C, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xC0, 0x7C, 0x00, -0xEF, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07, 0x00, 0x11, 0x04, 0x4C, 0x00, 0xD1, -0x01, 0x00, 0x04, 0x31, 0x1D, 0x04, 0x44, 0x04, 0x50, 0x41, 0x00, 0x05, 0x05, -0x11, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x40, 0x00, 0x25, 0x1D, 0x04, 0x44, 0x00, -0xD0, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0xA0, 0x35, 0x00, 0xD9, 0x00, 0x24, 0x13, 0x52, 0x4C, 0x42, 0x31, 0x01, -0xCD, 0x04, 0x44, 0x83, 0x50, 0x0D, 0x0A, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x43, -0xD0, 0x4C, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x4D, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x07, 0x00, -0x11, 0x00, 0x40, 0x80, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x47, 0x00, -0x50, 0x01, 0x48, 0x01, 0x40, 0x15, 0x20, 0x74, 0x00, 0xD0, 0x00, 0x48, 0x05, -0x00, 0x0D, 0x00, 0x54, 0x00, 0xC0, 0x01, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xDB, 0x00, 0x6C, 0x03, -0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x40, 0x0C, 0x03, 0x70, 0x0D, 0x40, 0x34, -0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x4C, -0x03, 0xE0, 0x0D, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xDC, 0x40, 0xF3, 0x03, 0xD4, 0x0E, -0x10, 0x3F, 0x00, 0xF8, 0x40, 0xF0, 0x03, 0xC0, 0x0F, 0x20, 0x3B, 0x00, 0xDC, -0x00, 0xF1, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, -0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, -0x00, 0xD7, 0x04, 0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x60, 0x5C, -0x07, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x4C, 0x13, 0xF0, 0x0D, 0xC0, -0x34, 0x40, 0xD3, 0x04, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0xAB, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x00, 0x06, 0x01, 0x12, 0x74, -0x14, 0xD0, 0x71, 0x60, 0x07, 0x00, 0x11, 0x00, 0x6C, 0x00, 0x10, 0x00, 0x40, -0xC7, 0x02, 0x0D, 0x11, 0x6C, 0x18, 0xD2, 0x01, 0x40, 0x04, 0x00, 0x11, 0x12, -0x6C, 0x00, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x20, 0xF0, 0x10, 0xC5, 0x80, 0x34, 0x03, 0xD1, 0x0D, 0x42, -0x33, 0x00, 0xDD, 0x00, 0x24, 0x0B, 0x90, 0x0C, 0x40, 0xB3, 0x00, 0xC5, 0x01, -0x04, 0x0F, 0xD8, 0x0C, 0x40, 0x32, 0x00, 0xC1, 0x01, 0x04, 0x0B, 0xD2, 0x1C, -0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, -0x4C, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD9, 0x12, 0x40, 0x4F, 0x02, 0x39, 0x01, -0xA4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x04, 0x3D, 0x01, 0xA6, 0x24, 0xD0, 0x12, -0x68, 0x4A, 0x00, 0x31, 0x01, 0xA4, 0x04, 0xD0, 0x12, 0x53, 0x3C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00, -0x3C, 0x03, 0xF0, 0x0C, 0x48, 0x33, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xB0, 0x0C, -0x40, 0x33, 0x00, 0xC7, 0x00, 0x0C, 0xA3, 0xF1, 0x0D, 0xCC, 0x32, 0x80, 0xC3, -0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC0, 0x49, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF8, 0x03, -0x80, 0x0B, 0x08, 0x36, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, -0x00, 0xFC, 0x20, 0xD2, 0x03, 0xC0, 0x0D, 0x10, 0x3F, 0x00, 0xFC, 0x00, 0xFA, -0x11, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xA8, 0x77, 0x20, 0xD7, 0x41, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x74, 0x00, 0xC3, -0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x01, 0x4D, 0x03, 0x70, -0x1D, 0xC0, 0x30, 0x00, 0xD3, 0x01, 0x4C, 0x07, 0x30, 0x1D, 0xD0, 0x40, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80, 0x0D, 0x48, 0x21, -0x40, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x25, 0x00, 0x90, 0x00, 0xD0, -0x02, 0x40, 0x0B, 0x00, 0x35, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x09, 0x00, -0x2B, 0x40, 0x84, 0x00, 0xB0, 0x03, 0xC0, 0x4E, 0x08, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xC2, -0x1F, 0x40, 0x7C, 0x00, 0xF5, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7F, 0x00, -0xE1, 0x01, 0x94, 0x07, 0x50, 0x1F, 0x48, 0x7C, 0x80, 0xE1, 0x01, 0xC4, 0x07, -0x18, 0x1E, 0x48, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x16, 0x28, 0x03, 0x00, 0x09, 0x00, 0x40, 0x00, 0xD8, 0x00, 0x42, 0x01, 0x00, -0x05, 0x20, 0x14, 0x00, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x05, 0x00, 0x14, 0x00, -0x50, 0x00, 0x40, 0x05, 0x08, 0x09, 0x00, 0x04, 0x00, 0x98, 0x00, 0x40, 0x5A, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00, -0x5B, 0x00, 0x6C, 0x01, 0xD0, 0x04, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x4C, 0x01, -0xF0, 0x05, 0xC4, 0x17, 0x00, 0x53, 0x00, 0x1C, 0x01, 0x70, 0x05, 0xC0, 0x14, -0x08, 0x53, 0x60, 0x4C, 0x01, 0x30, 0x05, 0x40, 0x5C, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x00, 0x37, 0x02, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x08, 0xF0, 0x03, 0xC8, 0x0F, -0x00, 0x3F, 0x02, 0xE4, 0x08, 0xB0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFD, -0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0x40, 0x24, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C, -0x16, 0x30, 0x09, 0xC0, 0x27, 0x40, 0x93, 0x04, 0x78, 0x16, 0xF0, 0x09, 0xC0, -0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, -0x01, 0x9D, 0x00, 0x74, 0x42, 0x14, 0x59, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x74, -0x0A, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x91, 0x9A, 0x74, 0x8E, 0xB2, 0x09, 0x40, -0x27, 0x10, 0x91, 0x02, 0x64, 0x16, 0xD1, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6C, 0x80, 0xBD, 0x01, 0xE4, -0x06, 0x10, 0x4B, 0x40, 0x2D, 0x00, 0xBD, 0x00, 0xF4, 0x0E, 0xD0, 0x0A, 0x40, -0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x00, 0x2F, 0x00, 0xB1, 0x10, -0xF4, 0x02, 0xD0, 0x0B, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x28, 0x00, 0xEC, 0x00, 0xB4, 0x02, 0x10, 0x0B, 0x40, -0x2B, 0x22, 0xAD, 0x08, 0xB4, 0x82, 0xD0, 0x8A, 0x60, 0x28, 0x42, 0xA1, 0x40, -0xF4, 0x02, 0x90, 0x8A, 0x40, 0x2B, 0x0A, 0xA1, 0x08, 0xA4, 0x02, 0xD0, 0x0A, -0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, -0x06, 0x00, 0x1F, 0x40, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x85, 0x00, 0x1D, 0x02, -0x7C, 0x00, 0xF0, 0x21, 0xD0, 0x84, 0x00, 0x13, 0x0A, 0x7C, 0x01, 0x30, 0x21, -0xC0, 0x87, 0x08, 0x03, 0x22, 0x7C, 0x00, 0xF0, 0x03, 0xE0, 0x77, 0xE0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x8D, 0x14, -0x7C, 0x52, 0xF0, 0x48, 0xC1, 0x22, 0x01, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x49, -0xC0, 0x27, 0x01, 0x9F, 0x81, 0x7C, 0x52, 0xF0, 0x48, 0xC0, 0x27, 0x01, 0x9F, -0x24, 0x3C, 0x52, 0xF0, 0x49, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xA0, 0xAF, 0x00, 0xB7, 0x02, 0xDC, 0x0A, 0xB0, 0x2B, -0xC0, 0x27, 0x00, 0x9F, 0x02, 0xDC, 0x02, 0x30, 0x89, 0xC0, 0x2F, 0x10, 0xB3, -0x00, 0xFC, 0x02, 0xF0, 0x29, 0xC0, 0xA7, 0x10, 0xBF, 0x00, 0xCC, 0x02, 0xB0, -0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x00, 0x05, 0x01, 0x11, 0x81, 0x44, 0x00, 0x10, 0x41, 0x40, 0x07, 0x05, 0x1D, -0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00, 0x74, 0x50, 0xD0, -0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x63, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x01, 0x85, -0x00, 0x54, 0x12, 0x90, 0x48, 0x40, 0x23, 0x80, 0x8D, 0x04, 0x44, 0x02, 0x10, -0x48, 0x40, 0x23, 0x44, 0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x80, -0x8D, 0x00, 0x06, 0x02, 0x90, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x00, 0x44, 0x03, 0x08, -0x09, 0x40, 0x27, 0x00, 0x8C, 0x00, 0x45, 0x82, 0x50, 0x09, 0x42, 0x23, 0x08, -0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, -0xD8, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x20, 0x25, 0x00, 0x97, 0x00, 0x1C, 0x02, 0xB0, 0x09, 0xC4, 0x27, 0x00, -0x9F, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x00, 0x7C, 0x02, -0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC8, 0x17, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x25, 0x00, -0x9F, 0x00, 0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02, -0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x80, 0x7D, 0x42, 0x70, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1D, 0x10, 0x7C, 0x10, -0xD0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04, -0x00, 0x1B, 0x49, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, -0x00, 0xB4, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xA0, 0xDC, 0x00, 0x7D, 0x23, 0xF4, 0x9D, 0x10, 0x97, 0x40, 0x17, -0x00, 0x5D, 0x00, 0xB4, 0x21, 0xD0, 0x05, 0x40, 0x1C, 0x00, 0x7D, 0x01, 0xF4, -0x01, 0xD0, 0x05, 0x40, 0x15, 0x20, 0x7D, 0x02, 0xF4, 0x09, 0x10, 0x07, 0x40, -0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB6, -0x06, 0xDD, 0x0B, 0x34, 0x03, 0x50, 0xAC, 0x40, 0x33, 0x00, 0xCD, 0x80, 0x14, -0x8F, 0xD0, 0x0C, 0x50, 0x70, 0x80, 0xC9, 0x21, 0x32, 0x27, 0xD0, 0x0C, 0x40, -0x32, 0x00, 0xDD, 0x12, 0x74, 0x23, 0x10, 0x1C, 0x40, 0x43, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x00, 0xF4, -0x03, 0x10, 0x0E, 0x40, 0x3B, 0x03, 0xEC, 0x04, 0xB4, 0x0A, 0xC0, 0x5E, 0x40, -0x38, 0x04, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x5F, 0x40, 0x3B, 0x00, 0x2D, 0x10, -0xB4, 0x03, 0x10, 0x2E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xEF, 0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0, -0x7B, 0x05, 0xEB, 0x89, 0x9C, 0x07, 0x70, 0xBF, 0xC0, 0x78, 0x20, 0x2B, 0x21, -0xBC, 0x07, 0xF0, 0x3E, 0xC0, 0x7A, 0x05, 0xEF, 0x01, 0xFC, 0x07, 0x31, 0x1E, -0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, -0x15, 0x10, 0x5F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0x80, 0xB7, 0x01, 0xDF, 0x0C, -0x7C, 0x00, 0xF0, 0x4D, 0xC0, 0x17, 0x00, 0x1F, 0x20, 0x7C, 0x03, 0xF0, 0x0C, -0x41, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x43, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x7D, 0x00, 0xFF, 0x89, -0xF8, 0x05, 0x70, 0x1F, 0xC2, 0x7D, 0x00, 0xFB, 0x01, 0xFC, 0x07, 0xF0, 0x1F, -0xC0, 0x6F, 0x00, 0xF7, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xF3, -0x01, 0x8C, 0x25, 0x30, 0x1E, 0xC0, 0x18, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x04, 0xED, 0x08, 0xF4, 0x11, 0x00, 0x0E, -0x40, 0x3F, 0x00, 0xE0, 0x10, 0xB4, 0x42, 0xD0, 0x8E, 0x41, 0x3B, 0x00, 0xF5, -0x02, 0x94, 0x0B, 0x50, 0x0E, 0xC0, 0x3B, 0x00, 0x3B, 0x08, 0x85, 0x39, 0xB0, -0x0A, 0x40, 0x55, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, -0x00, 0x39, 0x02, 0xED, 0x08, 0xB0, 0x01, 0xD1, 0x06, 0x40, 0x39, 0x04, 0xE9, -0x08, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0x71, 0x08, 0xC4, 0x01, 0x90, -0x0E, 0x40, 0x3F, 0x00, 0xE9, 0x00, 0xC4, 0x00, 0x18, 0x07, 0x40, 0x20, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x21, 0x10, 0x9D, -0x03, 0x34, 0x00, 0x90, 0x89, 0x40, 0xF2, 0x80, 0xC1, 0x02, 0x34, 0x0C, 0xD0, -0x1C, 0x60, 0x57, 0x00, 0x05, 0x06, 0x14, 0x0E, 0xD8, 0x2C, 0x40, 0xB1, 0x00, -0xCD, 0x0A, 0x00, 0xAC, 0x98, 0x00, 0x42, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x55, 0xA0, 0xC4, 0x20, 0x1F, 0x52, 0x7C, 0x0A, 0xD0, -0xA1, 0xC0, 0xFD, 0x80, 0xFB, 0x01, 0x7C, 0x2C, 0xF0, 0x0F, 0xC8, 0xD7, 0x01, -0x93, 0x11, 0x4C, 0x12, 0xB0, 0x3F, 0x41, 0xBF, 0x00, 0xC9, 0x08, 0x48, 0x0E, -0x10, 0x91, 0xC0, 0x74, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x08, 0x27, 0x20, 0x9F, 0x84, 0x7E, 0x60, 0x70, 0x21, 0xC8, 0x37, 0x09, -0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC1, 0xA6, 0x00, 0x9E, 0x40, 0x7E, 0x40, -0x70, 0x0D, 0xC1, 0x37, 0x22, 0x1B, 0x00, 0x7C, 0x1A, 0xF0, 0x89, 0xC4, 0x97, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x0B, 0x84, -0x33, 0x80, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x3E, 0x00, 0xF7, 0x10, 0xF8, 0x00, -0xF2, 0x0F, 0xC0, 0x1C, 0x04, 0x33, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, -0x04, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x08, 0x17, 0x11, 0x4C, 0x06, -0xD0, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x80, 0x74, 0x04, 0xF0, 0x0C, 0x40, 0x85, -0x02, 0x11, 0x03, 0x64, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x08, 0x1D, 0x11, 0x6C, -0x04, 0xD0, 0x38, 0xC8, 0x06, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0xA0, 0x44, 0x04, 0x11, 0x21, 0x54, 0x06, 0xD8, 0x39, 0x66, 0x32, -0x00, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x04, 0x04, 0x31, 0x21, 0x74, -0x04, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x08, 0x44, 0x06, 0xD0, 0x31, 0x40, -0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x24, -0x00, 0x85, 0x00, 0x05, 0x00, 0xD2, 0x08, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x34, -0x02, 0xD0, 0x0D, 0x40, 0x21, 0x20, 0x01, 0x00, 0x34, 0x00, 0xD2, 0x0C, 0x40, -0x33, 0x00, 0x1D, 0x00, 0x24, 0x02, 0xD0, 0x09, 0x40, 0x42, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x06, 0x00, 0x11, 0x00, 0x5C, -0x82, 0xF8, 0x01, 0xC0, 0x3E, 0x00, 0xF6, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0x40, -0x04, 0x00, 0x13, 0x00, 0x74, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x90, 0x1F, 0x00, -0x4C, 0x02, 0xF0, 0x01, 0xC0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xB6, 0x00, 0xCC, 0x02, 0xF8, 0x0B, 0xC0, -0x3F, 0x00, 0xFE, 0x80, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x0B, 0x40, 0x3F, 0x00, -0xA4, 0x02, 0xF2, 0x0F, 0xC0, 0x3B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, -0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, -0x7F, 0x40, 0xF3, 0x46, 0xFC, 0x03, 0x30, 0x4F, 0xC0, 0x4F, 0x12, 0x3B, 0x4C, -0xCC, 0x23, 0x30, 0x4F, 0xC2, 0x0C, 0x80, 0x3F, 0x01, 0xFC, 0x07, 0x71, 0x8F, -0xC0, 0x0F, 0x08, 0x73, 0x01, 0xFC, 0x00, 0x30, 0x03, 0xC0, 0x0C, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x7D, 0x00, 0xE1, 0x08, -0xF4, 0xAF, 0x10, 0xBF, 0x40, 0x27, 0x01, 0x5D, 0x08, 0xC4, 0x3B, 0x50, 0x9F, -0x40, 0x44, 0x00, 0x5D, 0x00, 0xF4, 0x07, 0x10, 0x0F, 0x40, 0x07, 0x00, 0xD5, -0x81, 0x74, 0x00, 0xB1, 0x01, 0x80, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00, 0xC4, 0x04, 0x34, 0x03, 0x55, 0x0C, -0x40, 0x43, 0x01, 0x8D, 0x44, 0x14, 0x03, 0x50, 0x0C, 0x50, 0x00, 0x00, 0x0D, -0x80, 0x34, 0x03, 0x10, 0x4C, 0x40, 0x07, 0x00, 0x41, 0x00, 0x34, 0x00, 0xD0, -0x00, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA0, 0x35, 0x00, 0xD5, 0x00, 0x70, 0x03, 0x50, 0x0D, 0x40, 0x67, 0x00, 0x5D, -0x14, 0x54, 0x03, 0x10, 0x0D, 0x00, 0x6C, 0x00, 0x5D, 0x10, 0x74, 0x03, 0x10, -0x0F, 0x40, 0x6F, 0x00, 0xD5, 0x04, 0x70, 0x06, 0xD0, 0x11, 0x40, 0x0F, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xD7, -0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC4, 0x47, 0x00, 0x1B, 0x03, 0x5D, 0x03, 0x70, -0x0D, 0x80, 0x44, 0x20, 0xDD, 0x00, 0x3C, 0x03, 0x74, 0x0D, 0xC4, 0x47, 0x00, -0x93, 0x06, 0x78, 0x04, 0x70, 0x51, 0xC0, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFB, 0x00, 0xBC, 0x03, 0xB0, -0x0F, 0xC0, 0x0F, 0x00, 0x6A, 0x20, 0xEC, 0x03, 0xF0, 0x0F, 0x84, 0x0F, 0x08, -0xFC, 0x00, 0xFE, 0x03, 0xE0, 0x0F, 0x80, 0x0F, 0x00, 0xBF, 0x01, 0xB8, 0x02, -0xB0, 0x09, 0xC2, 0x3E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x08, 0x31, 0x10, 0xD3, 0x40, 0x5C, 0x03, 0xF3, 0x0D, 0xC0, 0x06, 0x00, -0x9F, 0x02, 0x2C, 0x03, 0x70, 0x4C, 0xC0, 0x26, 0x04, 0xD7, 0x22, 0x7C, 0x13, -0x30, 0x0D, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x28, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00, -0xF1, 0x20, 0xC4, 0x17, 0xD0, 0x4F, 0x40, 0x24, 0x00, 0x5D, 0x40, 0xC0, 0x17, -0x10, 0x7F, 0x40, 0xE7, 0x00, 0xDD, 0x06, 0x70, 0x03, 0x11, 0xAF, 0x10, 0x24, -0x00, 0x9D, 0x45, 0x44, 0x46, 0x11, 0x19, 0x11, 0x4C, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x72, 0x40, 0xC9, 0x20, 0x24, 0x03, -0xD0, 0x6C, 0x40, 0x22, 0x00, 0x08, 0x20, 0x20, 0x03, 0xD0, 0x1C, 0x40, 0xC2, -0x88, 0x84, 0x20, 0x30, 0x0B, 0x10, 0x0C, 0x40, 0x04, 0x00, 0x8D, 0x21, 0x25, -0x04, 0x14, 0x11, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0F, 0x00, 0x70, 0x04, 0xE9, 0x01, 0xB4, 0x17, 0xD8, 0x1E, 0x40, 0x6A, -0x08, 0xAD, 0x05, 0xA4, 0x07, 0x90, 0x1E, 0x4A, 0x5B, 0x0A, 0xED, 0x6B, 0x34, -0x07, 0x81, 0x9E, 0x42, 0x58, 0x00, 0xAD, 0x01, 0xB6, 0x05, 0x10, 0xB6, 0x40, -0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, -0x00, 0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x0C, 0xC0, 0x22, 0x01, 0x9F, 0x00, 0x6C, -0x03, 0xF0, 0x0C, 0xC0, 0x02, 0x04, 0x87, 0x05, 0x3C, 0x43, 0x20, 0x0D, 0xC0, -0x10, 0x00, 0xCF, 0x00, 0x6C, 0x01, 0x30, 0x00, 0xC0, 0x48, 0x68, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x7D, 0x00, 0xF7, 0x10, 0xC1, -0x53, 0xF0, 0x0E, 0xC0, 0x3D, 0x00, 0xBB, 0x04, 0xDC, 0x0B, 0x7A, 0x8F, 0xC1, -0x3F, 0x08, 0xFF, 0x28, 0xFC, 0x07, 0x72, 0x2F, 0xC0, 0x3F, 0x00, 0xEF, 0x00, -0x4C, 0x03, 0xF0, 0x07, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x03, 0x5C, 0x4F, 0x30, 0x3D, 0xC9, -0x04, 0x10, 0x5F, 0x40, 0x4C, 0x37, 0x30, 0x2D, 0xC0, 0x56, 0x40, 0xDB, 0x01, -0x4C, 0x03, 0xB3, 0x2D, 0xC2, 0x14, 0x00, 0x8F, 0x00, 0x4C, 0x00, 0xF0, 0x0D, -0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80, -0x39, 0x01, 0xCD, 0x14, 0x02, 0x13, 0xB0, 0x4C, 0x4A, 0x08, 0x00, 0xCC, 0x00, -0x84, 0x13, 0xB0, 0x4E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x84, 0x0B, 0xD0, 0x0F, -0x40, 0x18, 0x00, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0xC0, 0x4E, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x02, 0xED, 0x01, -0x94, 0x17, 0x10, 0x9E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x04, 0x17, 0x10, 0x1E, -0x40, 0x61, 0x88, 0xE1, 0x21, 0x96, 0x17, 0xD0, 0x9E, 0x44, 0x78, 0x00, 0xBD, -0x01, 0x85, 0x05, 0xD0, 0x1C, 0x40, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x90, 0x0C, -0x40, 0x71, 0x01, 0xCD, 0x88, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xC1, -0x3A, 0x14, 0x03, 0xD0, 0x0C, 0x42, 0xF0, 0x04, 0x8D, 0x03, 0x44, 0x0B, 0xD0, -0x8D, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, -0x20, 0x15, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x05, 0x40, 0xDD, 0x01, 0x7F, -0xC1, 0x4D, 0x01, 0x31, 0x05, 0xC0, 0x9E, 0x04, 0x71, 0x03, 0x5C, 0x01, 0xB0, -0x05, 0xC4, 0xDC, 0x01, 0x7F, 0x59, 0xCC, 0x09, 0xF0, 0xB7, 0x40, 0x5D, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x00, 0x1F, -0x00, 0x64, 0x00, 0xF0, 0x21, 0x50, 0x06, 0x20, 0x0B, 0x80, 0x7C, 0x00, 0xF0, -0x01, 0xC0, 0x86, 0x04, 0x17, 0x00, 0x68, 0x08, 0xA2, 0x01, 0xD0, 0x07, 0x08, -0x1F, 0x22, 0x7C, 0x48, 0xF0, 0x01, 0xC0, 0x4A, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x00, 0x6C, 0x82, 0xF0, -0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x6C, 0x22, 0xF0, 0x49, 0xC4, 0x27, 0x00, -0x9F, 0x00, 0x7C, 0x0A, 0xD0, 0x29, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x50, 0x02, -0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x20, 0x2C, 0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0xA9, 0x40, 0x27, 0x10, -0x94, 0x00, 0x44, 0x02, 0xD0, 0x29, 0x04, 0xA7, 0x01, 0x9D, 0x11, 0xF4, 0x4E, -0xC2, 0x29, 0x50, 0x24, 0x00, 0x8D, 0x04, 0x44, 0x2A, 0x50, 0x09, 0x40, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, -0x9D, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x90, 0x40, 0x64, 0x02, -0xD0, 0x09, 0x01, 0x26, 0x82, 0x9D, 0x01, 0x74, 0x02, 0xC0, 0x28, 0x40, 0x24, -0x00, 0x9C, 0x80, 0x54, 0x02, 0x12, 0x29, 0x46, 0x60, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x21, 0x00, 0x8D, 0x48, 0x34, 0x02, -0xD1, 0x08, 0x40, 0x23, 0x62, 0x81, 0x08, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0x23, -0x21, 0x8D, 0x20, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x01, 0x8D, 0x80, 0x10, -0x53, 0x52, 0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1D, 0xB8, 0x46, 0x00, 0x1F, 0x36, 0x7C, 0x50, 0xF0, 0x45, 0xC1, 0x87, -0x00, 0x12, 0x16, 0x6C, 0x50, 0xF1, 0x41, 0x81, 0x46, 0x00, 0x0F, 0x0A, 0x7C, -0x04, 0xF0, 0x31, 0xC4, 0xC4, 0x02, 0x1F, 0x00, 0x58, 0x10, 0x30, 0x41, 0xE2, -0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0xA7, -0x00, 0x9F, 0x24, 0x78, 0x82, 0xF0, 0x09, 0xCA, 0x2F, 0x01, 0xFC, 0x04, 0x7C, -0x06, 0xF1, 0x09, 0x80, 0x2F, 0x02, 0xBF, 0x01, 0x7C, 0x0A, 0xB0, 0xC9, 0xC0, -0x6F, 0x02, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0xD1, 0x77, 0x60, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x6F, 0x00, 0x9F, 0x16, 0xFC, -0x02, 0x34, 0x4B, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, -0x2C, 0x60, 0xB3, 0x00, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x80, -0xCD, 0x82, 0xF0, 0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x1D, 0x02, 0x74, 0x00, 0x10, 0x01, 0x40, -0x04, 0x01, 0x0D, 0x8A, 0x74, 0x04, 0xD0, 0xA1, 0x40, 0x04, 0x08, 0x11, 0x00, -0x74, 0x08, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD1, 0x01, -0x42, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, -0xA1, 0x00, 0x8D, 0x00, 0x34, 0x0A, 0x11, 0x2C, 0x40, 0x20, 0x24, 0x89, 0x40, -0x34, 0x1A, 0xD0, 0x08, 0x40, 0x20, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD8, 0x08, -0x61, 0x20, 0x40, 0x95, 0x00, 0x14, 0x06, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, -0x70, 0x02, 0x12, 0x09, 0x40, 0xA4, 0x0A, 0x9D, 0x20, 0x74, 0x02, 0xD0, 0x09, -0x10, 0x24, 0x10, 0x95, 0x20, 0x74, 0x82, 0xD0, 0x08, 0x4C, 0x24, 0x04, 0x95, -0x08, 0x54, 0xA3, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x2A, 0x25, 0x20, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, -0xD0, 0x64, 0x00, 0x9F, 0x02, 0xFC, 0x02, 0xF0, 0x09, 0xC4, 0xA4, 0x04, 0x97, -0x00, 0x7C, 0x02, 0xF2, 0x09, 0x50, 0x64, 0x02, 0x87, 0x00, 0x5C, 0x02, 0xF0, -0x09, 0xC0, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x00, 0x25, 0x00, 0x9F, 0x00, 0x7E, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x20, 0x9F, -0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC3, 0x27, 0x02, 0x9B, 0x10, 0x7C, 0x82, 0xF0, -0x09, 0xC0, 0x67, 0x00, 0x9A, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x17, -0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC8, 0x07, 0x00, 0x13, 0x02, 0x6C, 0x20, 0xF0, -0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x87, 0x00, -0x13, 0x04, 0x7C, 0x04, 0x30, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x00, 0x2C, 0x01, 0xD0, -0xA7, 0x48, 0x17, 0x08, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x26, 0x40, 0x5B, 0x20, -0x7C, 0x83, 0xC4, 0x01, 0x11, 0x07, 0x41, 0x17, 0x00, 0x70, 0x00, 0xF4, 0x01, -0x10, 0x07, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x80, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x27, 0x9A, 0x0C, 0x44, 0x33, 0x00, -0xC0, 0x00, 0x24, 0x07, 0xD0, 0x2C, 0x40, 0x63, 0x20, 0xCD, 0x00, 0x00, 0x02, -0x90, 0x5C, 0x40, 0x37, 0x00, 0x81, 0x03, 0x30, 0x03, 0x94, 0x1C, 0x40, 0x43, -0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x79, 0x00, -0xE1, 0x01, 0xA5, 0x03, 0xD0, 0x06, 0x40, 0x7B, 0x02, 0xE1, 0x49, 0x84, 0x02, -0xD0, 0x06, 0x40, 0xBB, 0x80, 0x6D, 0x03, 0x84, 0x46, 0x92, 0x06, 0x40, 0x33, -0x00, 0xE1, 0x02, 0xB4, 0x07, 0x90, 0x26, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xF7, 0x09, 0x9C, 0x06, -0xB0, 0x1E, 0xC0, 0x7F, 0x45, 0xE2, 0x15, 0xAC, 0x07, 0xF0, 0x1A, 0xC0, 0x6B, -0x20, 0xBF, 0x01, 0x8C, 0x06, 0xA0, 0x1A, 0xC0, 0x7B, 0x05, 0xA3, 0x01, 0xFC, -0x07, 0xB0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0xB8, 0x31, 0x00, 0xDF, 0x0C, 0x5C, 0x02, 0xF1, 0x01, 0xC0, 0xB7, -0x01, 0xDF, 0x86, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x26, 0x00, 0x1F, 0x00, 0x3C, -0x02, 0x70, 0x09, 0xC0, 0x37, 0x01, 0xDF, 0x80, 0x7C, 0x02, 0x72, 0x05, 0xC0, -0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, -0x00, 0xFF, 0x01, 0xDE, 0x27, 0x70, 0x9B, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xDC, -0x27, 0xF0, 0x1F, 0xC0, 0x6F, 0x00, 0x7B, 0x09, 0xCC, 0x07, 0x30, 0x1F, 0xC0, -0x7C, 0x26, 0xBF, 0x81, 0xFC, 0x27, 0x31, 0x9F, 0xC0, 0x18, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x39, 0x00, 0xED, 0x00, 0x84, -0x02, 0xC0, 0x22, 0x42, 0x3B, 0x00, 0xE9, 0x00, 0x80, 0x02, 0xD0, 0x22, 0x40, -0x3B, 0x00, 0x19, 0x01, 0x94, 0x0A, 0x50, 0x06, 0x40, 0x79, 0x0A, 0xED, 0x00, -0xB4, 0x33, 0x30, 0x22, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x88, 0x00, 0x39, 0x00, 0xED, 0x00, 0x94, 0x82, 0x50, 0x02, 0x00, -0x3B, 0x00, 0xED, 0x08, 0x94, 0x03, 0xD1, 0x0A, 0x40, 0x2B, 0x00, 0x39, 0x10, -0x24, 0x03, 0xD0, 0x04, 0x40, 0x38, 0x00, 0xAD, 0x00, 0xB4, 0x09, 0x12, 0x0E, -0x60, 0x61, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, -0x21, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0, 0x00, 0x40, 0xF3, 0x00, 0xCD, 0x02, -0x04, 0x02, 0xD0, 0x08, 0x48, 0x73, 0x84, 0x09, 0x01, 0x34, 0x03, 0xD0, 0x04, -0x64, 0x31, 0x82, 0xCD, 0x00, 0x34, 0x04, 0x11, 0x00, 0x40, 0x09, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0xFF, 0x00, -0x54, 0x03, 0x70, 0x09, 0xC0, 0x3F, 0x03, 0xFF, 0x01, 0x5C, 0x03, 0xF0, 0x09, -0xC8, 0xA7, 0x01, 0x9B, 0x01, 0x64, 0x02, 0xB0, 0x0D, 0xCC, 0xFC, 0x12, 0x9D, -0x0A, 0x7C, 0x90, 0x33, 0x19, 0xC2, 0x75, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x0D, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x29, -0xC0, 0x37, 0x08, 0xDB, 0x18, 0x7E, 0x02, 0xF2, 0x01, 0x40, 0x37, 0x00, 0x1E, -0x00, 0x5C, 0x0A, 0x38, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x08, 0x74, -0x81, 0x50, 0x16, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, -0x08, 0x3F, 0x10, 0xDF, 0x00, 0xFC, 0x0B, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xDF, -0x00, 0xFC, 0x07, 0xF1, 0x0A, 0xC0, 0x2C, 0x40, 0x32, 0x01, 0xFC, 0x02, 0xF2, -0x1A, 0x80, 0x3C, 0x00, 0xB3, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x26, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, -0x00, 0x64, 0x07, 0xD0, 0x19, 0x42, 0x33, 0x00, 0xD1, 0x80, 0x74, 0x07, 0xD0, -0x39, 0x40, 0x00, 0x00, 0x11, 0x07, 0x74, 0x00, 0xD0, 0x19, 0xC0, 0x37, 0x00, -0x9B, 0x18, 0x64, 0x0C, 0xD0, 0x31, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD8, -0x19, 0x40, 0x37, 0x00, 0xD9, 0x00, 0x74, 0x13, 0xD0, 0x11, 0x40, 0xA6, 0x00, -0x35, 0x08, 0x74, 0x03, 0xC8, 0x49, 0x46, 0x39, 0x00, 0x91, 0x00, 0x60, 0x04, -0xD0, 0x19, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0xD8, 0x08, 0x40, 0x37, 0x00, -0xC1, 0x00, 0x34, 0x82, 0xD0, 0x00, 0x40, 0x30, 0x80, 0x05, 0x00, 0x34, 0x02, -0xD0, 0x00, 0x40, 0x32, 0x01, 0xC9, 0xA0, 0x24, 0x00, 0xD0, 0x00, 0x40, 0x43, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0x36, 0x00, -0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0x74, 0x02, -0xD1, 0x01, 0xC0, 0x24, 0x00, 0x17, 0x04, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3D, -0x05, 0x13, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x07, 0x64, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xEC, 0x02, -0xF0, 0x03, 0xCC, 0x3F, 0x00, 0xFB, 0x00, 0xF8, 0x02, 0xF2, 0x03, 0x88, 0x1F, -0x00, 0x1B, 0x16, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x37, 0x00, 0x7F, 0x00, 0xFC, -0x00, 0xF0, 0x03, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xAA, 0x7B, 0x12, 0xEF, 0x09, 0xEC, 0x07, 0xB0, 0x9E, 0xC0, 0x7A, -0x00, 0xF7, 0x09, 0xEC, 0x07, 0xF0, 0x3F, 0xC0, 0x7B, 0x00, 0xF7, 0x29, 0xCC, -0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0xA7, 0xB0, 0x1F, 0xC0, -0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07, -0x00, 0x1D, 0x44, 0x44, 0x04, 0x32, 0x01, 0x40, 0x44, 0x20, 0x11, 0x04, 0x4C, -0x10, 0x10, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40, -0x44, 0x10, 0x11, 0x20, 0x74, 0x00, 0x10, 0x11, 0xC0, 0x0E, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x11, 0xDD, 0x00, 0x24, -0x03, 0x91, 0x4D, 0x42, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x43, 0xD0, 0x4C, 0x40, -0x32, 0x00, 0xC5, 0x44, 0x14, 0x43, 0xD0, 0x0C, 0x62, 0x32, 0x00, 0xC1, 0x80, -0x34, 0x13, 0x90, 0x0D, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x05, 0x00, 0x1D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x40, -0x05, 0x08, 0x01, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x05, 0x00, -0x54, 0x00, 0xDA, 0x01, 0x44, 0x04, 0x40, 0x11, 0x00, 0x34, 0x00, 0x11, 0x01, -0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, -0x37, 0x08, 0xDF, 0x80, 0x6C, 0x83, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD6, 0x00, -0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD7, 0x00, 0x5C, 0x03, 0xE0, 0x0D, -0xC0, 0x32, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xB1, 0x0C, 0xC0, 0x21, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, -0xEC, 0x00, 0x70, 0x03, 0xC8, 0x0E, 0x20, 0x3E, 0x00, 0xCC, 0x00, 0xF0, 0x03, -0xC0, 0x0C, 0x08, 0x3B, 0x00, 0xEC, 0x00, 0xF2, 0x03, 0xC0, 0x0E, 0x00, 0x3F, -0x00, 0xE4, 0x00, 0xF0, 0x03, 0xC0, 0x1E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x0A, 0x00, 0x35, 0x20, 0xD7, 0xC8, 0x5C, 0x83, 0xC0, 0x0D, -0xC0, 0x35, 0x01, 0xD7, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0x36, 0x00, 0xD7, -0x00, 0x7C, 0x13, 0x30, 0x4D, 0xC4, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xD0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0xA0, 0xC4, 0x00, 0x01, 0x83, 0x04, 0x04, 0x10, 0xE0, 0x40, 0x80, 0x00, 0x11, -0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x48, 0xB0, -0x50, 0x40, 0xC7, 0x00, 0x11, 0x00, 0x70, 0x24, 0xD1, 0x01, 0x40, 0x4D, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0xB0, 0x04, 0xC5, -0x53, 0x14, 0x03, 0x50, 0x0C, 0x42, 0x31, 0x00, 0xC5, 0x00, 0x14, 0x03, 0xD0, -0x0D, 0x00, 0x32, 0x00, 0xC5, 0x00, 0x34, 0x0F, 0x92, 0x3C, 0x44, 0xB2, 0x09, -0xC5, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x08, 0x4C, 0x06, 0x31, 0x01, 0xC4, 0x04, 0x11, -0x13, 0x40, 0x48, 0x08, 0x25, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x00, -0x21, 0x01, 0xF4, 0x04, 0xD2, 0x92, 0x40, 0x4B, 0x0C, 0x21, 0x01, 0xB4, 0x14, -0xD0, 0x92, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x63, 0x72, 0x0C, 0xC0, 0x31, 0x02, -0xD5, 0x00, 0x1C, 0x13, 0xF0, 0x4C, 0xC0, 0x32, 0x01, 0xC7, 0x28, 0x3C, 0x23, -0xB0, 0x8C, 0xC0, 0x32, 0x00, 0xC6, 0x00, 0x3C, 0x63, 0xF2, 0x8C, 0xC0, 0x4A, -0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x0D, 0x00, -0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x0A, 0x3B, 0x08, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x08, 0xBC, 0xA0, 0xA0, 0x81, 0xC0, 0x0B, -0x10, 0x1F, 0x00, 0xFC, 0x30, 0xF0, 0x90, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xD3, 0x00, 0x7E, 0x03, -0x70, 0x0D, 0x80, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x30, -0x00, 0xDA, 0x00, 0x5C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00, 0x7C, -0x03, 0x34, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0x80, 0x0D, 0x08, 0x20, 0x00, 0xB2, 0x00, 0xD1, 0x02, 0x40, 0x0B, -0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0xC0, 0x09, 0x00, 0x21, 0xA0, 0xB4, -0x00, 0xD0, 0x02, 0xC4, 0x0A, 0x00, 0x2B, 0x80, 0xB4, 0x00, 0x10, 0x02, 0xC0, -0x4E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79, -0x20, 0xE9, 0x01, 0x94, 0x87, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xED, 0x01, 0xF4, -0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40, -0x7E, 0x00, 0xE9, 0x21, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x02, 0x00, 0x09, 0x00, 0x34, -0x00, 0xD2, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x74, 0x00, 0xD0, 0x00, 0x40, -0x01, 0x80, 0x0D, 0x00, 0x34, 0x80, 0xD0, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00, -0x36, 0x00, 0x10, 0x00, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x17, 0xA0, 0x11, 0x00, 0x5B, 0x00, 0x78, 0x01, 0x70, 0x05, 0xE0, -0x17, 0x00, 0x5F, 0x00, 0x7E, 0x01, 0xB1, 0x04, 0xC0, 0x16, 0x00, 0x5B, 0x20, -0x5C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x00, 0x5B, 0x20, 0x7C, 0x01, 0x30, 0x05, -0xC0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, -0x8F, 0x40, 0x37, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xE0, 0x0F, 0x00, 0x3F, 0x00, -0xFA, 0x00, 0x70, 0x23, 0xC0, 0x0F, 0x00, 0x33, 0x00, 0xF4, 0x08, 0xF0, 0x23, -0xC0, 0x8F, 0x00, 0x3F, 0x40, 0xF4, 0x08, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x01, 0x97, 0x00, -0x7C, 0x16, 0x50, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0xA0, 0x7C, 0x02, 0x33, 0x09, -0xC2, 0x25, 0x20, 0x93, 0x40, 0x74, 0x02, 0x02, 0x09, 0x54, 0xA4, 0x00, 0x97, -0x00, 0x7C, 0x06, 0x32, 0x29, 0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x91, 0x05, 0x34, 0x86, 0x10, 0x39, -0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x10, 0xA0, 0x04, 0x91, -0x00, 0x34, 0x06, 0xB2, 0x28, 0x40, 0xE0, 0x08, 0x95, 0x00, 0x30, 0x06, 0x51, -0x08, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA0, 0x24, 0x00, 0xB5, 0x04, 0xF4, 0x02, 0x50, 0x6B, 0x40, 0x2D, 0x00, 0xBD, -0x80, 0xD4, 0x82, 0x18, 0x0B, 0x41, 0x2C, 0xC0, 0xB1, 0x00, 0xD4, 0x12, 0x10, -0x2B, 0x40, 0x2D, 0x90, 0xB0, 0x80, 0xF4, 0x22, 0x12, 0x0B, 0x42, 0x60, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x3D, 0x00, 0xA1, -0x00, 0xF4, 0x02, 0x50, 0x0A, 0x40, 0x28, 0x20, 0xAC, 0x28, 0xB4, 0x22, 0x50, -0x0A, 0x40, 0x28, 0x00, 0xA1, 0xC8, 0xF4, 0x03, 0xD0, 0x0A, 0x40, 0x2D, 0x00, -0xA4, 0x00, 0xF4, 0x23, 0x50, 0x0E, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0x38, 0x06, 0x00, 0x17, 0x80, 0x7C, 0x00, 0x70, -0x01, 0xC0, 0x07, 0x00, 0x1C, 0x02, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x05, 0x00, -0x13, 0x02, 0x5C, 0x00, 0x32, 0xA1, 0xC0, 0x15, 0x00, 0x17, 0x0A, 0x38, 0x08, -0x30, 0x03, 0xC8, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB0, 0x25, 0x05, 0x9F, 0x34, 0x7C, 0x02, 0xB0, 0x49, 0xC1, 0x27, 0x00, -0x9F, 0x04, 0x2C, 0x12, 0xF0, 0x48, 0xC9, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x52, -0xB0, 0x19, 0xC0, 0x26, 0x00, 0x9F, 0x01, 0x7C, 0x12, 0xF0, 0x08, 0xC0, 0x77, -0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x80, 0x2F, 0x00, -0xBF, 0x08, 0xDC, 0x02, 0xF8, 0x0B, 0xC2, 0x2F, 0x00, 0x8F, 0x02, 0x7C, 0x02, -0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x2C, -0x40, 0x83, 0x00, 0xCC, 0x02, 0xB0, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x47, 0x01, 0x1D, 0x25, 0x44, 0x00, -0xD1, 0x41, 0x41, 0x07, 0x00, 0x1D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x42, 0x05, -0x08, 0x11, 0x00, 0x74, 0x00, 0xB0, 0x01, 0x42, 0x04, 0x00, 0x11, 0x40, 0x44, -0x00, 0x11, 0x01, 0x40, 0x61, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x31, 0x15, 0x8D, 0x44, 0x10, 0x02, 0xD8, 0x0C, 0x40, 0x23, -0x00, 0x8D, 0x04, 0x34, 0x42, 0x10, 0x09, 0x40, 0x20, 0x00, 0x81, 0x14, 0x34, -0x02, 0x10, 0x08, 0x50, 0x20, 0x80, 0x81, 0x20, 0x15, 0x02, 0xD0, 0x09, 0x40, -0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2A, 0x25, -0x00, 0x9D, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, -0x02, 0x11, 0x09, 0x40, 0x25, 0x20, 0x91, 0x00, 0x74, 0x02, 0x90, 0x08, 0x60, -0x24, 0x00, 0x91, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x22, 0x25, 0x10, 0x9F, 0x00, 0x5C, -0x02, 0xD0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, -0x20, 0x08, 0x93, 0x80, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x20, 0x00, 0x93, 0x00, -0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00, -0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x27, 0x04, 0x9F, 0x00, 0x6C, 0x42, 0x30, 0x09, -0x40, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, -0x05, 0x00, 0x17, 0x00, 0x4C, 0x00, 0xF0, 0x41, 0xC4, 0x07, 0x01, 0x17, 0x00, -0x4C, 0x00, 0x70, 0x01, 0xC3, 0x07, 0x00, 0x1F, 0x00, 0x5C, 0x40, 0xB0, 0x01, -0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC1, 0x51, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x02, 0x7D, 0xD8, -0x44, 0x01, 0x70, 0x27, 0x40, 0x9F, 0x00, 0x51, 0x20, 0x6C, 0x01, 0xD0, 0x76, -0x42, 0xDF, 0x00, 0x5D, 0x40, 0xEC, 0x0D, 0x11, 0x27, 0x40, 0x1C, 0x00, 0x59, -0x00, 0xD4, 0x01, 0x14, 0x06, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xD5, 0x40, 0x04, 0x26, 0xD0, 0x0C, -0x40, 0xA3, 0x00, 0xC5, 0x00, 0x44, 0x03, 0x58, 0x0C, 0x48, 0xF3, 0x03, 0xCD, -0x00, 0x46, 0x07, 0x90, 0x2C, 0x40, 0x32, 0x00, 0xDD, 0x00, 0x40, 0x0F, 0x00, -0x3C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x80, 0x38, 0x20, 0xED, 0x40, 0x85, 0x03, 0x58, 0x0E, 0x68, 0xEF, 0x00, 0xF5, -0x09, 0xA4, 0x23, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xFD, 0x45, 0xA4, 0x0B, 0x10, -0x02, 0x41, 0x2A, 0x04, 0xF9, 0x04, 0x96, 0x0B, 0x12, 0x0E, 0x45, 0x10, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x59, 0x00, 0x77, -0x01, 0x8C, 0x07, 0xF1, 0x1E, 0x40, 0x6B, 0x00, 0xE7, 0x15, 0x8C, 0x07, 0x70, -0x16, 0x80, 0x7B, 0x00, 0xEF, 0x01, 0xDC, 0x05, 0xB0, 0x1E, 0xD0, 0x5A, 0x08, -0xEF, 0x07, 0xCC, 0x06, 0x30, 0x1E, 0xC0, 0x51, 0x60, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0x5F, 0x40, 0x7C, 0x83, 0xF0, -0x0D, 0xC0, 0x23, 0x00, 0xDB, 0x06, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00, -0xCF, 0x08, 0x7E, 0x83, 0xF0, 0x60, 0xD5, 0x15, 0x20, 0xDB, 0x06, 0x7C, 0x02, -0xD0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x20, 0x7D, 0x0A, 0xFF, 0x01, 0xDC, 0xA7, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, -0xE7, 0x01, 0x8C, 0x0F, 0xB0, 0x13, 0xC8, 0x7B, 0x00, 0xF3, 0x03, 0xCC, 0x07, -0x30, 0x1B, 0xD0, 0x78, 0xA2, 0xFB, 0x03, 0xCC, 0x07, 0xF0, 0x1A, 0xC0, 0x18, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, -0xEC, 0x18, 0xB4, 0x83, 0xD0, 0x0E, 0x42, 0x3B, 0x28, 0xE1, 0x10, 0x94, 0x03, -0x50, 0x22, 0x44, 0x3B, 0x06, 0xE5, 0x00, 0xD4, 0x03, 0x50, 0x43, 0x40, 0x28, -0x02, 0xE1, 0x04, 0x84, 0x13, 0x71, 0x4A, 0x48, 0x54, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x02, 0x39, 0x10, 0xED, 0x00, 0x94, 0x03, -0xC0, 0x06, 0x40, 0x3B, 0x04, 0xF5, 0x00, 0xE4, 0x43, 0x10, 0x02, 0x40, 0x3F, -0x00, 0xFD, 0x00, 0xD4, 0x01, 0x50, 0x0A, 0x61, 0x18, 0x84, 0xE1, 0xB0, 0x84, -0x42, 0xD2, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x28, 0x65, 0x00, 0x8D, 0x00, 0x36, 0x13, 0xD0, 0x39, 0x40, 0xF3, -0x00, 0xC5, 0x03, 0x34, 0x0B, 0x50, 0xA0, 0x40, 0xF3, 0x00, 0xDD, 0x02, 0x14, -0x2A, 0x50, 0x38, 0x62, 0x40, 0x04, 0xC9, 0x53, 0x05, 0x04, 0x50, 0x28, 0x40, -0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xE5, -0x10, 0x9F, 0x01, 0x5C, 0x43, 0xD0, 0xA1, 0xC4, 0x07, 0x02, 0xF7, 0x01, 0xEC, -0x07, 0x30, 0xB1, 0xC8, 0xB7, 0x00, 0xFF, 0x01, 0x5E, 0x0E, 0x10, 0x99, 0xC4, -0x44, 0x00, 0xEB, 0x00, 0x0C, 0x81, 0xF3, 0x3D, 0xC6, 0x54, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x06, 0x9F, 0x04, 0x7C, -0x03, 0xF0, 0x81, 0xC0, 0xA7, 0x10, 0xDA, 0x00, 0x5C, 0x43, 0x78, 0x21, 0x80, -0x37, 0x0C, 0xD7, 0xB8, 0x78, 0x00, 0xF0, 0x09, 0xC0, 0xA7, 0x40, 0xD7, 0x00, -0x7C, 0x81, 0x70, 0xAD, 0xC1, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x08, 0x0F, 0x00, 0x3B, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, -0x0E, 0x00, 0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x03, 0x40, 0x3E, 0x00, 0xF3, 0x00, -0xFC, 0x40, 0xF0, 0x0B, 0xC0, 0x0C, 0x00, 0xF7, 0x00, 0xD4, 0x54, 0x30, 0x0F, -0xC0, 0x04, 0x28, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, -0xC6, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x60, 0x01, 0xDB, 0x00, -0x54, 0x03, 0xD0, 0x11, 0x40, 0xD3, 0x00, 0xDB, 0x00, 0x44, 0x0C, 0xD0, 0x18, -0xC0, 0x83, 0x20, 0xD1, 0x00, 0x54, 0x89, 0x51, 0x4C, 0x50, 0x84, 0x04, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC6, 0x00, 0x19, 0x03, -0x74, 0x13, 0xD8, 0x31, 0x40, 0x66, 0x00, 0xC1, 0x80, 0x44, 0x03, 0xD0, 0x11, -0x40, 0x66, 0x04, 0xD1, 0x00, 0x44, 0xC6, 0x90, 0x1B, 0x40, 0x04, 0x06, 0xF5, -0x00, 0x40, 0x09, 0x50, 0x45, 0x48, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x81, 0x00, 0x34, 0x83, 0xD0, 0x00, -0x40, 0x24, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x27, 0x00, 0xC9, -0x00, 0x04, 0x82, 0xC2, 0x19, 0x40, 0x02, 0xA0, 0xD1, 0x40, 0x54, 0x02, 0x50, -0x04, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x18, 0x06, 0x10, 0x1B, 0x00, 0x7C, 0x03, 0xDA, 0x01, 0xC0, 0x26, 0x00, 0xF3, -0x00, 0xC4, 0x03, 0xF0, 0x01, 0xC4, 0x26, 0x00, 0xF3, 0x00, 0x5D, 0x00, 0xF0, -0x0B, 0xC0, 0x04, 0x00, 0xE7, 0x00, 0x5C, 0x00, 0x30, 0x09, 0xD0, 0x04, 0x60, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xBF, -0x00, 0xFC, 0x03, 0xD0, 0x0B, 0xC0, 0x2B, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xE0, -0x03, 0xC0, 0x2F, 0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xC2, 0x0F, 0x00, -0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x6F, 0x00, 0xBF, 0x10, 0xFC, 0x05, 0x30, -0x16, 0xC8, 0x3F, 0x10, 0xFF, 0x14, 0xFC, 0x00, 0x30, 0x17, 0xC0, 0x2C, 0x00, -0x63, 0x01, 0xFC, 0x0F, 0x30, 0x4B, 0xC0, 0x5F, 0x00, 0xF3, 0x01, 0xBC, 0x02, -0xB0, 0x1F, 0xC8, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x67, 0x00, 0xDD, 0x01, 0x74, 0x05, 0x00, 0x19, 0x40, 0xFF, 0x30, -0xFD, 0x03, 0x74, 0x0D, 0x10, 0x1D, 0x42, 0xE4, 0x00, 0x95, 0x01, 0xF4, 0x13, -0x12, 0x19, 0x40, 0x77, 0x00, 0xF1, 0x41, 0x74, 0x02, 0x50, 0x11, 0x40, 0x0F, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, -0x8D, 0x40, 0x74, 0x00, 0x00, 0x08, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x08, -0x14, 0x0D, 0x48, 0xB0, 0x10, 0x84, 0x00, 0x34, 0x13, 0x10, 0x8C, 0x40, 0x23, -0x00, 0xC1, 0x00, 0x54, 0x02, 0x90, 0x0C, 0x40, 0x4F, 0x80, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x10, -0x18, 0x09, 0x40, 0x37, 0x20, 0xDD, 0x00, 0x76, 0x23, 0x10, 0x0D, 0x48, 0x30, -0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x04, 0x23, 0x00, 0xD1, 0x40, 0x74, -0x06, 0x50, 0x0D, 0x42, 0x0F, 0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA0, 0x77, 0x00, 0x9F, 0x01, 0x3C, 0x09, 0x30, 0x0D, 0xC2, 0x37, -0x00, 0xDF, 0x60, 0x5C, 0x13, 0x31, 0x08, 0xC8, 0x64, 0x02, 0xD3, 0x00, 0x7C, -0x03, 0x34, 0x0D, 0xC0, 0xD7, 0x00, 0xD3, 0x00, 0x7C, 0x17, 0xB2, 0x6D, 0xC0, -0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D, -0x21, 0x9F, 0x04, 0xFC, 0x45, 0xF4, 0x0B, 0xC2, 0x3F, 0x00, 0xFF, 0x00, 0xFC, -0x03, 0xF0, 0x2B, 0xD0, 0x3F, 0x40, 0xFD, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x7F, 0x01, 0xFF, 0x80, 0xFC, 0x03, 0xF1, 0x23, 0xC0, 0x1F, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01, 0x9F, 0x00, 0x5C, -0x09, 0xB8, 0x0D, 0xC1, 0x34, 0x00, 0xDB, 0x50, 0x7C, 0x01, 0xB0, 0x0D, 0xC0, -0x27, 0x80, 0x9E, 0x04, 0x0C, 0x03, 0xD0, 0x0D, 0xC4, 0xB7, 0x08, 0xDF, 0x40, -0x7C, 0x13, 0x32, 0x0D, 0xC2, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x13, 0x80, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x0D, 0xF0, 0x29, 0x40, -0x3C, 0x00, 0xFD, 0x01, 0x34, 0x0B, 0x10, 0x0D, 0x48, 0x37, 0x80, 0x9F, 0x12, -0x44, 0x2B, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x11, 0x34, 0x03, 0xB0, 0x1D, -0x41, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, -0x30, 0x00, 0x8D, 0x00, 0x14, 0x0C, 0xD0, 0xB4, 0x50, 0x70, 0x01, 0xCD, 0x02, -0x20, 0x10, 0x92, 0x00, 0x4C, 0x23, 0x00, 0x4D, 0x01, 0x24, 0x23, 0xD0, 0x08, -0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x08, 0x1C, 0x0C, 0x40, 0x0F, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00, 0xED, 0x01, -0x84, 0x44, 0x50, 0x1B, 0x40, 0x78, 0x00, 0xED, 0x01, 0x34, 0x06, 0x10, 0x1A, -0x40, 0x7B, 0x00, 0xB5, 0x09, 0xA6, 0x97, 0xD0, 0x1A, 0x40, 0x6B, 0x00, 0xED, -0x01, 0xF4, 0x86, 0x90, 0x12, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x04, 0xCF, 0x08, 0x1C, 0x00, 0xDA, 0x08, -0xC8, 0x30, 0x14, 0xCB, 0x10, 0x2C, 0x20, 0xB0, 0x48, 0xC0, 0x23, 0x02, 0x8D, -0x00, 0x2C, 0x23, 0xF0, 0x8C, 0x40, 0xA3, 0x00, 0xCF, 0x8C, 0x3E, 0x00, 0x30, -0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x38, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, -0x12, 0xF4, 0x23, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDD, 0x37, 0xF0, -0x0F, 0x00, 0x2F, 0x00, 0xDF, 0x29, 0x7E, 0x22, 0xF4, 0x0F, 0xC0, 0x0B, 0x60, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x33, 0x00, 0xD3, -0x48, 0x7C, 0x00, 0x60, 0x0C, 0xC0, 0xB4, 0x04, 0xDF, 0x04, 0x5C, 0x00, 0xF0, -0x09, 0xC0, 0x24, 0x00, 0xD7, 0x01, 0x6C, 0x27, 0x30, 0x0D, 0xC0, 0x27, 0x00, -0xDF, 0x00, 0x7C, 0x00, 0x30, 0x00, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xE1, 0xC0, 0xB4, 0x00, 0xD0, -0x0A, 0x44, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0A, 0x40, 0x38, 0x00, -0xED, 0x00, 0x04, 0x13, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x04, 0xB4, 0x02, -0x50, 0x02, 0x40, 0x4C, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x79, 0x10, 0xE1, 0x05, 0xB4, 0x44, 0xD8, 0x1F, 0x51, 0x78, 0x13, -0xE9, 0x05, 0x94, 0x25, 0xD0, 0x3A, 0x40, 0xE8, 0x02, 0xAD, 0x01, 0xA4, 0x07, -0x90, 0x1E, 0x40, 0x6B, 0x04, 0xED, 0x09, 0xF4, 0x0C, 0x10, 0x02, 0x40, 0x10, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, -0xC1, 0x01, 0x34, 0x16, 0xD0, 0x38, 0x40, 0x30, 0x10, 0xCD, 0x00, 0x34, 0x07, -0xD0, 0x18, 0x41, 0x70, 0x00, 0x8D, 0x00, 0x04, 0x03, 0x90, 0x9C, 0x40, 0x63, -0x00, 0xCD, 0x00, 0x34, 0x06, 0x50, 0x8C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x43, 0x11, 0xFC, 0x05, -0xF0, 0x36, 0xC0, 0x14, 0x20, 0x4F, 0x00, 0xDC, 0x15, 0xF1, 0x27, 0xD4, 0x14, -0x00, 0x77, 0x1B, 0x6C, 0x01, 0xB5, 0x15, 0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC, -0x01, 0x34, 0x37, 0xC4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x08, 0x05, 0x42, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x07, -0x20, 0x1F, 0x00, 0x70, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, -0x08, 0x71, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x22, 0x7C, 0x00, 0xF0, 0x01, 0xC1, -0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, -0x00, 0x93, 0x00, 0x45, 0x06, 0x50, 0x19, 0xD1, 0x24, 0x40, 0x93, 0x08, 0x5C, -0x42, 0xF0, 0x09, 0x40, 0x22, 0x40, 0x93, 0x02, 0x7C, 0x16, 0xF0, 0x29, 0xC0, -0x27, 0x00, 0x93, 0x82, 0x7C, 0x06, 0x34, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x20, 0x00, 0xB1, 0x03, 0x44, -0x02, 0xD0, 0x29, 0x40, 0x20, 0x13, 0x91, 0x40, 0xC4, 0x02, 0xD0, 0x09, 0x40, -0x2C, 0x00, 0x91, 0x40, 0xF4, 0x0E, 0xD0, 0x09, 0x40, 0x22, 0x20, 0xB1, 0x83, -0x74, 0x06, 0x10, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x08, 0x54, 0x1B, 0xD0, 0x69, 0x40, -0x24, 0x00, 0x91, 0x50, 0x50, 0x1A, 0xD0, 0x08, 0x40, 0x27, 0x00, 0x91, 0x00, -0x74, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x40, 0x74, 0x52, 0x10, 0x09, -0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, -0x21, 0x00, 0x81, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x80, 0x00, -0x04, 0x02, 0xD0, 0x28, 0x40, 0xA0, 0x00, 0x81, 0x00, 0x34, 0x0A, 0x80, 0x08, -0x40, 0xA6, 0x00, 0x81, 0x00, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x07, 0x00, 0x53, 0x01, -0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x05, 0x12, 0x14, 0x5C, 0x04, 0xF0, 0x00, -0xC0, 0x47, 0x00, 0x13, 0x00, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x07, 0x40, 0x53, -0x81, 0x7C, 0x00, 0x34, 0x01, 0xC0, 0x77, 0xE0, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x00, 0xBF, 0x02, 0xFC, 0x02, 0xF0, 0x0B, -0xC0, 0x27, 0x08, 0x9F, 0x40, 0xFC, 0x0A, 0xF1, 0x1B, 0xC0, 0xEF, 0x00, 0xEF, -0x00, 0x7C, 0x0E, 0xF0, 0x2B, 0x00, 0x6E, 0x20, 0x9F, 0x82, 0xBC, 0x5A, 0xE0, -0x0B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xA0, 0x29, 0x00, 0xBF, 0x01, 0xCC, 0x02, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xA3, -0x00, 0xBC, 0x46, 0xB0, 0x09, 0x40, 0x67, 0x00, 0xBB, 0x00, 0xC4, 0x16, 0x24, -0x5B, 0xC0, 0xA7, 0x10, 0xB3, 0x15, 0xCD, 0x42, 0xB0, 0x0B, 0xC0, 0x74, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x00, 0x1D, -0x00, 0x44, 0x00, 0x10, 0x05, 0x40, 0x85, 0x02, 0x11, 0x40, 0x74, 0x08, 0x30, -0x55, 0x41, 0xC3, 0x01, 0x11, 0x00, 0x54, 0x14, 0x10, 0x01, 0x40, 0x47, 0x08, -0x11, 0x02, 0x44, 0x08, 0x11, 0x01, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x21, 0x00, 0x8D, 0x02, 0x14, 0x02, 0x90, -0x08, 0x68, 0x20, 0x00, 0x81, 0x02, 0x34, 0x02, 0x90, 0x08, 0x40, 0xA3, 0x04, -0x99, 0x00, 0x04, 0x4A, 0x10, 0x28, 0x40, 0x23, 0x00, 0x81, 0x20, 0x04, 0x52, -0x91, 0x09, 0x42, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x64, 0x24, 0x00, -0x90, 0x00, 0x74, 0x06, 0x10, 0x89, 0x4C, 0x27, 0x00, 0x91, 0x00, 0x14, 0x02, -0x10, 0x09, 0x40, 0x23, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x19, 0x40, 0x60, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x65, 0x02, -0x8F, 0x09, 0x5C, 0x12, 0xB0, 0x18, 0x40, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x4A, -0xB0, 0x3B, 0xC0, 0x6F, 0x00, 0x9B, 0x00, 0xCC, 0x02, 0x30, 0x19, 0xC0, 0xEF, -0x01, 0x93, 0x80, 0x4C, 0x02, 0xB0, 0x49, 0xD0, 0x14, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x6D, 0x12, -0xF0, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x23, -0x01, 0x9F, 0x02, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0x7C, -0x02, 0x71, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x08, 0x05, 0x10, 0x13, 0x08, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05, -0xC1, 0x13, 0x08, 0x1C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, -0x00, 0x30, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0x31, 0x01, 0xC0, -0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC, -0x06, 0x71, 0x00, 0xB0, 0x1D, 0x50, 0x07, 0x42, 0x1B, 0x80, 0x71, 0x01, 0xC4, -0x0D, 0x10, 0x05, 0x40, 0x17, 0x00, 0x71, 0x02, 0xF4, 0x61, 0xB0, 0x05, 0x40, -0x17, 0x00, 0x6D, 0x00, 0xF4, 0x01, 0x11, 0x04, 0x40, 0x43, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xE2, 0x00, 0x81, 0x10, 0x34, -0x1E, 0x18, 0x04, 0x40, 0x23, 0x10, 0x85, 0x51, 0x14, 0x0D, 0x10, 0x0C, 0x40, -0x33, 0x00, 0xD9, 0x13, 0x34, 0x06, 0x14, 0x1C, 0x40, 0x33, 0x00, 0x8D, 0x10, -0x74, 0x02, 0x10, 0x08, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x82, 0x7C, 0x00, 0xA1, 0x00, 0xF4, 0x03, 0x50, 0x06, 0x40, -0x33, 0x00, 0xA5, 0x01, 0x84, 0x09, 0x11, 0x4E, 0x40, 0x3B, 0x03, 0xE1, 0x02, -0xB4, 0x33, 0x90, 0x0E, 0x61, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x02, 0x10, 0x0E, -0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, -0x68, 0x00, 0xA3, 0x01, 0xBC, 0x06, 0x30, 0x16, 0xC0, 0x6B, 0x00, 0xE5, 0x01, -0x9C, 0x05, 0x30, 0x3E, 0xC0, 0x7B, 0x00, 0xEB, 0x01, 0xBC, 0x07, 0x30, 0x1E, -0xC0, 0xFB, 0x00, 0xAF, 0x01, 0x3C, 0x01, 0x30, 0x1A, 0xC0, 0x53, 0x60, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x40, 0x9D, 0x00, -0x3C, 0x02, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x01, 0xF0, 0x0D, -0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x28, 0x6D, 0x00, 0xBB, 0x21, 0xFC, 0x06, 0xF0, 0x17, -0xC0, 0x6F, 0x00, 0xB3, 0x01, 0xDE, 0x07, 0x31, 0x9E, 0xC8, 0x7C, 0x00, 0xAE, -0x01, 0xEC, 0x07, 0xF8, 0x9F, 0xC0, 0x78, 0x00, 0xB3, 0x41, 0xCC, 0x06, 0x30, -0x1B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x10, 0x29, 0x00, 0xAD, 0x08, 0xB4, 0x03, 0xD0, 0x06, 0x40, 0x3B, 0x08, 0xA1, -0x00, 0x84, 0x13, 0xB0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x02, 0x84, 0x03, 0xD0, -0x0E, 0xC0, 0x3A, 0x02, 0xA1, 0x00, 0x94, 0x02, 0xB0, 0x0E, 0x44, 0x54, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x29, 0x00, 0xAD, -0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x23, 0x00, 0xA1, 0x00, 0xD4, 0x01, 0x11, -0x1F, 0x00, 0x78, 0x00, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x44, 0x7C, 0x00, -0x81, 0x00, 0x84, 0x01, 0x50, 0x0B, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x21, 0x00, 0x8D, 0x01, 0x34, 0x41, 0xD0, -0x04, 0x40, 0x03, 0x00, 0x41, 0x00, 0x04, 0x33, 0x90, 0x2C, 0x41, 0x30, 0x20, -0xCD, 0x0C, 0x04, 0x01, 0xD0, 0x0C, 0x40, 0x32, 0x04, 0xC1, 0x00, 0x54, 0x03, -0xD0, 0x3C, 0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xA8, 0x25, 0x10, 0xDF, 0x11, 0x7C, 0x8A, 0xF0, 0x8D, 0xC1, 0x27, 0x00, -0x93, 0x00, 0x5C, 0x05, 0x31, 0x0D, 0xD0, 0x34, 0x01, 0x4F, 0x02, 0x6C, 0x01, -0xF1, 0x0C, 0xC0, 0xB4, 0x40, 0x93, 0x00, 0x4C, 0xAA, 0x70, 0x29, 0xC0, 0x74, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x25, 0xC0, 0x37, 0x00, 0x8F, 0x00, 0x7E, 0x01, -0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x09, 0xF0, 0x0D, 0xC0, 0x37, -0x08, 0xDF, 0x00, 0x7C, 0x02, 0xB0, 0x89, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x6F, 0x00, 0xAF, 0x00, 0xDC, 0x02, -0x34, 0x1F, 0x00, 0x6F, 0x00, 0xDF, 0x00, 0xEC, 0x89, 0xF1, 0x0F, 0xC0, 0x3F, -0x00, 0x7F, 0x00, 0xCC, 0x01, 0x70, 0x4D, 0xD0, 0x3C, 0x00, 0xBF, 0x00, 0xCD, -0x00, 0x34, 0x0B, 0xC1, 0x07, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA1, 0x20, 0x36, 0x10, 0x9D, 0x03, 0x04, 0x02, 0x10, 0x89, 0x43, 0x37, -0x00, 0xDD, 0x00, 0x44, 0x05, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x03, 0x44, -0x19, 0x10, 0x0D, 0x42, 0x34, 0x00, 0xCD, 0x02, 0x44, 0x06, 0x10, 0x19, 0x40, -0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6, -0x01, 0xDD, 0x06, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x60, -0x03, 0xD0, 0x0D, 0x44, 0x37, 0x00, 0xDD, 0x01, 0x04, 0x85, 0x50, 0x0D, 0x40, -0x34, 0x10, 0x9D, 0x50, 0x44, 0x06, 0x10, 0x49, 0x40, 0x07, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xCD, 0x00, 0x04, -0x03, 0x10, 0x04, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, -0x33, 0x80, 0xDD, 0xA0, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0x8D, 0xC0, -0x44, 0x02, 0x10, 0x08, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x18, 0x26, 0x00, 0x5F, 0x00, 0x5C, 0x02, 0x30, 0x0D, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x6C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xDF, 0x00, -0x4C, 0x01, 0x70, 0x09, 0x80, 0x3C, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x09, -0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, -0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x1F, 0x00, 0x7F, 0x00, -0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFD, 0x01, 0xD0, 0x0B, -0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xBC, 0x02, 0xF0, 0x0A, 0xC4, 0x17, 0x62, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xB3, 0x0C, -0xDC, 0x00, 0x30, 0x4F, 0xC0, 0x3C, 0x01, 0xF3, 0x18, 0xFC, 0x32, 0x70, 0x17, -0xC0, 0x7F, 0x00, 0x5B, 0x01, 0x8C, 0x06, 0x32, 0x1A, 0xC2, 0x7E, 0x00, 0x3B, -0x08, 0xCD, 0x00, 0xB0, 0x03, 0xC2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0x18, 0x37, 0x01, 0x91, 0x8E, 0x44, 0x27, 0x10, 0x3F, -0x40, 0xBC, 0x40, 0xF5, 0x26, 0x74, 0x38, 0x10, 0x05, 0x44, 0x77, 0x00, 0x53, -0x01, 0x54, 0x05, 0x52, 0x19, 0x40, 0x55, 0x00, 0x11, 0x06, 0x44, 0x82, 0x10, -0x01, 0xC0, 0x0E, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0xA0, 0x33, 0x04, 0x81, 0x00, 0x54, 0x03, 0x10, 0x2C, 0x44, 0xB2, 0x05, 0xC1, -0x00, 0x34, 0x02, 0x50, 0x44, 0x41, 0x31, 0x00, 0x4D, 0x00, 0x54, 0x03, 0x10, -0x08, 0x40, 0x22, 0x00, 0x89, 0x02, 0x04, 0x21, 0xD0, 0x10, 0x42, 0x4F, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x31, 0x00, 0x91, -0x01, 0x44, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xD1, 0x00, 0x74, 0x84, 0x10, -0x05, 0x41, 0x37, 0x01, 0x51, 0x01, 0x54, 0x09, 0x50, 0x1D, 0x00, 0x35, 0x00, -0x11, 0x02, 0x44, 0x83, 0x51, 0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x36, 0x00, 0x13, 0x07, 0x10, 0x17, 0x30, -0x0D, 0xC0, 0x36, 0x08, 0xD3, 0x40, 0x7C, 0x44, 0x50, 0xB1, 0xE0, 0x35, 0x20, -0x5B, 0x07, 0x5C, 0x0B, 0x30, 0x18, 0x80, 0x36, 0x00, 0x1B, 0x02, 0x4C, 0x28, -0xF4, 0x19, 0xC0, 0x2B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x0F, 0x80, 0x3D, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0F, 0xC0, 0x39, 0x00, -0xDF, 0x00, 0x7C, 0x40, 0xF0, 0x13, 0xC0, 0x7F, 0x00, 0x79, 0x10, 0xFC, 0x13, -0xE0, 0x0F, 0xC0, 0x1F, 0x00, 0x5F, 0x02, 0xBC, 0x04, 0xB0, 0x02, 0xC0, 0x1E, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, -0x1F, 0x04, 0x4C, 0x03, 0x70, 0x0C, 0xE1, 0x35, 0x04, 0xD7, 0x08, 0x4C, 0x02, -0x70, 0x25, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x5C, 0x0B, 0xB0, 0x49, 0xC0, 0x34, -0x00, 0x5B, 0x00, 0x4C, 0x49, 0x34, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x03, -0x11, 0x1F, 0xC4, 0xFC, 0x04, 0xF1, 0x00, 0x44, 0x10, 0x10, 0x05, 0x40, 0x70, -0x00, 0x4B, 0x41, 0x68, 0x2F, 0xB0, 0x2D, 0x40, 0xB0, 0x01, 0x51, 0x00, 0x44, -0x89, 0x00, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x20, 0x32, 0x00, 0x1D, 0x00, 0x34, 0x83, 0x50, 0x1C, 0x40, 0x73, -0x80, 0xC1, 0x26, 0x64, 0x0E, 0x10, 0x00, 0x48, 0x31, 0x00, 0xC5, 0x03, 0x70, -0x0F, 0x90, 0x00, 0x48, 0x31, 0x21, 0x59, 0x0F, 0x04, 0x24, 0x10, 0x08, 0x60, -0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x7A, -0x80, 0x6D, 0x51, 0x95, 0x47, 0x10, 0x9E, 0x41, 0x70, 0x80, 0xE1, 0x81, 0xA6, -0x07, 0x14, 0x12, 0x00, 0x78, 0x00, 0x69, 0x05, 0xB4, 0x47, 0x99, 0xDA, 0x40, -0x5D, 0x00, 0xA1, 0x49, 0x04, 0x26, 0x10, 0x32, 0x41, 0x37, 0x20, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x32, 0x00, 0xCF, 0x20, 0x1C, -0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x2C, 0x13, 0x30, 0x41, 0xC0, -0x33, 0x24, 0x47, 0x15, 0x3C, 0x03, 0xB0, 0x5C, 0xC8, 0x21, 0x08, 0x8B, 0x05, -0x0D, 0x08, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xB8, 0x3D, 0x20, 0xFF, 0x00, 0xE8, 0x03, 0xF0, 0xAE, 0xC0, -0x3F, 0x40, 0xFB, 0x00, 0xDD, 0x03, 0xF1, 0x03, 0xC0, 0x3B, 0x00, 0x45, 0x80, -0xEC, 0x03, 0xF0, 0x0D, 0xC0, 0x3A, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF4, 0x8F, -0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, -0x77, 0x20, 0x53, 0x20, 0x7E, 0x83, 0xF0, 0xCD, 0xC0, 0x34, 0x11, 0xDF, 0x44, -0x5C, 0x01, 0xF0, 0x11, 0xC0, 0x32, 0x00, 0x1B, 0x00, 0x1C, 0x03, 0x70, 0x0D, -0xC2, 0x36, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x30, 0x0D, 0xC2, 0x40, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x3D, 0x00, 0x61, 0x00, -0xB4, 0x83, 0x14, 0x0E, 0x40, 0xB8, 0x05, 0xFD, 0x16, 0x84, 0x03, 0xD0, 0x02, -0x40, 0x38, 0x80, 0x27, 0x40, 0x84, 0x03, 0x11, 0x0E, 0x40, 0x18, 0x00, 0xED, -0x00, 0x85, 0x03, 0x10, 0x07, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xE1, 0x01, 0xF6, 0x87, 0xD2, 0x4E, -0x40, 0x7B, 0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x33, 0x40, 0x7B, 0x00, 0x31, -0x01, 0x94, 0x07, 0x58, 0x1F, 0x41, 0x7A, 0x00, 0xED, 0x01, 0x04, 0x07, 0x54, -0x1E, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x20, 0x33, 0x00, 0xC1, 0x43, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xDD, -0x00, 0x44, 0x1F, 0xD0, 0x48, 0x60, 0x21, 0x02, 0x05, 0x01, 0x06, 0x0F, 0x10, -0x3C, 0x40, 0x72, 0x00, 0xCD, 0x19, 0x04, 0x23, 0x50, 0x2D, 0x40, 0x58, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x71, -0x05, 0xFC, 0x49, 0xF0, 0x05, 0xC0, 0x16, 0x00, 0x5F, 0x00, 0xDC, 0x0D, 0xF0, -0x17, 0xC0, 0x17, 0x00, 0x63, 0x02, 0x9C, 0x6D, 0x70, 0x27, 0xE0, 0x1E, 0x09, -0x7F, 0x02, 0xCC, 0x25, 0x70, 0x87, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x1F, 0x30, 0x7C, 0x10, 0x74, -0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7E, 0x28, 0xF0, 0x01, 0xC0, 0x06, 0x08, -0x17, 0x58, 0x7C, 0x00, 0xF0, 0x61, 0xC0, 0x85, 0x00, 0x1E, 0x82, 0x3C, 0x00, -0x90, 0x21, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x67, 0x01, -0x9F, 0x01, 0x68, 0x06, 0x32, 0x09, 0xC2, 0x27, 0x00, 0x92, 0x20, 0x5C, 0x06, -0x70, 0x19, 0xD0, 0x24, 0x00, 0x8A, 0x05, 0x44, 0x02, 0x70, 0x09, 0xC2, 0x40, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, -0x9D, 0x11, 0x34, 0x02, 0x10, 0x59, 0x40, 0xE7, 0x00, 0x9D, 0x8B, 0x44, 0x06, -0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08, 0x44, 0x8A, 0x10, 0x88, 0x40, 0xE4, -0x20, 0x9D, 0x07, 0x44, 0x0A, 0x50, 0x29, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x08, 0x74, 0x12, -0x50, 0x89, 0x42, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x52, 0x50, 0x09, 0x48, 0x27, -0x40, 0x9D, 0x90, 0x54, 0xA2, 0x53, 0x0D, 0x61, 0x64, 0x00, 0x98, 0x00, 0x54, -0x2A, 0x51, 0x39, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x52, 0x15, 0x48, 0x41, 0x23, -0x25, 0xCD, 0x14, 0x14, 0x52, 0x50, 0x08, 0x40, 0x23, 0x00, 0x95, 0x00, 0x04, -0x02, 0x11, 0x08, 0x60, 0x20, 0x00, 0x8D, 0x08, 0x14, 0x02, 0x50, 0x48, 0x51, -0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06, -0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x41, 0xC8, 0x07, 0x01, 0x1F, 0x04, 0x7C, -0x10, 0x70, 0x01, 0xC8, 0x07, 0x08, 0x17, 0x00, 0x58, 0x01, 0x72, 0x01, 0xD0, -0x14, 0x00, 0x0B, 0x16, 0x5C, 0x50, 0x70, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x25, 0x05, 0xBF, 0x34, 0xBC, -0x02, 0xF6, 0x08, 0xC0, 0x27, 0x05, 0x9F, 0x14, 0xE4, 0x52, 0xB4, 0x4A, 0xC1, -0x2F, 0x10, 0xAB, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBF, 0x04, -0xED, 0x52, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x11, 0xBC, 0x02, 0xC4, 0x0B, 0xC0, -0x6E, 0x01, 0xBF, 0x54, 0xFC, 0x32, 0xF0, 0x09, 0xC8, 0x29, 0x90, 0xB3, 0x00, -0xAD, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xCC, 0x12, 0x36, 0x0F, -0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, -0x47, 0x05, 0x1D, 0x87, 0x74, 0x00, 0x10, 0x81, 0x40, 0x07, 0x05, 0x1D, 0x04, -0x7C, 0x30, 0xD0, 0x05, 0x40, 0x07, 0x80, 0x55, 0x40, 0x44, 0x00, 0x12, 0x05, -0x54, 0x04, 0x00, 0x11, 0x00, 0x45, 0x28, 0x54, 0x01, 0x40, 0x73, 0x60, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x21, 0x00, 0xCD, 0x10, -0x74, 0x27, 0xC0, 0x0C, 0x40, 0xA3, 0x00, 0x8D, 0x14, 0x34, 0x13, 0xD2, 0x08, -0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x03, 0x90, 0x09, 0x40, 0x24, 0x00, 0x85, -0x80, 0x04, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x02, 0x76, 0x02, 0x10, 0x09, -0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xC2, 0x09, 0x48, 0x27, 0x01, 0x95, -0x00, 0x44, 0x22, 0x10, 0x09, 0x44, 0xA4, 0x02, 0x91, 0x00, 0x44, 0x22, 0x50, -0x09, 0x00, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xA8, 0x27, 0x00, 0x9D, 0x01, 0x3C, 0x0A, 0xF0, 0x09, 0xC0, 0x26, 0x08, 0x9F, -0x40, 0x7A, 0x42, 0xF0, 0xB9, 0xC0, 0x21, 0x80, 0x91, 0x00, 0x2C, 0x02, 0xB0, -0x19, 0xC0, 0x64, 0x00, 0x97, 0x04, 0x4C, 0x02, 0x30, 0x49, 0xC0, 0x17, 0x28, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x20, 0x9F, -0x04, 0x7C, 0x16, 0xF4, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x20, 0x5E, 0x52, 0xF0, -0x19, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC1, 0x27, 0x00, -0x9F, 0x53, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x42, 0x7C, 0x00, 0x70, -0x11, 0xCC, 0x07, 0x00, 0x1B, 0x00, 0x4C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00, -0x12, 0x30, 0x4C, 0x40, 0x70, 0x01, 0xC0, 0x85, 0x09, 0x0F, 0x8A, 0x5C, 0x00, -0x34, 0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0xA0, 0x14, 0x00, 0x7D, 0x0A, 0x74, 0x01, 0x10, 0x07, 0x40, 0x9F, 0x00, -0x71, 0x80, 0xC4, 0x01, 0xD0, 0x05, 0xC0, 0x9F, 0x00, 0x61, 0x41, 0xC5, 0x09, -0x10, 0x06, 0x42, 0x58, 0x08, 0x7D, 0x21, 0xC4, 0x09, 0x10, 0x07, 0x40, 0x50, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, -0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x48, 0x73, 0x80, 0xC9, 0x11, 0x14, 0x03, -0xD0, 0x0C, 0x40, 0xB3, 0x06, 0xC1, 0x88, 0x04, 0x03, 0x51, 0x2C, 0x40, 0x31, -0x02, 0xCD, 0x01, 0x54, 0x43, 0x90, 0x2C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x01, 0xED, 0x80, 0xF4, 0x03, -0x14, 0x02, 0x40, 0xFB, 0x00, 0xE1, 0x03, 0x94, 0x03, 0xD0, 0x8E, 0x64, 0x2B, -0x40, 0xF1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x44, 0x18, 0x00, 0xAD, 0x00, 0xC4, -0x03, 0x91, 0x1C, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x81, 0xB4, 0x07, 0x70, 0x12, 0xCA, 0x7F, -0x00, 0x4B, 0x01, 0x9D, 0x05, 0xF2, 0x1E, 0xC8, 0x7B, 0x80, 0x62, 0x01, 0x8C, -0x07, 0x70, 0x1E, 0xE8, 0x69, 0x20, 0xFF, 0x01, 0xDC, 0x85, 0xB0, 0x1E, 0xD0, -0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xB5, -0x0A, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x6C, -0x03, 0xF0, 0x0D, 0xC0, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0x40, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC2, 0x40, 0x00, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFD, 0x00, 0xFF, 0x01, 0xCC, -0x87, 0xB0, 0x17, 0x80, 0x5F, 0x00, 0xFF, 0x41, 0xFC, 0x07, 0xF9, 0x9E, 0xC0, -0x58, 0x00, 0x73, 0x81, 0x8C, 0x86, 0xB0, 0x9E, 0xC0, 0x7D, 0x08, 0xDF, 0x01, -0xFC, 0x07, 0x34, 0x17, 0xC2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0x7D, 0x08, 0x84, 0x23, 0x10, 0x82, 0x40, -0x1B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x62, 0x18, 0x01, 0x6B, 0x04, -0x84, 0x22, 0x10, 0x1C, 0xC0, 0x2A, 0x04, 0x8D, 0x0D, 0xB4, 0x29, 0xB4, 0x07, -0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x39, 0x00, 0xED, 0x00, 0xC4, 0x03, 0x90, 0x02, 0x40, 0x3B, 0x00, 0x6D, 0x00, -0xB4, 0x01, 0xD0, 0x0F, 0x5A, 0x18, 0x20, 0x71, 0x00, 0xF4, 0x43, 0xD0, 0x4F, -0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x90, 0x0E, 0x40, 0x00, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x80, 0x8D, 0x22, -0x04, 0x0B, 0x19, 0x08, 0x40, 0x07, 0x00, 0x8D, 0x00, 0x34, 0x08, 0xD1, 0x2C, -0x40, 0x50, 0x00, 0x49, 0x00, 0x34, 0x4A, 0x51, 0x3C, 0x40, 0xE3, 0x04, 0x0D, -0x10, 0x34, 0x00, 0x90, 0x28, 0x51, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x10, 0x1F, 0x01, 0x4C, 0x0B, 0xB0, 0x01, -0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x1A, 0xF0, 0x2F, 0xC0, 0x30, 0x04, 0xC1, -0x20, 0x7C, 0x80, 0xF0, 0x0C, 0xCC, 0xA3, 0x00, 0x5D, 0x20, 0x7C, 0x0A, 0x90, -0x29, 0x48, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x37, 0x28, 0x9F, 0x0C, 0x7D, 0x23, 0xF0, 0x01, 0xC0, 0x27, 0x00, 0x1F, -0x02, 0x7C, 0x4A, 0xF0, 0x0D, 0xC0, 0x27, 0xC0, 0xD7, 0x50, 0x49, 0x0A, 0xA0, -0xCD, 0x00, 0xA6, 0x00, 0x0F, 0x08, 0x78, 0x12, 0x74, 0x01, 0xC0, 0x07, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x10, 0x2F, -0x00, 0xEC, 0x47, 0xB0, 0x02, 0xD0, 0x2C, 0x00, 0x33, 0x00, 0xBC, 0x80, 0xB0, -0x0F, 0xC3, 0x3F, 0x00, 0x7F, 0xC0, 0xEC, 0x80, 0x71, 0x0B, 0xC0, 0x2E, 0x08, -0x73, 0x00, 0x0D, 0x02, 0x14, 0x0A, 0xD0, 0x11, 0x22, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x9D, 0x25, 0x04, 0x27, 0x10, -0x21, 0x40, 0x64, 0x00, 0x11, 0x05, 0x74, 0x16, 0x12, 0x0D, 0x40, 0x27, 0x10, -0xD5, 0x01, 0x04, 0x24, 0x10, 0x19, 0x45, 0xE4, 0x01, 0x55, 0x0A, 0x44, 0x06, -0x54, 0x71, 0x42, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0xA0, 0x34, 0x00, 0x1D, 0x81, 0x64, 0x03, 0x90, 0x05, 0x49, 0xC4, 0x80, -0x91, 0x01, 0x76, 0x06, 0x90, 0x0D, 0x40, 0xB7, 0x00, 0x55, 0x01, 0x66, 0x8A, -0x50, 0x1D, 0x60, 0x66, 0x80, 0x55, 0x02, 0x44, 0x06, 0x54, 0x11, 0x40, 0x04, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x08, -0x0D, 0x00, 0x44, 0x03, 0x14, 0x00, 0x40, 0x00, 0x48, 0x81, 0x40, 0x36, 0x02, -0x10, 0x0C, 0x40, 0x33, 0x00, 0x11, 0x08, 0x44, 0x02, 0x10, 0x4D, 0x60, 0x04, -0xC0, 0x05, 0x06, 0x04, 0x00, 0x58, 0x00, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x6C, 0x83, -0xB0, 0x01, 0xC0, 0x24, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC8, 0x37, -0x40, 0x1F, 0x02, 0x6C, 0x02, 0x70, 0xE9, 0xC3, 0x26, 0x80, 0x93, 0x16, 0x4C, -0x02, 0x70, 0x09, 0xC2, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x85, 0xA0, 0x3F, 0x20, 0xBF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC0, 0x2F, -0x00, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x08, 0x2F, 0x00, 0xFC, -0x02, 0xF0, 0x41, 0xC0, 0x2F, 0x00, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03, 0xC0, -0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, -0x00, 0x63, 0x04, 0xCC, 0x32, 0x72, 0x1F, 0xC8, 0x2C, 0x03, 0x72, 0x01, 0xCC, -0x05, 0x70, 0x0B, 0xC0, 0x3D, 0x00, 0xBB, 0x80, 0xEC, 0x04, 0xD0, 0x9B, 0xD0, -0x5C, 0x4A, 0xF3, 0x01, 0xCC, 0x12, 0xF1, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x7F, 0x00, 0x51, 0x03, 0x44, -0xB2, 0x12, 0x1F, 0x40, 0x24, 0x13, 0xD1, 0x01, 0x44, 0x07, 0x10, 0x3D, 0x40, -0xFC, 0x00, 0xB1, 0x03, 0x44, 0x80, 0xD0, 0x45, 0x40, 0x04, 0x01, 0xF1, 0x21, -0x44, 0x26, 0xD0, 0x1D, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x55, 0x02, 0x04, 0x12, 0x50, 0x0C, 0x40, -0x21, 0x01, 0x91, 0x00, 0x16, 0x02, 0x50, 0x88, 0x40, 0x31, 0x02, 0x89, 0x08, -0x24, 0x00, 0xD8, 0x08, 0x40, 0x30, 0x88, 0xC1, 0x00, 0x14, 0x82, 0xD2, 0x08, -0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, -0x35, 0x00, 0xD5, 0x00, 0x44, 0x82, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xD1, 0x00, -0x10, 0x22, 0x00, 0x09, 0x40, 0x35, 0x80, 0x95, 0x04, 0x44, 0x06, 0xC0, 0x81, -0x00, 0x34, 0x04, 0xD1, 0x40, 0x54, 0x12, 0xD0, 0x0C, 0x40, 0x0D, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x33, 0x40, 0xC7, 0x00, -0x4C, 0x26, 0x71, 0x0D, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x5C, 0x07, 0x70, 0x05, -0xC0, 0x35, 0x00, 0x9B, 0x00, 0x6C, 0x4C, 0xF0, 0x09, 0xC8, 0x24, 0x00, 0xD3, -0x00, 0x5C, 0x07, 0xF0, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0x7B, 0x09, 0xFC, 0x03, 0xB3, 0x0F, -0xC0, 0x3E, 0x41, 0xBF, 0x00, 0xED, 0x83, 0xF0, 0x9F, 0x82, 0x36, 0x20, 0x9B, -0x01, 0xFC, 0x00, 0xF0, 0x1F, 0xC0, 0x2F, 0x00, 0xFD, 0x80, 0xEC, 0x02, 0xF2, -0x8F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x08, 0x35, 0x12, 0xDF, 0x0A, 0x4D, 0x03, 0xF0, 0x8C, 0xC4, 0x34, 0x00, 0x9F, -0x00, 0x7C, 0x03, 0xF0, 0x00, 0xC0, 0x73, 0x00, 0x8B, 0x00, 0x5C, 0x08, 0xF0, -0x09, 0xC0, 0xA7, 0x00, 0xCF, 0x00, 0x7C, 0x42, 0xF2, 0x09, 0xC2, 0x08, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA2, 0x34, 0x00, 0xDD, -0x80, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x9D, 0x00, 0x74, 0x03, 0xD0, -0x0B, 0x02, 0x3F, 0x00, 0x91, 0x01, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x04, -0xDD, 0x00, 0x74, 0x02, 0xD2, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x0C, 0x4C, 0x00, 0x44, 0x03, 0xD0, -0x0C, 0x51, 0x34, 0x02, 0x4D, 0x00, 0x30, 0x00, 0xD0, 0x08, 0x40, 0x32, 0x00, -0x81, 0x00, 0x14, 0x00, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x20, 0x34, 0x2E, -0xD0, 0x00, 0x50, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x80, 0x78, 0x00, 0x6D, 0x41, 0x84, 0x46, 0xD0, 0x1E, 0x48, 0x68, 0x00, -0xED, 0x01, 0xB4, 0x06, 0xD0, 0x1E, 0x42, 0x7B, 0x60, 0xA1, 0x21, 0x84, 0x84, -0xD0, 0x5E, 0x41, 0x6B, 0x00, 0xEC, 0x81, 0xB4, 0x07, 0xD2, 0x1B, 0x40, 0x18, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, -0xCF, 0x00, 0x0C, 0x02, 0xF2, 0x0C, 0xC0, 0x20, 0x00, 0x8F, 0x00, 0x3C, 0x12, -0xF0, 0x48, 0xC0, 0x33, 0x00, 0x83, 0x10, 0x1C, 0x80, 0xF8, 0x08, 0xE0, 0x33, -0x00, 0xCF, 0x48, 0x3C, 0x03, 0xF0, 0x09, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x42, -0xF0, 0x1E, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, -0x00, 0xB7, 0x00, 0xEC, 0x22, 0xF2, 0x4B, 0xC0, 0x3F, 0x00, 0xFE, 0x01, 0xFC, -0x43, 0xF0, 0x09, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x11, 0xA0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, -0x00, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x85, 0xC0, 0xF0, 0x22, 0xDB, 0x14, 0x74, -0x00, 0xE0, 0x1C, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, -0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9, -0x00, 0x6D, 0x04, 0xB4, 0x13, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0xB6, -0x02, 0xD0, 0x4E, 0x50, 0x38, 0x04, 0xA1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, -0x28, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x89, 0xED, 0x09, 0xB4, -0x07, 0xD0, 0x9E, 0x40, 0x79, 0x03, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x14, 0x62, -0x78, 0x01, 0xE9, 0x11, 0xB4, 0x04, 0xD0, 0x1F, 0x40, 0x69, 0x88, 0xED, 0x0D, -0xB4, 0x57, 0xD0, 0x1A, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0x8D, 0xA0, 0x34, 0x07, 0xD0, 0x0C, 0x40, -0x73, 0x10, 0x8D, 0x0B, 0x34, 0x2A, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x01, -0x34, 0x03, 0xD0, 0xDC, 0x40, 0x21, 0x23, 0xCD, 0x00, 0x34, 0x07, 0xD0, 0x08, -0x41, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, -0x11, 0x00, 0x7F, 0x20, 0x7C, 0x11, 0xF0, 0x05, 0xC0, 0x17, 0x24, 0x7F, 0x02, -0xFC, 0x0D, 0xF0, 0x07, 0xC0, 0x14, 0x00, 0x5B, 0x01, 0xFC, 0x31, 0xF0, 0x07, -0xD0, 0x9D, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x27, 0xC0, 0x5F, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x01, -0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x70, 0x40, 0xF0, 0x80, -0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0x80, 0x06, 0x28, 0x1F, -0x80, 0x78, 0x08, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x7C, 0x26, 0xF0, 0x39, -0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4D, 0x02, 0x32, 0x09, 0xC3, 0x64, 0x00, 0x8F, -0x01, 0x4C, 0x02, 0xF1, 0x29, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x06, 0x30, -0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x20, 0x2E, 0x00, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x6F, 0x00, 0x9D, -0x00, 0x04, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0, -0x09, 0x40, 0x67, 0x08, 0xBD, 0x00, 0x84, 0x0E, 0x10, 0x08, 0x40, 0x04, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0xD1, -0x08, 0x74, 0x02, 0xD0, 0x09, 0x41, 0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x10, -0x09, 0x50, 0x24, 0x01, 0x9D, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x42, 0x27, 0x00, -0x8D, 0x00, 0x44, 0x1A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0, -0x08, 0x42, 0xA3, 0x08, 0x8D, 0x02, 0x44, 0x0A, 0x10, 0x68, 0x41, 0x20, 0x05, -0x8D, 0x14, 0x05, 0x02, 0xD0, 0x28, 0x40, 0xA3, 0x08, 0x8D, 0x02, 0x05, 0x02, -0x10, 0x29, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1D, 0xB0, 0x56, 0x40, 0x53, 0x01, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00, -0x1F, 0x00, 0x4C, 0x00, 0x34, 0x41, 0xC0, 0x04, 0x01, 0x1F, 0x04, 0x4C, 0x28, -0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x4C, 0x04, 0x34, 0x01, 0xD0, 0x74, -0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, -0xBF, 0x02, 0xFC, 0x0E, 0xF0, 0x29, 0xC0, 0xEF, 0x00, 0xBF, 0x01, 0xFC, 0x06, -0xF0, 0x1B, 0xC0, 0x27, 0x00, 0xBF, 0x80, 0xFC, 0x06, 0xF0, 0x1B, 0xC0, 0x6F, -0x08, 0x9F, 0x23, 0xFC, 0x0A, 0xF0, 0x1B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6F, 0x00, 0xFB, 0x11, 0xCD, 0x16, -0xF0, 0x1B, 0xC0, 0x6F, 0x01, 0x93, 0x00, 0x6C, 0x0A, 0x20, 0x59, 0x80, 0x6D, -0x01, 0xA3, 0x05, 0x0C, 0x02, 0xF0, 0x2B, 0xC8, 0x2B, 0x00, 0x9D, 0x85, 0xCC, -0x06, 0x30, 0x29, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x42, 0x44, 0x14, 0xD0, 0x21, 0x40, 0xC7, -0x03, 0x51, 0x15, 0x64, 0x04, 0x10, 0x30, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54, -0x00, 0xD0, 0x51, 0x40, 0x57, 0x00, 0x1D, 0x07, 0x44, 0x28, 0x10, 0x11, 0x40, -0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3, -0x00, 0x89, 0x00, 0x04, 0x4A, 0xD0, 0x28, 0x42, 0x23, 0x04, 0x81, 0x20, 0x24, -0x02, 0x10, 0xC8, 0x61, 0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x50, 0x48, 0x60, -0x33, 0x05, 0x8D, 0x12, 0x14, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x91, 0x40, 0x44, -0x02, 0xD0, 0x09, 0x42, 0x27, 0x60, 0x91, 0x08, 0x24, 0x02, 0x10, 0x09, 0x42, -0x26, 0x00, 0x91, 0x04, 0x54, 0x0A, 0xD0, 0x89, 0x42, 0x27, 0x01, 0x9D, 0x00, -0x54, 0x06, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9B, 0x0E, 0xCC, 0x22, 0xF0, 0x09, 0xC0, -0x2F, 0x00, 0xB3, 0x03, 0xEC, 0x12, 0x30, 0x1B, 0xC0, 0x27, 0x00, 0x93, 0x00, -0x4C, 0x06, 0xE0, 0x1B, 0xC0, 0xEF, 0x20, 0xBF, 0x00, 0x5D, 0x02, 0xF0, 0x6B, -0xC0, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, -0x25, 0x00, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x21, -0x7C, 0x12, 0xF4, 0x38, 0xD0, 0x21, 0x40, 0x9F, 0x00, 0x7C, 0x0A, 0xF2, 0x09, -0xC0, 0x67, 0x08, 0x9F, 0x00, 0x2C, 0x82, 0x34, 0x39, 0xC0, 0x53, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x01, 0x0F, 0x00, -0x4D, 0x80, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, -0xC0, 0x04, 0x10, 0x17, 0x00, 0x4C, 0x08, 0x72, 0x01, 0xD0, 0x04, 0x40, 0x03, -0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x20, 0xDC, 0x20, 0x7D, 0x00, 0x44, 0x05, 0x10, 0x07, -0x40, 0x17, 0x04, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x16, 0x00, 0x41, -0x11, 0x44, 0x01, 0x10, 0x15, 0x43, 0x14, 0x00, 0x51, 0x00, 0xF0, 0x01, 0xC0, -0x05, 0x40, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0xA0, 0xE2, 0x00, 0x8D, 0x00, 0x04, 0x07, 0x10, 0x08, 0x42, 0x37, 0x00, 0xCD, -0x00, 0x30, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x01, 0x05, 0x03, 0x50, -0x0C, 0x40, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x02, 0xC0, 0x0C, 0x40, 0x53, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0xB8, 0x00, 0xAD, -0x00, 0x04, 0x77, 0x14, 0x0E, 0x40, 0x2B, 0x82, 0xED, 0x04, 0xB4, 0x13, 0xD0, -0x4E, 0x40, 0x2A, 0x00, 0xF5, 0x00, 0xC4, 0x07, 0x50, 0xDE, 0x40, 0x7E, 0x01, -0xE1, 0x0C, 0xB4, 0x03, 0xD1, 0x4E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xAF, 0x01, 0x84, 0x06, 0x30, -0x1A, 0xC0, 0x7B, 0x01, 0xEF, 0x03, 0xBC, 0x0F, 0xF0, 0x5E, 0xC0, 0x6A, 0x00, -0xE7, 0x01, 0x8C, 0x07, 0x70, 0x1F, 0x80, 0xFA, 0x00, 0xE3, 0x01, 0xBC, 0x06, -0xF0, 0x3E, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xC0, 0x0D, 0xC0, 0x27, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x8D, 0xC4, 0x23, 0x00, 0xDB, 0x00, 0x7C, 0x63, -0xB8, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, -0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00, -0xB3, 0x01, 0xFC, 0x87, 0x30, 0x1B, 0x80, 0x7F, 0x02, 0xE3, 0x01, 0x8C, 0x07, -0x30, 0x1F, 0x40, 0x7C, 0x01, 0xFF, 0x01, 0xEC, 0x07, 0x30, 0x1B, 0xC0, 0x78, -0x28, 0xF3, 0x21, 0xFC, 0x06, 0x30, 0x1E, 0xC8, 0x08, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x40, 0xA1, 0x00, 0xF4, 0x03, -0x14, 0x0A, 0x40, 0x2B, 0x48, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x8E, 0x40, 0x29, -0x00, 0xED, 0x00, 0xC4, 0x43, 0xB0, 0x0A, 0xC0, 0x3A, 0x02, 0xE1, 0x00, 0xB4, -0x0B, 0x10, 0x8E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x21, 0x00, 0xA1, 0x10, 0xB4, 0x02, 0x10, 0x0A, 0x40, 0x3B, -0x80, 0xF1, 0x01, 0xC4, 0x07, 0x10, 0x1F, 0x40, 0x28, 0x01, 0xCD, 0x00, 0xA4, -0x03, 0x10, 0x0B, 0x41, 0x3D, 0x00, 0xE1, 0x01, 0xB4, 0x62, 0x14, 0x1F, 0x40, -0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x13, -0x00, 0x81, 0x01, 0x34, 0x86, 0x10, 0x0C, 0x40, 0x63, 0x00, 0xC1, 0x07, 0x04, -0x0B, 0x18, 0x3C, 0x40, 0x21, 0x00, 0xCD, 0x00, 0x04, 0x17, 0x90, 0x3C, 0x43, -0x67, 0x00, 0xC1, 0x00, 0x34, 0x07, 0x10, 0x1C, 0x40, 0x18, 0x20, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x00, 0xD3, 0x03, 0x7C, -0x13, 0x30, 0x09, 0xC2, 0x77, 0x04, 0xD3, 0x04, 0x45, 0x2B, 0x34, 0x6D, 0xC0, -0x24, 0x00, 0xDF, 0x11, 0xEC, 0x03, 0x30, 0x3C, 0xC0, 0x65, 0x44, 0xD3, 0x20, -0x3C, 0x02, 0x30, 0x6D, 0xD0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0, -0x27, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDD, 0x40, -0x7C, 0x83, 0xF2, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D, -0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, -0x2F, 0x00, 0xBF, 0x10, 0x8C, 0x06, 0x31, 0x0B, 0xD0, 0xB4, 0x00, 0xFF, 0x00, -0xCC, 0x03, 0xF0, 0x0F, 0xC1, 0xEF, 0x00, 0xFF, 0x85, 0xCC, 0x03, 0x30, 0x4F, -0xC0, 0xEC, 0x00, 0xF3, 0x00, 0x4C, 0x16, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x03, -0x44, 0x02, 0x11, 0x24, 0x40, 0x74, 0x00, 0xDD, 0x40, 0x44, 0x03, 0xD0, 0x0D, -0x42, 0x67, 0x20, 0xCD, 0x01, 0x44, 0x03, 0x10, 0x19, 0x48, 0x74, 0x20, 0xD1, -0x00, 0x44, 0x01, 0x00, 0x0D, 0x40, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xDD, 0x06, 0x44, 0xA3, 0x14, 0x09, -0x41, 0x34, 0x00, 0xCD, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0xDD, -0x00, 0x84, 0x03, 0x10, 0x09, 0x40, 0x24, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10, -0x0C, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0x20, 0x00, 0xCD, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xCD, -0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x80, 0xDD, 0x40, 0x04, 0x03, 0x14, -0x09, 0x50, 0x20, 0x00, 0xC1, 0x40, 0x04, 0x02, 0x16, 0x0C, 0x54, 0x40, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0x1F, -0x00, 0x4C, 0x03, 0x30, 0x09, 0xCA, 0x24, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xF0, -0x0F, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0xCD, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x00, -0xF3, 0x00, 0x4D, 0x02, 0x30, 0x0F, 0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0x7F, 0x00, 0xED, 0x02, 0xF0, -0x07, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x2F, 0x00, -0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01, -0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA0, 0x7F, 0x00, 0xF7, 0x0C, 0xCC, 0x1B, 0x70, 0x3A, 0xC0, 0xEC, 0x00, -0xBB, 0x04, 0xFC, 0x03, 0x30, 0x1E, 0xC0, 0x3E, 0x00, 0xA7, 0x01, 0x8C, 0x06, -0x30, 0x1B, 0xC0, 0x7E, 0x12, 0xBF, 0x04, 0xCC, 0x07, 0xF0, 0x03, 0xC4, 0x0E, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, -0xF1, 0x8E, 0xC4, 0x3B, 0x10, 0x49, 0x40, 0x24, 0x00, 0x91, 0x0E, 0xF4, 0x2F, -0x50, 0x19, 0x40, 0xF4, 0x00, 0x5D, 0x01, 0x44, 0x50, 0x10, 0x19, 0x40, 0x34, -0x00, 0xC9, 0x14, 0x44, 0x03, 0xD0, 0x19, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA2, 0x33, 0x20, 0xC5, 0x04, 0x04, 0x13, -0x50, 0x49, 0x40, 0x30, 0x01, 0x09, 0x10, 0x14, 0x03, 0x12, 0x08, 0x60, 0x32, -0x02, 0xCD, 0x80, 0x44, 0x10, 0x10, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x04, -0x03, 0xD0, 0x08, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00, 0x46, 0x03, 0x10, 0x19, 0x41, 0x70, -0x00, 0x11, 0x01, 0x74, 0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x46, -0x84, 0x10, 0x09, 0x40, 0x35, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0, 0x19, 0x41, -0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA8, 0x36, -0x08, 0xD7, 0x00, 0x48, 0x03, 0x70, 0x39, 0xC0, 0x44, 0x01, 0x9B, 0x05, 0x5C, -0x83, 0x30, 0x19, 0xC0, 0x36, 0x80, 0xD7, 0x00, 0x4C, 0x4E, 0x31, 0x08, 0xC0, -0x37, 0x02, 0x9F, 0x00, 0x4D, 0x07, 0xF0, 0x30, 0xC0, 0x03, 0x20, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x82, 0x3D, 0x10, 0xEF, 0x00, 0xFC, -0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xFC, 0x43, 0xF0, 0x0B, 0xC0, -0x3F, 0xA4, 0xFF, 0x01, 0xFD, 0x03, 0xF0, 0x0F, 0xC2, 0x3E, 0x00, 0xEF, 0x02, -0xFC, 0x8F, 0xF0, 0x03, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x21, 0xC0, -0x35, 0x00, 0x97, 0x08, 0x0C, 0x03, 0x70, 0x01, 0xC0, 0x34, 0x02, 0xD7, 0x10, -0x4C, 0x00, 0xB1, 0x0D, 0xC0, 0x37, 0x04, 0xD3, 0x18, 0x44, 0x03, 0xF0, 0x21, -0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x70, 0x00, 0xFD, 0x0F, 0xF4, 0x03, 0xD0, 0x0C, 0x60, 0x34, 0x00, 0x91, 0x03, -0xC4, 0x4F, 0x30, 0xC0, 0xC0, 0x3C, 0x08, 0xC1, 0x11, 0x2C, 0x00, 0x10, 0x8D, -0x40, 0xF4, 0x00, 0xD5, 0x00, 0x44, 0x0B, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x72, 0x00, 0xCD, 0x03, -0x74, 0x07, 0x50, 0x08, 0x44, 0x31, 0x00, 0x05, 0x12, 0x14, 0x0B, 0xD0, 0x18, -0x40, 0xF0, 0x20, 0xC5, 0x00, 0x24, 0x02, 0xD2, 0x00, 0x06, 0xF3, 0x00, 0x89, -0x01, 0x04, 0x37, 0xD0, 0x90, 0x40, 0x1D, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x04, 0xED, 0x81, 0xB4, 0x4F, 0xD0, 0x1B, -0x48, 0x7D, 0x08, 0xE1, 0x09, 0x95, 0x07, 0x00, 0x9B, 0x40, 0x78, 0x00, 0x61, -0x01, 0xE4, 0x04, 0x10, 0x9A, 0x40, 0x78, 0x06, 0xAD, 0x01, 0x84, 0x07, 0xD9, -0x1A, 0x48, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, -0x10, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x70, 0x08, 0x40, 0x31, 0x00, 0x57, -0x00, 0x1C, 0x03, 0xF0, 0x88, 0xC0, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x00, 0xB0, -0x00, 0xC0, 0x37, 0x00, 0x8B, 0x0C, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x49, 0x48, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x3D, 0x00, 0xFF, -0x02, 0xFC, 0x4B, 0xF0, 0x8B, 0x80, 0x3A, 0x02, 0xFF, 0x00, 0xAC, 0x63, 0xF1, -0x8B, 0xD0, 0x3B, 0x00, 0xFF, 0x48, 0xFC, 0x00, 0xF0, 0x0A, 0xC2, 0x3F, 0x00, -0x97, 0x28, 0xFD, 0x03, 0xF0, 0x8E, 0xC0, 0x09, 0x60, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x0C, 0x7C, 0x0B, 0xF0, -0x09, 0xC0, 0x34, 0x00, 0x57, 0x01, 0x4C, 0x1B, 0xF1, 0x09, 0xC0, 0x34, 0x12, -0xCF, 0x00, 0x4C, 0x03, 0xB0, 0x01, 0xC0, 0x76, 0x90, 0xDB, 0x00, 0x7C, 0x83, -0x30, 0x05, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x88, 0x39, 0x00, 0xED, 0x04, 0xB4, 0x13, 0xD0, 0x0F, 0x44, 0x38, 0x00, -0xE1, 0x00, 0x84, 0x33, 0xD8, 0x0A, 0x42, 0x38, 0x00, 0xED, 0xA0, 0x84, 0x81, -0x14, 0x0E, 0x44, 0x39, 0x00, 0xE5, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x48, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x79, 0x00, -0xED, 0x05, 0xB4, 0x07, 0xD0, 0x1A, 0x54, 0x7C, 0x00, 0x45, 0x01, 0x84, 0x17, -0xC0, 0x13, 0x48, 0x78, 0x01, 0xEC, 0x01, 0xC5, 0x05, 0x12, 0x16, 0x40, 0x7D, -0x80, 0xE1, 0xA1, 0xF4, 0x8F, 0x11, 0x1C, 0x60, 0x0C, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, -0xD8, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x03, 0x04, 0x03, 0xD0, 0x80, 0x40, 0x30, -0x20, 0xCD, 0x05, 0x04, 0x15, 0x10, 0x0C, 0x40, 0x21, 0x00, 0xC5, 0x08, 0x74, -0x06, 0x50, 0x2C, 0x41, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x47, 0xC0, 0x98, -0x00, 0x77, 0x49, 0x4C, 0x01, 0xF0, 0xA7, 0xC8, 0x14, 0x00, 0x7F, 0x07, 0x8C, -0x15, 0x30, 0x47, 0xC0, 0x55, 0x00, 0x5B, 0x21, 0x7C, 0x01, 0x10, 0x27, 0xD1, -0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, -0x00, 0x1F, 0x82, 0x7C, 0x00, 0xF1, 0x01, 0xC1, 0x07, 0x01, 0x1F, 0xA8, 0x7D, -0x08, 0xD0, 0x21, 0xD4, 0x87, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0x70, 0x21, 0xC0, -0x05, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x01, 0x9F, 0x03, 0x3C, -0x02, 0x30, 0x09, 0xC0, 0x24, 0x08, 0x97, 0x01, 0x7C, 0x12, 0xF2, 0x29, 0xC0, -0x26, 0x00, 0x9F, 0x08, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x8F, 0x09, -0x4D, 0x02, 0x30, 0x48, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x74, 0x0A, 0x10, 0x09, 0x40, -0x24, 0x00, 0x91, 0x01, 0x74, 0x1A, 0xD0, 0x08, 0x41, 0xE4, 0x01, 0x8D, 0x60, -0x44, 0x02, 0x12, 0x68, 0x40, 0x24, 0x03, 0x9D, 0x02, 0x44, 0x02, 0x30, 0x29, -0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, -0x24, 0x00, 0x9D, 0x00, 0x74, 0x46, 0x50, 0x08, 0x42, 0x24, 0x00, 0x95, 0x08, -0x74, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x9D, 0x00, 0x54, 0x02, 0x52, 0x0D, -0x40, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x0A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x14, -0x34, 0x52, 0x54, 0x08, 0x40, 0x24, 0x0A, 0xC1, 0x94, 0x30, 0xD2, 0xD0, 0x09, -0x40, 0x21, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x19, 0x09, 0x70, 0x20, 0x10, 0x8D, -0x08, 0x04, 0x02, 0x14, 0x4C, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x01, -0xD0, 0x84, 0x00, 0x17, 0x04, 0x78, 0x10, 0xF0, 0x01, 0xC4, 0x07, 0x05, 0x1D, -0x40, 0x5C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x16, 0x4C, 0x00, 0x30, -0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, -0xB0, 0x27, 0x00, 0x9F, 0x14, 0x7C, 0x52, 0xB1, 0x4B, 0xC1, 0x2B, 0x01, 0xBF, -0x94, 0x7C, 0x02, 0xF2, 0x0A, 0xC0, 0x26, 0x10, 0xFE, 0x00, 0xBC, 0x53, 0xF0, -0x0A, 0xC0, 0x2B, 0x15, 0xBF, 0x04, 0xBC, 0x52, 0x70, 0x0B, 0xC0, 0x67, 0x60, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x00, 0xBF, -0x01, 0xCC, 0x5E, 0xE0, 0x28, 0xC0, 0xA7, 0x00, 0xB7, 0x09, 0xEC, 0x12, 0x70, -0x0A, 0xC0, 0x2F, 0x04, 0xAD, 0x00, 0x4C, 0x02, 0x30, 0x0A, 0xC0, 0xAE, 0x00, -0xBB, 0x00, 0xCD, 0x02, 0xB0, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x0F, 0x44, 0x08, 0xD0, -0x01, 0x40, 0x07, 0x01, 0x11, 0x0B, 0x44, 0x00, 0x10, 0x01, 0x40, 0x87, 0x00, -0x19, 0x00, 0x44, 0x10, 0x10, 0x01, 0x40, 0x04, 0x01, 0x11, 0x00, 0x44, 0x00, -0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0xA0, 0x23, 0x00, 0x8D, 0x10, 0x04, 0x12, 0xD0, 0x48, 0x40, 0x67, 0x00, -0x85, 0x04, 0x24, 0x0B, 0x50, 0x08, 0x40, 0x33, 0x00, 0x99, 0x00, 0x04, 0x42, -0x10, 0x09, 0x40, 0x22, 0x01, 0x89, 0x00, 0x24, 0x02, 0x90, 0x08, 0x40, 0x43, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, -0x9D, 0x60, 0x44, 0x02, 0xC8, 0x09, 0x41, 0x27, 0x02, 0x91, 0x00, 0x64, 0x02, -0x10, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00, 0x64, -0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, -0xC1, 0x39, 0xC8, 0x67, 0x00, 0x95, 0x51, 0x6C, 0x02, 0x70, 0x79, 0xC0, 0x27, -0x00, 0x9B, 0x01, 0x4C, 0x0E, 0x30, 0x19, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x4C, -0x06, 0xB0, 0x09, 0xC1, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x29, 0xC0, 0x67, -0x00, 0x8F, 0x05, 0x1C, 0x02, 0xF0, 0x99, 0xC4, 0x27, 0x24, 0x9B, 0x03, 0x7D, -0x12, 0xF4, 0x99, 0xC3, 0x27, 0x00, 0x9F, 0x13, 0x7C, 0xD6, 0xF0, 0x49, 0xC1, -0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04, -0x00, 0x0F, 0x04, 0x7C, 0x00, 0xF4, 0x21, 0xC2, 0x04, 0x40, 0x13, 0x00, 0x6C, -0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x02, 0x5C, 0x08, 0x31, 0x01, 0xC0, -0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x54, 0x04, 0x7D, 0x00, 0xF4, -0x61, 0x10, 0x05, 0xC0, 0x12, 0x00, 0x71, 0x07, 0xC4, 0x09, 0xD0, 0x27, 0x40, -0x1C, 0x00, 0x6D, 0x60, 0x44, 0x01, 0x12, 0x36, 0x41, 0x1C, 0x01, 0x7D, 0x47, -0xC4, 0x85, 0x50, 0x27, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0xA0, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x0F, 0x10, 0x0C, 0x40, -0x30, 0x00, 0xC1, 0x07, 0x24, 0x09, 0xD1, 0xC4, 0x40, 0xB3, 0x00, 0x8D, 0x00, -0x14, 0x03, 0x10, 0x00, 0x48, 0x35, 0x09, 0xDD, 0x03, 0x45, 0xAF, 0x10, 0xAC, -0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88, -0x28, 0x00, 0x6D, 0x82, 0xB4, 0x07, 0x10, 0xDF, 0x40, 0x3A, 0x03, 0xE1, 0x00, -0x84, 0x03, 0xD0, 0x13, 0x48, 0x39, 0x80, 0x7D, 0x80, 0xD4, 0x13, 0x1C, 0x02, -0x40, 0x39, 0x10, 0xED, 0x20, 0xC4, 0x03, 0x41, 0x1C, 0x40, 0x10, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01, -0x3C, 0x05, 0x30, 0xDE, 0xC0, 0x7C, 0x00, 0x73, 0x01, 0xAC, 0x07, 0xF0, 0x1E, -0xC0, 0x5B, 0x00, 0xAF, 0x01, 0x9C, 0x17, 0x30, 0x12, 0xD0, 0x79, 0x90, 0xBF, -0x01, 0xCC, 0x07, 0x20, 0x1E, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA8, 0x25, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0x31, 0x0D, -0xC8, 0xB7, 0x05, 0x5F, 0x20, 0x70, 0x03, 0xF1, 0x01, 0xC0, 0x16, 0x00, 0x5F, -0x80, 0x2C, 0x6B, 0xF0, 0x01, 0xD0, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0xF0, -0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xA0, 0x6F, 0x02, 0xF7, 0x09, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xFB, -0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7E, 0x00, 0xBB, 0x01, 0xCC, 0x17, 0xB0, -0x97, 0xC0, 0x7C, 0x08, 0x7F, 0x01, 0xCC, 0x05, 0xF1, 0x1F, 0xC0, 0x0B, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x00, 0x6D, -0x48, 0xB0, 0x03, 0xD0, 0x4E, 0xC0, 0x3B, 0x01, 0x61, 0x22, 0xB4, 0x8B, 0xD0, -0x46, 0x40, 0xB8, 0x08, 0x71, 0x00, 0xFC, 0x13, 0x10, 0xC6, 0x40, 0x38, 0x00, -0x6D, 0x48, 0x84, 0x00, 0xD0, 0x42, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x20, 0xE5, 0x40, 0xB4, 0x03, 0xD0, -0x0F, 0x40, 0x3C, 0x10, 0xE9, 0x08, 0xB4, 0x03, 0xD0, 0x07, 0x41, 0x1B, 0x02, -0xB9, 0x08, 0xA4, 0x73, 0x92, 0x06, 0x41, 0x18, 0x00, 0x2D, 0x00, 0xA4, 0x61, -0xD0, 0x0E, 0x60, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x28, 0x23, 0x00, 0x9D, 0x00, 0x34, 0x02, 0xD0, 0xEC, 0x60, 0xB2, 0x04, -0x09, 0x01, 0x34, 0x03, 0xD0, 0x10, 0x40, 0x10, 0x00, 0x41, 0x23, 0x36, 0x0F, -0x12, 0x34, 0x41, 0x20, 0x20, 0x0D, 0x09, 0x60, 0x04, 0xD0, 0x00, 0x40, 0x1B, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xA8, 0x25, 0x00, -0x97, 0x00, 0x74, 0x02, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x9B, 0x02, 0x7C, 0x03, -0xF0, 0x05, 0x80, 0x37, 0x00, 0x4B, 0x05, 0xEC, 0x07, 0xB0, 0x34, 0xD0, 0x04, -0x80, 0xDF, 0x01, 0x6D, 0x06, 0xD0, 0x0D, 0x48, 0x57, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x02, -0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x97, 0x0E, 0x74, 0x0B, 0xE0, 0x01, 0xA0, 0x36, -0x10, 0x5F, 0x02, 0x5C, 0x13, 0xF0, 0x05, 0xC0, 0x87, 0x0A, 0xDF, 0x02, 0x5C, -0x02, 0xF0, 0x0D, 0xC8, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x81, 0x08, 0xAF, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x3E, -0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF1, 0x07, 0xC8, 0x17, 0x20, 0x3B, 0x18, 0xCC, -0x03, 0xB2, 0x07, 0xD0, 0x0E, 0x00, 0xBF, 0x01, 0xFC, 0x02, 0x30, 0x23, 0xC1, -0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x26, -0x20, 0x1D, 0x01, 0x44, 0x04, 0xD0, 0x0C, 0xC0, 0x36, 0x00, 0x1D, 0x01, 0x74, -0x0F, 0xD0, 0x31, 0x42, 0xD7, 0x00, 0x5D, 0x52, 0x04, 0x03, 0x10, 0x35, 0x40, -0x44, 0x04, 0x1D, 0x03, 0x74, 0x8C, 0x10, 0x21, 0x40, 0x87, 0x02, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x80, 0x9D, 0x31, 0x64, -0x0C, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0x9D, 0x01, 0x74, 0x07, 0x50, 0x15, 0x41, -0x77, 0x00, 0x5D, 0x00, 0x47, 0x03, 0x90, 0x1D, 0x41, 0x64, 0x00, 0x5D, 0x94, -0x74, 0x46, 0x10, 0x2D, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x0D, 0x00, 0x04, 0x02, 0xD0, 0x0D, 0x40, -0x32, 0x00, 0x8D, 0x20, 0x34, 0x83, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x4D, 0x00, -0x46, 0x03, 0x10, 0x04, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x26, 0x82, 0x1C, 0x00, -0x40, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, -0x24, 0x00, 0x9F, 0x80, 0x6C, 0x00, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0x9F, 0x00, -0x7C, 0x03, 0x70, 0x05, 0xC4, 0x17, 0x00, 0x1B, 0x00, 0xCC, 0x03, 0xB4, 0x05, -0xC0, 0x04, 0x00, 0x4F, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC4, 0x07, 0x40, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBE, 0x00, -0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x02, -0xC0, 0x3F, 0x20, 0x7F, 0x40, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x2F, 0x00, 0x3F, -0x00, 0xFC, 0x00, 0xF2, 0x03, 0xE0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x01, 0xEC, 0x32, 0xF2, 0xC7, -0xC8, 0x5F, 0x02, 0x33, 0xA1, 0xFC, 0x07, 0x30, 0x6B, 0xC8, 0x3F, 0x08, 0xB3, -0x00, 0xEC, 0x04, 0x10, 0x1B, 0xC8, 0x1F, 0x03, 0xFD, 0x09, 0xCC, 0x82, 0x32, -0x1F, 0xC6, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x08, 0x7F, 0x00, 0xDD, 0x81, 0x74, 0x32, 0xD2, 0xC5, 0x40, 0x07, 0x11, 0xD1, -0x01, 0xF4, 0x07, 0x10, 0x69, 0x48, 0xFF, 0x00, 0x95, 0x03, 0x74, 0x04, 0x10, -0x1D, 0x40, 0x97, 0x01, 0xED, 0x04, 0x44, 0x0E, 0x10, 0x1F, 0x40, 0x0F, 0x60, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0xCD, -0x00, 0x24, 0x03, 0xD0, 0x44, 0x40, 0x37, 0x01, 0xC5, 0x01, 0x14, 0x83, 0x10, -0x28, 0x40, 0x33, 0x0A, 0x01, 0x08, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x93, 0x00, -0xCD, 0x00, 0x14, 0x22, 0x1A, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x35, 0x00, 0xDD, 0x01, 0x74, 0x82, 0xD0, -0x65, 0x40, 0x27, 0x00, 0xD0, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x42, 0x37, 0x08, -0x95, 0x20, 0x74, 0x04, 0x10, 0x1D, 0x42, 0x37, 0x09, 0xDC, 0x00, 0x54, 0x13, -0x10, 0x0D, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xA8, 0x37, 0x00, 0xDF, 0x05, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0xB3, 0x01, -0xD7, 0x21, 0x3C, 0x03, 0x34, 0x1D, 0xC0, 0x37, 0x10, 0x93, 0x80, 0x28, 0x0C, -0x32, 0x1D, 0xC1, 0x57, 0x00, 0xDF, 0x80, 0x5C, 0x86, 0x31, 0x0D, 0xC0, 0x0B, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, -0xFE, 0x00, 0xFC, 0x23, 0xF1, 0x0F, 0xC0, 0xBF, 0x40, 0xFF, 0x00, 0xFC, 0x03, -0xA0, 0x3B, 0xC0, 0x37, 0x04, 0xBF, 0x23, 0xF0, 0x00, 0xF0, 0x0F, 0xC1, 0x1F, -0x00, 0xFF, 0x00, 0x2C, 0x02, 0xF0, 0x0F, 0xC4, 0x1F, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x07, -0x70, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80, 0x7C, 0x43, 0x34, 0x0D, 0xC0, 0x33, -0x42, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0xB7, 0x08, 0xC3, 0x00, 0x4C, -0x43, 0x70, 0x0D, 0xC1, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x13, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xB4, -0x08, 0xDA, 0x01, 0x74, 0x07, 0x00, 0x4D, 0x46, 0xBF, 0x00, 0xB1, 0x00, 0x44, -0x48, 0xD0, 0x2D, 0x40, 0x77, 0x04, 0xD1, 0x00, 0x40, 0x0F, 0x10, 0x3D, 0x40, -0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, -0x00, 0xC1, 0x00, 0x20, 0x02, 0x10, 0x9C, 0x40, 0x60, 0x26, 0xC5, 0x01, 0x24, -0x27, 0x10, 0x08, 0x00, 0xF3, 0x00, 0x89, 0x01, 0x35, 0x44, 0xD0, 0x2C, 0x40, -0x33, 0x00, 0xC5, 0x29, 0x04, 0x2F, 0x90, 0xBC, 0x42, 0x0F, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xE1, 0x01, 0xB6, -0x06, 0x10, 0x14, 0x58, 0x68, 0x10, 0xED, 0x51, 0x34, 0x07, 0x10, 0x1A, 0x42, -0x7B, 0x10, 0x89, 0x01, 0x94, 0x04, 0xD0, 0x1E, 0x40, 0x5B, 0xC2, 0xE5, 0x03, -0x84, 0x06, 0x90, 0x1E, 0x40, 0x77, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00, 0x7E, 0x02, 0x70, 0x04, 0xC0, -0x20, 0x82, 0xC7, 0x80, 0x2C, 0x13, 0x38, 0x0C, 0xE0, 0x33, 0x00, 0x0B, 0x90, -0x1C, 0x30, 0xF0, 0x0C, 0xC0, 0xB7, 0xA0, 0xC7, 0x80, 0x0C, 0x03, 0xF0, 0x0C, -0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, -0x79, 0xC0, 0xFF, 0x00, 0xF4, 0x02, 0xF8, 0x07, 0xC8, 0x2B, 0x08, 0xFB, 0x08, -0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xB7, 0x10, 0xEC, 0xA0, 0xF0, 0x0F, -0xC0, 0x3F, 0x00, 0xFB, 0x01, 0x7E, 0x23, 0x70, 0x1D, 0xC1, 0x0B, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, -0x7C, 0x83, 0xF0, 0x8D, 0x80, 0x27, 0x00, 0xDF, 0x40, 0x7E, 0x83, 0xF0, 0x89, -0x40, 0x37, 0x03, 0x9F, 0x00, 0x6E, 0x00, 0xF0, 0x0D, 0xC0, 0x17, 0x10, 0xD3, -0x00, 0x7E, 0x02, 0xF0, 0x0D, 0xC0, 0x40, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x0E, -0x40, 0x2B, 0x00, 0xED, 0x00, 0xB6, 0x0B, 0xD0, 0x4A, 0x44, 0x3B, 0x02, 0x8D, -0x04, 0x84, 0x80, 0xD0, 0x0E, 0x40, 0x93, 0x01, 0xE1, 0x04, 0xB4, 0x82, 0xD8, -0x4C, 0x40, 0x4D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0x00, 0x79, 0x02, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x60, 0x6B, 0x24, 0xED, -0x01, 0xB4, 0x97, 0xD0, 0x5E, 0x62, 0x7B, 0x18, 0x2D, 0x01, 0xA4, 0xC4, 0xD2, -0x1E, 0x41, 0xFB, 0x00, 0xE1, 0x0D, 0xB4, 0x2F, 0xD1, 0x1E, 0x40, 0x10, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0x4D, -0x07, 0x74, 0x07, 0xD0, 0x38, 0x49, 0xE3, 0x20, 0xCD, 0x05, 0x34, 0x03, 0xD0, -0x1C, 0x40, 0x33, 0x80, 0xCD, 0x00, 0x04, 0x0F, 0xD0, 0x74, 0x40, 0x63, 0x40, -0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0, -0x17, 0xC0, 0xDF, 0x00, 0x7F, 0x04, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, -0x7F, 0x11, 0xAC, 0x05, 0xF0, 0x27, 0xC8, 0xDF, 0x08, 0x53, 0x80, 0x7C, 0x01, -0xF1, 0x04, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x00, 0x87, 0x08, 0x1F, 0x80, 0x78, 0x00, 0xF0, 0x81, 0xC8, 0x87, 0x00, -0x1C, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0x82, 0x02, 0x00, 0x0F, 0x00, 0x7C, 0x10, -0xF0, 0x21, 0xC0, 0x03, 0x00, 0x1F, 0x02, 0x74, 0x00, 0xF0, 0x01, 0xC8, 0x4B, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x02, -0x9F, 0x00, 0x7C, 0x06, 0x30, 0x49, 0xC0, 0x67, 0x04, 0x9F, 0xC8, 0x7C, 0x02, -0x31, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x8A, 0x30, 0x49, 0xC0, 0x67, -0x04, 0x93, 0x08, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x9D, 0x40, 0xF0, 0x06, -0x10, 0x0B, 0x40, 0xA7, 0x02, 0x9D, 0x01, 0xF4, 0x0A, 0x10, 0x9B, 0x40, 0x27, -0x01, 0x9B, 0x80, 0x44, 0x06, 0x10, 0x29, 0x44, 0x2F, 0x00, 0xB1, 0x03, 0x84, -0x02, 0x10, 0x0B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x24, 0x04, 0x9D, 0x80, 0x70, 0x22, 0x10, 0x09, 0x40, 0x27, -0x00, 0x9D, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x44, -0x43, 0x14, 0x29, 0x40, 0x27, 0x02, 0x80, 0x00, 0x44, 0xC2, 0x10, 0x09, 0x40, -0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, -0x18, 0x8D, 0x42, 0x34, 0x0A, 0x14, 0x28, 0x44, 0xB3, 0x00, 0x8D, 0x00, 0x36, -0x02, 0x11, 0x28, 0x40, 0x23, 0x45, 0x89, 0x14, 0x04, 0x02, 0x10, 0x08, 0x40, -0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x7C, -0x04, 0x12, 0x11, 0xC2, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x04, 0x34, 0x11, 0xC0, -0x07, 0x01, 0x13, 0x04, 0x4C, 0x00, 0x32, 0x01, 0xC0, 0x47, 0x40, 0x53, 0x01, -0x4C, 0x04, 0x34, 0x11, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0xFC, 0x8E, 0xF0, 0x3B, 0xC0, -0x7F, 0x20, 0xBE, 0x00, 0x7C, 0x0A, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xF7, 0x00, -0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xEF, 0x00, 0x9C, 0x23, 0xFD, 0x0A, 0xF0, 0x29, -0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, -0x6B, 0x00, 0x93, 0x82, 0xFC, 0x16, 0xF0, 0x7B, 0xC1, 0x2C, 0x00, 0xB3, 0x00, -0xFC, 0x06, 0xF0, 0x7B, 0xC1, 0x6C, 0x01, 0xBE, 0x81, 0xCC, 0x02, 0xF0, 0x0B, -0xD0, 0xEC, 0x01, 0xBF, 0x07, 0xFC, 0x16, 0xF0, 0x1B, 0xC0, 0x60, 0x00, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x87, 0x00, 0x51, 0x05, -0x74, 0x54, 0xD0, 0x31, 0x40, 0x40, 0x05, 0x11, 0x00, 0x74, 0x00, 0xD1, 0x31, -0x44, 0x05, 0x00, 0x1D, 0x0A, 0x44, 0x01, 0xD0, 0x01, 0x40, 0x44, 0x20, 0x1D, -0x03, 0x74, 0x28, 0xD2, 0x01, 0x48, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3, 0x40, 0x85, 0x44, 0x36, 0x0A, 0xD8, 0x49, -0x40, 0x22, 0x00, 0x81, 0x21, 0x34, 0x0A, 0xD1, 0x48, 0x40, 0xA0, 0x00, 0x8D, -0xA0, 0x04, 0x02, 0xD1, 0x08, 0x60, 0xA2, 0x11, 0xCD, 0x06, 0x34, 0x82, 0xD0, -0x28, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0xA8, 0x25, 0x80, 0x95, 0x01, 0x74, 0x82, 0xD0, 0x19, 0x41, 0x22, 0x40, 0x91, -0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, -0x09, 0x41, 0x26, 0x05, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0xB7, -0x00, 0xFC, 0x06, 0xF2, 0x0A, 0xD0, 0xAE, 0x10, 0x93, 0x0B, 0x7C, 0x02, 0xF0, -0x0B, 0xC0, 0x24, 0x20, 0x9F, 0x03, 0x4C, 0x8E, 0xF0, 0x08, 0xC0, 0xEE, 0x00, -0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x08, 0xD0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x0E, 0xF0, -0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x0C, -0x8F, 0x49, 0x7D, 0x12, 0xF1, 0x49, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x52, -0xF0, 0x09, 0x81, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x08, 0x01, 0x01, 0x13, 0x02, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, -0x1B, 0x08, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x17, 0x88, 0x7C, 0x00, -0xF1, 0x21, 0xC0, 0x05, 0x00, 0x1B, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43, -0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00, -0x50, 0x00, 0x74, 0x01, 0x10, 0x05, 0x42, 0x5C, 0x02, 0x51, 0x00, 0xF4, 0x05, -0xD0, 0x15, 0x41, 0x1C, 0x00, 0x51, 0x81, 0xF4, 0x05, 0xD0, 0x07, 0x41, 0x14, -0x04, 0x71, 0x40, 0xF4, 0x0D, 0xD0, 0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xC9, 0x00, 0x34, 0x07, -0x90, 0x9C, 0x40, 0x20, 0x22, 0x89, 0x20, 0x34, 0x06, 0xD0, 0x0D, 0x40, 0xB0, -0x0A, 0x85, 0x01, 0x34, 0x23, 0xD0, 0x08, 0x43, 0x73, 0x00, 0x89, 0x00, 0x34, -0x0E, 0xD0, 0xA8, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0x80, 0xA8, 0x00, 0xE9, 0x04, 0x34, 0x0E, 0x90, 0xCA, 0x50, 0x38, -0x01, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x0E, 0x70, 0x48, 0x00, 0xE1, 0x00, 0xB4, -0x00, 0xD0, 0x02, 0x40, 0x7A, 0x00, 0x61, 0x00, 0xB4, 0x42, 0xD1, 0x0A, 0x60, -0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68, -0x00, 0xEB, 0x07, 0xBC, 0x07, 0xB0, 0x1C, 0xC0, 0xD8, 0x00, 0xEB, 0x01, 0xBC, -0x06, 0xF0, 0x5F, 0xC0, 0x58, 0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF1, 0x16, 0xC2, -0x73, 0x00, 0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x1A, 0xC0, 0x47, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x40, 0xD7, 0x00, 0x7C, -0x02, 0x74, 0x09, 0xC0, 0x17, 0x00, 0xDE, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, -0x03, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x04, 0xC6, 0x35, 0x02, 0x5F, 0x00, -0x7C, 0x02, 0xFA, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x30, 0x1F, 0xC2, -0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1B, 0x41, 0x4D, 0x00, 0xF1, 0x09, -0xCC, 0x06, 0xE0, 0x16, 0xE0, 0x6C, 0x01, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x9B, -0xC2, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, -0xB9, 0x10, 0xE1, 0x10, 0x84, 0x02, 0x12, 0x0B, 0x41, 0x38, 0x20, 0xE1, 0x00, -0xB4, 0x02, 0x10, 0x0A, 0x40, 0x08, 0x01, 0xE1, 0x08, 0x84, 0x00, 0xD1, 0x0E, -0xD0, 0x2C, 0x41, 0x61, 0x00, 0xC4, 0x02, 0x10, 0x8A, 0x40, 0x57, 0x60, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xF9, 0x01, -0x94, 0x03, 0x14, 0x8E, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0x34, 0x03, 0x90, 0x0A, -0x40, 0x08, 0x00, 0xF9, 0x00, 0xA4, 0x00, 0xD0, 0x8E, 0x41, 0x28, 0x13, 0xE1, -0x00, 0xD4, 0x23, 0x90, 0x0A, 0x44, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x28, 0x23, 0x00, 0xC9, 0x02, 0x06, 0x06, 0x10, 0x09, -0x42, 0x10, 0x00, 0xC1, 0x06, 0x34, 0x02, 0x90, 0x08, 0x40, 0x00, 0x00, 0xC9, -0x01, 0x26, 0x4C, 0xD0, 0x0C, 0x42, 0x20, 0x04, 0x41, 0x00, 0x14, 0x81, 0x90, -0x08, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA8, 0x25, 0x00, 0xDB, 0x00, 0x5C, 0x03, 0x30, 0x1D, 0xC0, 0x74, 0x48, 0xD3, -0x13, 0x7C, 0x02, 0xB4, 0x1D, 0xC0, 0x05, 0x00, 0xCB, 0x01, 0x6C, 0x46, 0xF0, -0x1D, 0xE0, 0x74, 0x00, 0xD3, 0x40, 0x1D, 0x06, 0xB0, 0x0D, 0xC0, 0x57, 0x20, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x40, 0xD7, -0x00, 0x7C, 0x22, 0xF0, 0x49, 0xD0, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x0A, 0x70, -0x8D, 0xD0, 0x07, 0x00, 0xD7, 0x0C, 0x5D, 0x00, 0xF0, 0x05, 0xC9, 0x35, 0x02, -0x4F, 0x00, 0x64, 0x22, 0x74, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0xFF, 0x10, 0x4C, 0x0B, 0xF0, -0x0F, 0xC0, 0x5C, 0x00, 0xFF, 0x80, 0xEC, 0x0E, 0xF0, 0x8C, 0xC0, 0x04, 0x00, -0xFF, 0x08, 0xCC, 0x00, 0xF0, 0x87, 0xC0, 0x7E, 0x20, 0xF3, 0x08, 0xCC, 0x02, -0x33, 0x2F, 0xC6, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x81, 0x00, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x87, 0xD0, 0x19, 0xC0, 0xF6, 0x00, -0xCD, 0x09, 0x44, 0x00, 0xD2, 0x19, 0x40, 0x44, 0x04, 0xDC, 0x20, 0x6C, 0x04, -0x90, 0x04, 0x40, 0x21, 0x00, 0xD3, 0x02, 0x44, 0x02, 0x10, 0x19, 0x40, 0x17, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x82, -0xCD, 0x00, 0x44, 0x03, 0xD0, 0x4D, 0x50, 0xB4, 0x02, 0xDD, 0x00, 0x64, 0x03, -0xD8, 0x09, 0x40, 0x44, 0x20, 0xDD, 0x00, 0x44, 0x06, 0xD0, 0x05, 0x44, 0x24, -0x01, 0xD0, 0x10, 0x44, 0x03, 0x10, 0x0D, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, -0xD0, 0x0C, 0x40, 0x12, 0x00, 0xDD, 0x00, 0x04, 0x03, 0xD0, 0x08, 0x40, 0x00, -0x00, 0xCD, 0x00, 0x26, 0x00, 0x90, 0x0D, 0x40, 0x35, 0x40, 0x41, 0x00, 0x05, -0x02, 0x1C, 0x04, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xB0, 0x16, 0x00, 0xFF, 0x40, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x14, -0x20, 0xDF, 0x00, 0x6C, 0x03, 0xD0, 0x0D, 0xC4, 0x04, 0x08, 0xDF, 0x00, 0x4C, -0x00, 0xF0, 0x0D, 0xC0, 0x26, 0x10, 0x53, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC2, -0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, -0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x1D, 0x00, 0xFF, 0x00, 0xFC, -0x01, 0xF0, 0x0B, 0xD0, 0x0F, 0x00, 0xEF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, -0x2F, 0x00, 0x77, 0x40, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x17, 0x22, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x7F, 0x00, 0xEF, 0x09, 0xDC, -0x06, 0xF2, 0x1F, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0xDC, 0x12, 0x30, 0x13, 0xC0, -0x4E, 0x10, 0xB3, 0x00, 0xDC, 0x32, 0x70, 0x2B, 0xC0, 0xBC, 0x00, 0xB3, 0x20, -0xFC, 0x10, 0x30, 0x02, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0xDD, 0x04, 0x44, 0x06, 0x10, 0x1D, 0x40, -0x74, 0x00, 0xD1, 0x01, 0x44, 0x0E, 0x10, 0x11, 0x40, 0x74, 0x00, 0x51, 0x43, -0x44, 0xB2, 0x10, 0xA1, 0x40, 0xBC, 0x03, 0x11, 0x32, 0x74, 0x26, 0x50, 0x11, -0x40, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, -0x33, 0x00, 0xCD, 0x04, 0x14, 0x03, 0x58, 0x0C, 0x40, 0x27, 0x00, 0xD5, 0x00, -0x17, 0x08, 0x10, 0x01, 0x60, 0x06, 0x08, 0x81, 0x28, 0x16, 0x12, 0xD8, 0x40, -0x40, 0x30, 0x00, 0x05, 0x86, 0x34, 0x00, 0x18, 0x08, 0x60, 0x4E, 0x80, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04, -0x54, 0x07, 0x10, 0x0D, 0x46, 0x26, 0x00, 0xD5, 0x11, 0x44, 0x0C, 0x12, 0x11, -0x40, 0x74, 0x00, 0x91, 0x01, 0x44, 0x46, 0x18, 0x10, 0x40, 0x36, 0x00, 0x15, -0x01, 0x74, 0x43, 0x52, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x08, 0xDF, 0x00, 0x1E, 0x06, 0x70, 0xD5, -0xC0, 0xD3, 0x00, 0xC7, 0x03, 0x5C, 0x0C, 0x30, 0x30, 0xC4, 0x52, 0x04, 0x92, -0x07, 0x5D, 0x04, 0x70, 0x39, 0xC0, 0x34, 0x00, 0x97, 0x61, 0x7C, 0x8D, 0x30, -0x39, 0xC0, 0x2A, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0x80, 0x3D, 0x30, 0xFF, 0x01, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x7D, 0x02, 0xFB, -0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6F, 0x20, 0xBC, 0x00, 0xF0, -0x03, 0xD0, 0x3D, 0x00, 0x3B, 0x20, 0xFC, 0x24, 0xF1, 0x0B, 0xC0, 0x1F, 0x00, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xDF, -0x00, 0x5C, 0x03, 0xB0, 0x49, 0xC0, 0xA5, 0x00, 0xDB, 0x02, 0x4C, 0x00, 0xF0, -0x21, 0xC0, 0x17, 0x02, 0xD7, 0x05, 0x6C, 0x02, 0xF1, 0x09, 0xC0, 0x37, 0x44, -0x93, 0x02, 0x6C, 0x0B, 0xF0, 0x29, 0xC4, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x4D, 0x40, 0x0F, 0x15, -0x38, 0x40, 0x24, 0x10, 0x91, 0x00, 0x2C, 0x44, 0xD1, 0xB1, 0x44, 0x54, 0x10, -0xD1, 0x01, 0x74, 0xB2, 0xD2, 0x01, 0x4A, 0xFF, 0x00, 0x90, 0x30, 0x34, 0x83, -0xD1, 0x08, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0xA0, 0x32, 0x00, 0xDD, 0x00, 0x14, 0x26, 0x10, 0x9C, 0x48, 0x31, 0x00, -0xCC, 0x08, 0x25, 0x02, 0xD0, 0x10, 0x40, 0x11, 0x00, 0x85, 0x02, 0x34, 0x00, -0xD0, 0x08, 0x42, 0x36, 0x00, 0x85, 0x25, 0x24, 0x00, 0xD0, 0xB0, 0x41, 0x0D, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, -0xFD, 0x01, 0xC4, 0x1E, 0x18, 0x9F, 0x40, 0x7C, 0x10, 0xF5, 0x41, 0xB4, 0x07, -0xD0, 0x12, 0x00, 0x58, 0x00, 0xA0, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x00, 0x73, -0x04, 0xE5, 0x01, 0xB4, 0x04, 0xD1, 0x16, 0x00, 0x34, 0x20, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x1C, 0x02, -0x30, 0x8C, 0xC0, 0xB1, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0xF0, 0xE0, 0xC3, 0x11, -0x00, 0x87, 0x00, 0x28, 0x01, 0xF0, 0x04, 0xC0, 0x32, 0x30, 0x47, 0x00, 0x2C, -0x03, 0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xA0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x12, 0x70, 0x8E, 0xC0, 0x3B, -0x02, 0xFB, 0x88, 0xEC, 0x23, 0xF0, 0x82, 0xC0, 0x19, 0x00, 0xBB, 0x00, 0xFC, -0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0x7B, 0x40, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, -0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, -0x00, 0x9F, 0x00, 0x3C, 0x06, 0x70, 0x0D, 0xE0, 0x35, 0x00, 0xDF, 0x00, 0x44, -0x01, 0xB2, 0x05, 0xC2, 0x13, 0x00, 0xCB, 0x00, 0x6C, 0x05, 0x72, 0x0D, 0xC2, -0xB7, 0x03, 0xDD, 0x00, 0x6C, 0x00, 0xF0, 0x15, 0x80, 0x40, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x39, 0x10, 0xEC, 0x00, 0xB4, -0x82, 0x10, 0x0E, 0x52, 0x38, 0x00, 0x6D, 0x00, 0x94, 0x03, 0x90, 0x06, 0x40, -0x1B, 0x00, 0xE1, 0x00, 0xC5, 0x01, 0x10, 0x0E, 0x48, 0x3B, 0x05, 0xED, 0x00, -0x84, 0x00, 0x90, 0x0E, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x00, 0x79, 0x20, 0xAC, 0x91, 0xB4, 0x06, 0xD0, 0x1F, 0x48, -0x79, 0x20, 0xFD, 0x01, 0xB4, 0x47, 0x90, 0x1E, 0x60, 0x5B, 0x00, 0xE9, 0x01, -0xA4, 0x07, 0x50, 0x1E, 0x41, 0x7B, 0x00, 0xCD, 0x03, 0xB4, 0x07, 0xD8, 0x14, -0x64, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, -0x33, 0x00, 0xCD, 0x01, 0x34, 0x40, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0xCD, 0x05, -0x34, 0x03, 0x98, 0x24, 0x40, 0x93, 0x08, 0xC1, 0x08, 0x04, 0x03, 0x10, 0x2C, -0x41, 0x33, 0x88, 0xDD, 0x00, 0x14, 0x1F, 0x90, 0x2C, 0x40, 0x58, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x5F, 0x01, -0xFC, 0x09, 0xF0, 0x07, 0x40, 0x1D, 0x00, 0x7F, 0x01, 0xFC, 0x01, 0xB0, 0x77, -0xC0, 0x5B, 0x00, 0x6B, 0x01, 0xEC, 0x29, 0x70, 0x07, 0xC0, 0x17, 0x00, 0x7F, -0x08, 0xFC, 0x01, 0xF0, 0x47, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0xC2, 0x7C, 0x00, 0x00, 0xA1, -0x80, 0x06, 0x01, 0x1C, 0x08, 0x58, 0x00, 0xC3, 0x01, 0x88, 0x07, 0x02, 0x1F, -0x42, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x40, 0x60, 0x20, 0xB0, -0x01, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x12, 0xF9, 0x09, 0xC8, 0x25, 0x00, 0x9F, -0x04, 0x1C, 0x56, 0x31, 0x89, 0xC3, 0x27, 0x04, 0x97, 0x05, 0x40, 0x06, 0xF0, -0x09, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x82, 0xF3, 0x39, 0xC1, 0x43, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, -0x03, 0x74, 0x0A, 0xD8, 0x48, 0x40, 0x24, 0x10, 0x8D, 0x00, 0x44, 0x06, 0x14, -0x19, 0x44, 0xE7, 0x81, 0x9B, 0x12, 0x44, 0x0E, 0xD0, 0x09, 0x40, 0x67, 0x20, -0x9D, 0x0E, 0x44, 0x02, 0x78, 0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x98, -0x09, 0x40, 0x25, 0x00, 0x9D, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x67, 0x00, -0x95, 0x00, 0x54, 0x1A, 0xD0, 0x0D, 0x60, 0x27, 0x00, 0xDD, 0x00, 0x44, 0x02, -0x50, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x00, -0x8D, 0x80, 0x14, 0xD2, 0x50, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x00, 0x10, 0x52, -0xD0, 0x48, 0x61, 0x33, 0x0D, 0x8D, 0x14, 0x14, 0x02, 0x50, 0x48, 0x41, 0x53, -0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x04, 0x00, -0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x80, 0x5C, 0x10, -0x70, 0x01, 0xC0, 0x07, 0x20, 0x14, 0x14, 0x4D, 0x10, 0xF0, 0x41, 0xC0, 0x07, -0x01, 0x1F, 0x04, 0x4D, 0x50, 0x70, 0x41, 0xE2, 0x77, 0xC0, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x00, 0xBF, 0x94, 0xFC, 0x02, -0xC0, 0x0E, 0x40, 0x3F, 0x00, 0xAF, 0x80, 0xEC, 0x02, 0xB0, 0x0B, 0xC0, 0x2F, -0x00, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0x41, 0x27, 0x05, 0xBF, 0x14, 0xEC, -0x02, 0x70, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x79, 0x0A, 0xC0, 0x25, -0x00, 0xBF, 0x00, 0xCC, 0x06, 0xB1, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDD, -0x12, 0xF0, 0x99, 0xC0, 0x6D, 0x03, 0xB9, 0x0D, 0xF8, 0x02, 0x30, 0x0B, 0xC8, -0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, -0x00, 0x1D, 0x41, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x44, -0x28, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x40, 0x44, 0x10, 0xD0, 0xB1, 0x40, -0xC4, 0x03, 0x11, 0x0F, 0x74, 0x00, 0x10, 0x01, 0x50, 0x70, 0x60, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x23, 0x00, 0x8D, 0x04, 0x74, -0x02, 0xD4, 0x08, 0x40, 0x21, 0x20, 0x9D, 0x00, 0x17, 0x02, 0x90, 0x08, 0x40, -0x23, 0x00, 0x9D, 0x00, 0x36, 0x62, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x89, 0x00, -0x34, 0x02, 0x14, 0x08, 0x48, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0x80, 0x74, 0x42, 0x12, 0x09, 0x44, -0x24, 0x00, 0x9D, 0x40, 0x52, 0x46, 0x00, 0x09, 0x41, 0x27, 0x00, 0x9D, 0x00, -0x74, 0x8E, 0xD0, 0x09, 0x61, 0x24, 0x00, 0x91, 0x10, 0x74, 0x02, 0x10, 0x09, -0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, -0x26, 0x00, 0x9D, 0x00, 0x78, 0x0A, 0xF2, 0x08, 0xC0, 0x25, 0x80, 0x9F, 0x04, -0x5C, 0x0A, 0xB2, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x19, 0x7C, 0x02, 0xF0, 0x39, -0xC0, 0x25, 0x20, 0x9A, 0x03, 0x7E, 0x16, 0x20, 0x09, 0xE5, 0x15, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x00, -0x7C, 0x12, 0xF0, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x28, 0x2C, 0x02, 0xF0, 0x09, -0xC0, 0x27, 0x00, 0x9F, 0x90, 0x4C, 0x02, 0xF0, 0x48, 0xC4, 0x27, 0x00, 0x9F, -0x89, 0x7E, 0x22, 0xF2, 0x08, 0xE0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x04, 0x7C, 0x18, 0xB2, 0x41, -0xC0, 0x04, 0x20, 0x1F, 0x06, 0x4C, 0x28, 0xF2, 0x61, 0xC0, 0x05, 0x02, 0x1F, -0x02, 0x6C, 0x08, 0xB0, 0x21, 0xC2, 0x07, 0x00, 0x1F, 0x12, 0x1C, 0x08, 0x30, -0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0xA0, 0x14, 0x00, 0x7D, 0x11, 0xB0, 0x0D, 0x10, 0x17, 0x58, 0x14, 0x00, 0x6D, -0x03, 0x45, 0x05, 0xD0, 0x17, 0x44, 0x9F, 0x02, 0x6D, 0x00, 0xC0, 0x01, 0x10, -0x05, 0x40, 0x9F, 0x02, 0x7D, 0x80, 0x44, 0x01, 0x10, 0x27, 0x00, 0x50, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, -0x00, 0x34, 0x8A, 0x90, 0xAC, 0x04, 0x30, 0x00, 0x45, 0x02, 0x12, 0x06, 0xD1, -0x2C, 0x40, 0x91, 0x00, 0xCD, 0x22, 0x24, 0x17, 0x90, 0x0C, 0x40, 0x37, 0xA2, -0xCD, 0x08, 0x16, 0xA7, 0x10, 0x4C, 0x50, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38, 0x00, 0x6D, 0x00, 0xF4, 0x0A, 0x10, -0x0E, 0x40, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03, 0xD0, 0x0E, 0x61, 0x1B, 0x80, -0xFD, 0x30, 0xA0, 0x47, 0x90, 0x4E, 0x40, 0x3B, 0xA0, 0x6D, 0x01, 0x84, 0x03, -0x50, 0x2C, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xB0, 0x1E, 0xC0, 0x78, 0x20, -0x6F, 0x01, 0x9C, 0x07, 0xF0, 0x1E, 0xE0, 0x59, 0x00, 0xEF, 0x01, 0xE8, 0x07, -0xB0, 0xBE, 0xC0, 0x7B, 0x20, 0xFF, 0x21, 0x1C, 0x07, 0x34, 0x1E, 0xC0, 0x44, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, -0xDF, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0x4F, 0x00, 0x4D, 0x83, -0xF0, 0x0D, 0xE0, 0x17, 0x00, 0xCF, 0x00, 0x5C, 0x03, 0x70, 0x6D, 0xC4, 0x17, -0x08, 0x5E, 0x40, 0x7C, 0x03, 0xB0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x07, -0x30, 0x17, 0xC0, 0x7D, 0x00, 0x7F, 0x01, 0xDC, 0x27, 0xF1, 0x9F, 0xC0, 0x5F, -0x00, 0xEF, 0x01, 0xEC, 0x85, 0xB0, 0x9F, 0x00, 0x5F, 0x02, 0xF3, 0x4D, 0xC8, -0x07, 0x20, 0x1F, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0x18, 0x39, 0x00, 0x6D, 0x42, 0xB4, 0x12, 0x10, 0x0E, 0x40, 0x38, -0x00, 0x29, 0x44, 0x80, 0x03, 0xD0, 0x0E, 0x40, 0x1B, 0x00, 0x6D, 0x02, 0x94, -0x01, 0xD0, 0x0E, 0x43, 0x1A, 0x00, 0xE1, 0x18, 0x84, 0x53, 0x10, 0x07, 0x41, -0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, -0x00, 0xED, 0x00, 0xF4, 0x02, 0x18, 0x2E, 0x50, 0xB9, 0x00, 0x6D, 0xB2, 0x80, -0x43, 0xD0, 0x0E, 0x42, 0x1B, 0x04, 0xED, 0x18, 0x95, 0x01, 0x90, 0x0E, 0x42, -0x3A, 0x30, 0xE1, 0x44, 0xB5, 0x03, 0x1C, 0x0F, 0x40, 0x00, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x34, -0x0A, 0x18, 0x0C, 0x58, 0x31, 0x08, 0x49, 0x01, 0x04, 0x07, 0xD0, 0x08, 0x40, -0xD3, 0x00, 0x4D, 0x03, 0x04, 0x9C, 0xD0, 0x1D, 0x48, 0x02, 0x80, 0x91, 0x01, -0x34, 0x13, 0x10, 0x30, 0x00, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0x9F, 0x00, 0x74, 0x0B, 0x30, 0x2D, 0xC0, -0x31, 0x00, 0xCF, 0x02, 0x4D, 0x23, 0xF2, 0x0D, 0xC0, 0xD7, 0x00, 0xCF, 0x09, -0x5C, 0x1A, 0xB0, 0x3F, 0x40, 0x26, 0x20, 0x91, 0x02, 0x7C, 0x02, 0x30, 0x2D, -0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x37, 0x00, 0x1F, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDB, 0x02, -0x7C, 0x03, 0xF0, 0x6D, 0xC4, 0x17, 0x01, 0xDF, 0x00, 0x74, 0x00, 0xD0, 0x0D, -0xC1, 0x26, 0x00, 0x1F, 0x02, 0x4C, 0x02, 0xF1, 0x4D, 0xC0, 0x07, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x08, 0x3F, 0x00, -0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3D, 0x08, 0x77, 0x00, 0xCC, 0x03, 0xE0, 0x9F, -0xD0, 0x1C, 0x00, 0xF9, 0x00, 0x8D, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F, -0x10, 0x48, 0x82, 0xD0, 0x07, 0xC0, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x1D, 0x03, 0x74, 0x86, 0xD2, 0x3C, -0x41, 0x34, 0x00, 0x51, 0x21, 0x44, 0x03, 0xD0, 0x5C, 0x40, 0x54, 0x08, 0xDD, -0x43, 0x44, 0x4E, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x1D, 0x07, 0x6C, 0xA2, 0xD2, -0x01, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x35, 0x00, 0x55, -0x03, 0x45, 0x07, 0xD2, 0x0D, 0x42, 0x55, 0x04, 0x9D, 0x81, 0x54, 0x06, 0x90, -0x0D, 0x50, 0xC4, 0x00, 0x1D, 0x01, 0x54, 0x03, 0xD0, 0x89, 0x41, 0x07, 0x08, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0x0D, -0x00, 0x34, 0x07, 0xD0, 0x09, 0x40, 0x34, 0x00, 0x51, 0x00, 0x04, 0x03, 0xD0, -0x04, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x04, 0x00, 0x18, 0x0C, 0x40, 0x00, 0x00, -0x1D, 0x00, 0x36, 0x83, 0xD0, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, -0x0D, 0xC0, 0x35, 0x00, 0x57, 0x00, 0x48, 0x03, 0xF0, 0x0D, 0x40, 0x34, 0x10, -0x5B, 0x00, 0x48, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x03, -0xF0, 0x01, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xA0, 0x3F, 0x00, 0xBF, 0x00, 0xB4, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x20, -0x6F, 0x00, 0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x00, 0x7E, 0x00, 0xFC, 0x02, -0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x17, -0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x7F, 0x00, -0xEF, 0x09, 0xCC, 0x27, 0xF2, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xBC, 0x27, -0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xEE, 0x09, 0xCC, 0x07, 0x31, 0x1E, 0xC0, 0x7C, -0x00, 0xF3, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x47, 0x10, 0x1D, 0x44, 0x44, 0x10, -0xD0, 0x11, 0x40, 0x44, 0x00, 0x1D, 0x01, 0x74, 0x00, 0xD2, 0x01, 0x48, 0x47, -0x00, 0x1D, 0x44, 0x44, 0x04, 0x50, 0x11, 0x40, 0x44, 0x00, 0x11, 0x84, 0x74, -0x04, 0x14, 0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x00, 0x14, 0x03, 0xD0, 0x0D, 0x40, 0x30, -0x08, 0xCC, 0x80, 0x36, 0x13, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04, -0x03, 0x11, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x80, 0x74, 0x03, 0x18, 0x0C, 0x40, -0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x05, -0x00, 0x1D, 0x00, 0x54, 0x80, 0xD0, 0x01, 0x40, 0x04, 0x18, 0x1D, 0x00, 0x74, -0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x0D, 0x00, 0x45, 0x00, 0x50, 0x01, 0x40, -0x04, 0x00, 0x11, 0x60, 0x76, 0x00, 0x10, 0x01, 0x40, 0x0C, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x20, 0x5C, -0x03, 0xF2, 0x0D, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, -0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00, -0x3C, 0x83, 0x31, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, -0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0xB0, -0xFC, 0x00, 0xF2, 0x03, 0xD0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03, -0xD1, 0x1F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, -0x35, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80, -0x4C, 0x23, 0x34, 0x8D, 0xC0, 0x74, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D, -0xC0, 0x34, 0x01, 0xD3, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x0D, 0x00, -0x40, 0x40, 0x10, 0x10, 0x50, 0x04, 0x00, 0x1A, 0x05, 0x44, 0x00, 0x10, 0x11, -0xC0, 0x86, 0x00, 0x1D, 0x03, 0x04, 0x04, 0x10, 0x11, 0x40, 0x85, 0x08, 0x11, -0x11, 0x6E, 0x2C, 0xD0, 0x30, 0x40, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x07, 0xA8, 0x72, 0x02, 0xCD, 0x00, 0x06, 0x07, 0x00, 0x9C, -0x40, 0x70, 0x80, 0xC1, 0x01, 0x20, 0x87, 0x10, 0x0C, 0x42, 0x30, 0x04, 0xCD, -0x20, 0x04, 0x23, 0x1A, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x81, 0x24, 0x07, 0xD0, -0x3C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x80, 0x48, 0x02, 0x3D, 0x01, 0x84, 0x04, 0x10, 0x92, 0x40, 0x48, 0x00, 0x39, -0x01, 0xE4, 0x04, 0x10, 0x33, 0x40, 0x4A, 0x20, 0x2D, 0x91, 0x85, 0x14, 0x18, -0x13, 0x41, 0x49, 0x00, 0x21, 0x01, 0xA4, 0x44, 0xD0, 0x12, 0x41, 0x1B, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, -0x80, 0x44, 0x23, 0x34, 0x0C, 0xC0, 0x30, 0x26, 0xC3, 0x00, 0x2D, 0x23, 0x30, -0x0C, 0x40, 0x30, 0x20, 0xCF, 0x44, 0x0E, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x40, -0xD3, 0x08, 0x25, 0x03, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x08, 0x3F, 0x80, 0xFD, 0x00, 0xF0, -0x02, 0xC0, 0x0B, 0x80, 0x2F, 0x00, 0xDC, 0x20, 0xF0, 0x82, 0xE0, 0x0F, 0x02, -0x3F, 0x00, 0xBC, 0x10, 0xF0, 0x03, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0x5E, 0x00, -0xF0, 0x13, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0xA0, 0x33, 0x00, 0xD7, 0x00, 0x7C, 0x83, 0xF0, 0x1D, 0xC0, 0x34, 0x00, -0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xD3, 0x00, 0x1C, 0x03, -0x30, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00, 0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x54, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x20, -0x21, 0x20, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x10, 0x2D, 0x40, 0xB4, 0x00, -0xD0, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0x84, 0x00, 0x52, 0x02, 0x40, 0x0B, -0x00, 0x21, 0x00, 0xB6, 0x00, 0xD1, 0x02, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xE5, 0xC1, 0xB4, 0x07, -0xD8, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x4A, 0x7B, -0x88, 0xE1, 0x01, 0x94, 0x07, 0x94, 0x1E, 0x40, 0x7F, 0x00, 0xE9, 0x01, 0xB4, -0x87, 0xD2, 0x1E, 0x52, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x28, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD9, 0x00, 0x56, 0x00, -0x08, 0x0D, 0x80, 0x76, 0x00, 0xD0, 0x00, 0x44, 0x03, 0x00, 0x01, 0x40, 0x04, -0x00, 0xD0, 0x00, 0x48, 0x03, 0x08, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, -0x48, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x11, -0x00, 0x57, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x10, 0x00, 0x5F, 0x00, 0x7C, -0x01, 0xF0, 0x04, 0xC0, 0x17, 0x40, 0x43, 0x00, 0x1C, 0x01, 0xB4, 0x05, 0xC0, -0x17, 0x00, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x0F, 0x00, 0x3F, 0x00, 0xFC, -0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4, 0x00, 0xF0, 0x03, 0xC4, -0x8F, 0x00, 0x3F, 0x00, 0xFD, 0x08, 0x70, 0x23, 0xC0, 0x8F, 0x40, 0x37, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x09, 0x7C, 0x26, 0x30, 0x19, 0xC0, -0x67, 0x00, 0x93, 0x08, 0x7C, 0x0A, 0x31, 0x19, 0xC8, 0x66, 0x02, 0x9F, 0x80, -0x6C, 0x02, 0x34, 0x09, 0xC0, 0x67, 0x40, 0x92, 0x05, 0x7C, 0x02, 0xF0, 0x09, -0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, -0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x51, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01, -0x74, 0x02, 0x10, 0x89, 0x40, 0x64, 0x01, 0x9D, 0x00, 0x44, 0x12, 0x10, 0x39, -0x48, 0x23, 0x02, 0x91, 0x01, 0x74, 0x0E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x01, 0xB1, 0x80, -0xF4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x01, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, -0x40, 0x2E, 0x20, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x80, 0xB5, -0x00, 0xF4, 0x52, 0xD0, 0x0B, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x20, 0x2C, 0x00, 0xA1, 0x02, 0xF4, 0x0A, 0x50, 0x0A, -0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB4, 0x0A, 0x04, 0x1A, 0x40, 0x2A, 0x00, 0xBD, -0x00, 0x85, 0x02, 0x18, 0x0E, 0x40, 0x2B, 0x00, 0xA5, 0x02, 0xB4, 0x02, 0xD0, -0x0A, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, -0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x13, -0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x0F, 0x40, 0x4C, 0x00, 0x32, -0x01, 0xC2, 0x17, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x77, 0xC0, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x40, 0x9F, -0x01, 0x7C, 0x86, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF2, -0x49, 0x41, 0x25, 0x20, 0x9F, 0x14, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, -0x9B, 0x01, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0, -0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x30, 0x0A, 0xC0, 0x2B, 0x20, -0xAF, 0x42, 0x8D, 0x02, 0x30, 0x0B, 0xC0, 0x28, 0x00, 0xB3, 0x02, 0xCC, 0x02, -0xF0, 0x0A, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x08, 0x07, 0x00, 0x1D, 0x15, 0x44, 0x54, 0xD0, 0x01, 0x48, 0x07, 0x00, -0x1D, 0x00, 0x74, 0x14, 0x10, 0x51, 0x41, 0x07, 0x00, 0x1D, 0x81, 0x44, 0x00, -0x50, 0x01, 0x48, 0x04, 0x10, 0x15, 0x01, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x71, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, -0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x48, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x42, -0x10, 0x08, 0x40, 0x23, 0xA0, 0x8D, 0x00, 0x44, 0x03, 0x10, 0x08, 0x52, 0x20, -0x00, 0xD1, 0x04, 0x04, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, -0xD0, 0x09, 0x40, 0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x44, 0x27, -0x00, 0x8D, 0x00, 0x44, 0x82, 0x50, 0x09, 0x46, 0x24, 0x00, 0x95, 0x00, 0x44, -0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x00, 0xCD, 0x82, 0xF0, 0x09, 0xC0, 0x27, -0x00, 0x9F, 0x00, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, -0x02, 0x30, 0x09, 0xC0, 0x20, 0x08, 0xA3, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0, -0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x02, 0x1F, 0x00, 0x4C, -0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xD0, -0x04, 0x40, 0x13, 0x00, 0x4C, 0x10, 0x30, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00, -0x7C, 0x04, 0x30, 0x01, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D, 0x20, 0x44, 0x01, 0xD1, 0x05, 0x40, -0x17, 0x10, 0x5D, 0x01, 0x70, 0x01, 0xD0, 0x07, 0x40, 0xDC, 0x00, 0x71, 0x81, -0x94, 0x01, 0x50, 0x16, 0x41, 0x1F, 0x00, 0x51, 0x00, 0xF4, 0x05, 0x11, 0x26, -0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, -0x62, 0x00, 0xDD, 0x08, 0x04, 0x07, 0xD0, 0x88, 0x48, 0x33, 0x00, 0x8D, 0x80, -0x74, 0x03, 0x50, 0x04, 0x40, 0xA0, 0x06, 0xC9, 0x11, 0x06, 0x01, 0x10, 0x4C, -0x48, 0x33, 0x0C, 0xC1, 0x80, 0x34, 0x05, 0x90, 0x18, 0x44, 0x50, 0x00, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x08, -0x84, 0x53, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x10, 0xB4, 0x43, 0xD0, 0x1F, -0x40, 0x5C, 0x20, 0xF9, 0x50, 0xD4, 0x80, 0x50, 0x0A, 0x40, 0x1F, 0x20, 0xE1, -0x08, 0xF4, 0x47, 0x91, 0x2B, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xFF, 0x05, 0x8C, 0x07, 0xF0, 0x1E, -0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEB, -0x01, 0x8C, 0x07, 0x30, 0x12, 0xC0, 0x7B, 0x00, 0xA3, 0x81, 0xBC, 0x07, 0xB4, -0x1A, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0xB8, 0x35, 0x10, 0xDF, 0x00, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x37, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x06, 0x00, 0xD7, 0x00, 0x78, 0x02, 0xF0, -0x01, 0xC0, 0x37, 0x00, 0x9D, 0x00, 0x3C, 0x03, 0x70, 0x09, 0xC0, 0x43, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x7F, 0x00, 0xBF, -0x00, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0xE3, 0x01, 0x8C, 0x47, 0x30, -0x17, 0xC0, 0x4F, 0x00, 0x3F, 0x01, 0x9C, 0x04, 0x70, 0x16, 0xC4, 0x5C, 0x00, -0xEF, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x15, 0x98, 0x39, 0x04, 0xAD, 0x0C, 0xB4, 0x02, 0x11, -0x8E, 0x40, 0x3B, 0x10, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x0E, 0x40, 0x0B, 0x10, -0x6D, 0x0A, 0x85, 0x60, 0x55, 0x86, 0xC0, 0x9A, 0x10, 0xED, 0x00, 0x84, 0x03, -0xD0, 0x0A, 0x44, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x39, 0x00, 0xAD, 0x08, 0xF4, 0x02, 0x10, 0x8E, 0x40, 0x3F, 0x04, -0xE1, 0x10, 0xE4, 0x03, 0x10, 0x0E, 0x41, 0x0B, 0x00, 0x2D, 0x10, 0x94, 0x00, -0xD0, 0x07, 0x41, 0x3A, 0x00, 0xBD, 0x0A, 0xA4, 0x03, 0xD0, 0x0A, 0x41, 0x23, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x00, -0x8D, 0x03, 0x74, 0x0A, 0x10, 0x5C, 0x40, 0xE3, 0x00, 0xC1, 0x41, 0x24, 0x0E, -0x10, 0x1D, 0x40, 0x83, 0x02, 0x5D, 0x03, 0x04, 0x04, 0xD0, 0x14, 0x40, 0x72, -0x10, 0x9D, 0x01, 0x24, 0x0B, 0xD1, 0x18, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x89, 0x7C, 0x03, -0x30, 0x2D, 0xC0, 0x77, 0x40, 0xD3, 0x01, 0x6C, 0x46, 0x34, 0x19, 0xC0, 0x83, -0x00, 0x5F, 0x41, 0x1C, 0x08, 0xF0, 0xB1, 0xC0, 0x76, 0x04, 0xDF, 0x11, 0x2C, -0x02, 0xF0, 0x1D, 0xC2, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x08, 0x78, 0x17, 0xF0, 0x8D, 0xC0, 0x37, -0x00, 0xDF, 0x10, 0x5C, 0x02, 0xF0, 0x0D, 0xC1, 0x07, 0x04, 0xDF, 0x00, 0x7C, -0x48, 0x60, 0x01, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x0F, 0xF0, 0x2D, 0xC1, -0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, -0x06, 0xF3, 0x04, 0xFC, 0x0B, 0x30, 0x9F, 0xC8, 0x3F, 0x04, 0xFF, 0x80, 0xCC, -0x56, 0xF0, 0x0F, 0xD0, 0x0C, 0x00, 0x73, 0x10, 0xCC, 0x00, 0xB0, 0x03, 0xC0, -0x2F, 0x04, 0xB2, 0x03, 0xC8, 0x43, 0x30, 0x0F, 0xC0, 0x07, 0x24, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x72, 0x40, 0x91, 0x01, 0x74, -0x06, 0x10, 0x1D, 0x44, 0x37, 0x08, 0xCD, 0x40, 0x44, 0x06, 0xD0, 0x3D, 0x40, -0x44, 0x30, 0xDF, 0xC0, 0x45, 0x04, 0x10, 0x71, 0x44, 0x63, 0x10, 0xD1, 0x01, -0x44, 0x17, 0xB0, 0x0D, 0x40, 0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0x91, 0x80, 0x74, 0x02, 0x10, 0x0D, 0x40, -0x37, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x46, 0x00, 0x11, 0x00, -0x44, 0x0C, 0x9A, 0x15, 0x42, 0x77, 0x00, 0xD5, 0x00, 0x77, 0x07, 0x00, 0x49, -0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x34, 0x00, 0x81, 0x00, 0x34, 0x02, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, -0x06, 0x03, 0xD0, 0x0C, 0x40, 0x44, 0x28, 0x45, 0x00, 0x04, 0x00, 0x10, 0x04, -0x40, 0x33, 0x60, 0x85, 0x00, 0x34, 0x03, 0x90, 0x04, 0x40, 0x43, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x36, 0x00, 0xD3, 0x00, -0x7C, 0x03, 0x10, 0x0D, 0xC0, 0x37, 0x20, 0xDF, 0x00, 0x4D, 0x02, 0xF0, 0x0D, -0xC0, 0x04, 0x00, 0x01, 0x80, 0x4C, 0x00, 0xB4, 0x05, 0xC0, 0x27, 0x00, 0x97, -0x00, 0x7C, 0x03, 0x30, 0x09, 0xC0, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF1, 0x0F, -0xC0, 0x2B, 0x10, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0x80, 0x0F, 0x20, 0x7F, -0x00, 0xFD, 0x00, 0xF0, 0x07, 0xC0, 0x2F, 0x00, 0xBB, 0x40, 0xCC, 0x83, 0xF0, -0x07, 0xC4, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -0xA0, 0x7F, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1B, 0xD0, 0x28, 0x01, 0xA7, -0x01, 0xFC, 0x32, 0x30, 0x1A, 0xC0, 0x3C, 0x00, 0xB3, 0x14, 0xEC, 0x12, 0x30, -0x8B, 0xC0, 0x3D, 0x0C, 0xBF, 0x08, 0xCC, 0x02, 0xF1, 0x0F, 0xC0, 0x0F, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0x9D, -0x01, 0x44, 0x06, 0x10, 0x11, 0x42, 0x64, 0x00, 0x51, 0x01, 0x44, 0x0A, 0x10, -0x19, 0x40, 0xFC, 0x12, 0x91, 0x02, 0x44, 0x3A, 0x10, 0x49, 0x40, 0xBC, 0x00, -0x9D, 0x00, 0x44, 0x2A, 0xD0, 0x0D, 0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xDD, 0x00, 0x44, 0x85, 0x50, -0x04, 0x48, 0x00, 0x82, 0xD5, 0x00, 0x14, 0x18, 0x50, 0x09, 0x40, 0x32, 0x00, -0x85, 0x00, 0x34, 0x40, 0x50, 0x88, 0x42, 0x31, 0x24, 0x09, 0x06, 0x04, 0x00, -0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0xA0, 0x37, 0x00, 0xDD, 0x11, 0x45, 0x05, 0x10, 0x11, 0x44, 0x44, 0x00, -0xD1, 0x03, 0x04, 0x8C, 0x11, 0x89, 0x40, 0x36, 0x80, 0x94, 0x41, 0x14, 0x04, -0x50, 0x19, 0x40, 0x34, 0x00, 0x0D, 0x11, 0x44, 0x0C, 0xD0, 0x0D, 0x20, 0x0F, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, -0xCF, 0x01, 0x0C, 0x04, 0x70, 0x10, 0x40, 0x44, 0x20, 0xC7, 0x03, 0x5C, 0x0E, -0x70, 0x40, 0xD0, 0x32, 0x08, 0x17, 0xA3, 0x7C, 0x96, 0x71, 0x11, 0xC0, 0x35, -0x10, 0x1F, 0x03, 0x4E, 0x0E, 0xF8, 0x0D, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x00, -0xF0, 0x03, 0xC0, 0x2B, 0x00, 0x7F, 0x00, 0x7C, 0x02, 0xF2, 0x0B, 0xC0, 0x3D, -0x60, 0x9B, 0x00, 0xEC, 0x02, 0xB0, 0x00, 0xC0, 0x3F, 0x00, 0xBF, 0xA0, 0xFF, -0x02, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x2A, 0x08, 0x35, 0x00, 0xDF, 0x03, 0x4C, 0x01, 0x30, 0x05, 0xC0, 0x07, -0x24, 0xD3, 0x04, 0x5C, 0x02, 0x30, 0x21, 0xC0, 0x36, 0x01, 0x17, 0x00, 0x5C, -0x82, 0xF0, 0x29, 0xC0, 0x76, 0x04, 0x13, 0x02, 0x7C, 0x06, 0x30, 0x0D, 0xC2, -0xA9, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, -0x08, 0xDC, 0x01, 0x46, 0x05, 0x10, 0x41, 0x48, 0x27, 0x00, 0x51, 0x81, 0x44, -0x02, 0x10, 0x19, 0xC4, 0xBE, 0x00, 0x9B, 0x00, 0x44, 0x02, 0xD1, 0x09, 0x48, -0xBC, 0x00, 0x11, 0x80, 0x74, 0x22, 0x10, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x32, 0x08, 0xCD, 0x00, 0x06, -0x33, 0x10, 0x04, 0x40, 0x23, 0x02, 0x49, 0x02, 0x14, 0x00, 0x10, 0x2C, 0x51, -0x33, 0x00, 0x14, 0x00, 0x10, 0x00, 0xD0, 0x00, 0x40, 0xB2, 0x00, 0x81, 0x80, -0x34, 0x00, 0x11, 0x0C, 0x48, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xFD, 0x01, 0x84, 0x07, 0x11, 0x12, 0x40, -0x7B, 0x10, 0x79, 0x11, 0x94, 0x07, 0x10, 0x1F, 0x41, 0x7B, 0x00, 0x6C, 0x01, -0x94, 0x07, 0xD8, 0x1E, 0x40, 0x70, 0x42, 0xE1, 0x01, 0xB4, 0x07, 0x5C, 0x1E, -0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, -0x32, 0x00, 0xCF, 0x00, 0x04, 0x21, 0x12, 0x84, 0xC0, 0x33, 0x01, 0xCB, 0x00, -0x1C, 0x21, 0x30, 0x4C, 0xC0, 0x33, 0x00, 0xC7, 0xE8, 0x1C, 0x81, 0xF0, 0x24, -0xC0, 0x32, 0x02, 0xC3, 0x00, 0x7C, 0x11, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x00, 0xFF, 0x00, -0xFC, 0x81, 0xF0, 0x83, 0xC0, 0x3F, 0x00, 0xF7, 0x00, 0xEC, 0x03, 0xF0, 0x0F, -0xCC, 0x3A, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0xBF, 0x02, 0xFF, -0x48, 0xFC, 0x01, 0xB0, 0x0F, 0xC0, 0x08, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0xA2, 0x37, 0x20, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x05, -0xC2, 0x13, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0x5F, -0x40, 0x7C, 0x01, 0x70, 0x15, 0xC0, 0x34, 0x01, 0x53, 0x01, 0x4D, 0x01, 0x10, -0x0D, 0xC4, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, -0x98, 0x39, 0x08, 0xED, 0x00, 0x84, 0x01, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x61, -0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3A, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, -0x07, 0x50, 0xBC, 0x00, 0xF1, 0x00, 0xC4, 0x03, 0x10, 0x4E, 0x40, 0x4F, 0x60, -0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xFD, -0x11, 0xA6, 0x05, 0xD0, 0x16, 0x40, 0x5B, 0x04, 0x65, 0x01, 0xB4, 0x05, 0xD0, -0x0A, 0x50, 0x7A, 0x93, 0x6D, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x78, 0x41, -0xE5, 0x03, 0x84, 0x07, 0x10, 0x9E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0x4D, 0x12, 0x06, 0xBD, 0xD0, -0x20, 0x40, 0x33, 0x00, 0x41, 0x01, 0x74, 0x47, 0xD0, 0xEC, 0x40, 0x32, 0x80, -0xCD, 0x0A, 0x34, 0x2B, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xC5, 0x00, 0x04, 0x8B, -0x10, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x17, 0xA8, 0x17, 0x00, 0x6F, 0x02, 0xEC, 0x09, 0xF2, 0x07, 0xC0, 0x1B, 0x0A, -0x77, 0x07, 0xFC, 0x15, 0xF0, 0x06, 0xC0, 0x16, 0x00, 0x7F, 0x21, 0xF4, 0x2D, -0x78, 0x87, 0xC1, 0x14, 0x00, 0x77, 0x00, 0xCC, 0x39, 0x30, 0x05, 0xC0, 0x5F, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, -0x1F, 0x82, 0x7D, 0x00, 0xF3, 0x01, 0x01, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00, -0xC0, 0x21, 0xC0, 0x05, 0x20, 0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, -0x00, 0x19, 0x04, 0x7C, 0x08, 0xF4, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x04, 0x5C, 0x0E, -0xF0, 0x49, 0xC4, 0x24, 0x08, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x99, 0x02, 0x67, -0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x97, 0x80, 0x3C, -0x0E, 0x70, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x78, 0x44, 0x24, -0x10, 0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0x44, 0xA4, 0x08, 0x9D, 0x00, 0x74, -0x82, 0xD1, 0x09, 0x40, 0x67, 0x00, 0x91, 0x80, 0x74, 0x06, 0x10, 0x09, 0x40, -0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, -0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x0D, 0x44, 0x34, 0x20, 0x99, 0x08, 0x44, -0x02, 0x10, 0x09, 0x60, 0x27, 0x04, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, -0x27, 0x01, 0x95, 0x00, 0x74, 0x42, 0x50, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x04, -0x02, 0xD0, 0x09, 0x48, 0x20, 0x05, 0x81, 0x00, 0x04, 0x52, 0x10, 0x0C, 0x40, -0x21, 0x15, 0x8D, 0x14, 0x34, 0x52, 0xD0, 0x48, 0x41, 0x33, 0x05, 0x81, 0x14, -0x34, 0x52, 0x10, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, -0x04, 0x01, 0x1B, 0x00, 0x4C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x21, 0x1F, 0x06, -0x7C, 0x10, 0xF0, 0x41, 0xC8, 0x07, 0x01, 0x17, 0x04, 0x7C, 0x10, 0x70, 0x01, -0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, -0x27, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2, 0x0B, 0xD0, 0x2F, 0x00, 0xBF, 0x00, -0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x26, 0x00, 0xBF, 0x10, 0xFC, 0x52, 0xF0, 0x4B, -0xC1, 0x27, 0x05, 0xBF, 0x14, 0xFC, 0x52, 0xF0, 0x69, 0xC3, 0x67, 0x20, 0x0E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x25, 0x00, 0xBF, 0x00, -0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x6F, 0x60, 0xB3, 0x00, 0x7C, 0x26, 0xF0, 0x0A, -0xC0, 0x2D, 0x00, 0x93, 0x02, 0x7C, 0x52, 0x30, 0x39, 0xC1, 0xAF, 0x00, 0x9F, -0x09, 0xCC, 0x06, 0xF0, 0x5B, 0xE0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x5D, 0x00, 0x44, 0x00, 0xD0, 0x01, -0x40, 0x07, 0x00, 0x11, 0x00, 0x74, 0x2C, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x11, -0x01, 0x74, 0x18, 0x10, 0x21, 0x40, 0x47, 0x09, 0x1D, 0x0B, 0x44, 0x00, 0xD0, -0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x20, 0x21, 0x00, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85, -0x01, 0x34, 0x12, 0xD0, 0x09, 0x40, 0xA3, 0x80, 0x81, 0x26, 0x34, 0x42, 0x14, -0x08, 0x40, 0xA3, 0x00, 0x8D, 0x04, 0x04, 0x0A, 0xD0, 0x68, 0x41, 0x4B, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, -0x00, 0x46, 0x06, 0xD3, 0x19, 0x40, 0x27, 0x04, 0x95, 0x04, 0x76, 0x12, 0xD2, -0x49, 0x40, 0x24, 0xC0, 0x91, 0x02, 0x74, 0x82, 0x00, 0x09, 0x41, 0x27, 0x00, -0x9D, 0x02, 0x44, 0x02, 0xD2, 0x09, 0x48, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x8F, 0x02, 0x44, 0x16, 0xF2, -0x39, 0xC1, 0xA7, 0x00, 0x97, 0x02, 0x7C, 0x16, 0xF2, 0x09, 0xC0, 0x25, 0x00, -0x93, 0xC2, 0x7C, 0x12, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x4D, 0x6E, -0xD8, 0x09, 0x48, 0x17, 0x28, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x80, 0x25, 0x00, 0x9F, 0x02, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x63, 0x02, -0x9B, 0xA0, 0x7C, 0x02, 0xF1, 0x19, 0xC0, 0x27, 0x20, 0x9F, 0x05, 0x7C, 0x16, -0xF0, 0x59, 0xC0, 0x27, 0x00, 0x8F, 0x01, 0x7C, 0x46, 0xF0, 0x09, 0xC0, 0x4B, -0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, -0x1F, 0x04, 0x6C, 0x08, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x08, -0xF0, 0x01, 0xD0, 0x00, 0x00, 0x17, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC2, 0x04, -0x04, 0x1F, 0x02, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x7D, 0x02, 0xC4, 0x45, -0xC2, 0x07, 0x00, 0x1F, 0x20, 0x7D, 0x21, 0x7C, 0x01, 0xD0, 0x16, 0x58, 0x1C, -0x00, 0x5D, 0x00, 0x74, 0x01, 0xD1, 0x05, 0xC0, 0x1E, 0x04, 0x5D, 0x00, 0xC4, -0x89, 0x10, 0x05, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0xA0, 0x32, 0x00, 0x8D, 0x8B, 0x24, 0x06, 0xC8, 0xCC, 0x00, 0x53, -0x04, 0x0C, 0x05, 0x34, 0x03, 0xD1, 0xD4, 0x40, 0x40, 0x00, 0xC5, 0x00, 0x74, -0x03, 0xD0, 0x0C, 0x60, 0x72, 0x00, 0xCD, 0x00, 0x04, 0x0B, 0x15, 0x8C, 0x40, -0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38, -0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0xBB, 0x80, 0x2D, 0x82, 0x94, -0x03, 0xD0, 0x07, 0x40, 0x88, 0x00, 0xED, 0x24, 0xB4, 0x23, 0xD0, 0x1F, 0x40, -0x3A, 0x00, 0xFD, 0x80, 0x04, 0x07, 0x12, 0x1E, 0x40, 0x04, 0x20, 0x02, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x00, 0xAF, 0x01, 0xAC, -0x06, 0xF0, 0x1A, 0xC8, 0x5B, 0x00, 0x2F, 0x01, 0xB0, 0x07, 0xF0, 0x12, 0xCA, -0x78, 0x00, 0xE7, 0xA3, 0xBC, 0x87, 0xF0, 0x7F, 0xC4, 0x5A, 0x00, 0xFF, 0x0F, -0x89, 0x07, 0x32, 0x1F, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x5C, 0x00, 0xF0, 0x09, 0xC0, -0x37, 0x00, 0x1F, 0x80, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x17, 0x10, 0xDF, 0x00, -0x7C, 0x0B, 0xF0, 0x2D, 0xC4, 0x37, 0x00, 0xDF, 0xA4, 0x7C, 0x02, 0xF0, 0x0D, -0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -0x7D, 0x00, 0xBF, 0x01, 0xCC, 0x26, 0xF0, 0x9B, 0xC0, 0x6F, 0x02, 0x33, 0x09, -0xDC, 0xEF, 0x73, 0x17, 0xC8, 0x5C, 0x22, 0xFD, 0x09, 0xFC, 0x0F, 0xF1, 0x3F, -0xC0, 0x7F, 0x02, 0xF7, 0x81, 0xDC, 0x05, 0x10, 0x9B, 0xC0, 0x00, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0xAD, 0x48, -0x85, 0x22, 0xD0, 0x0A, 0x00, 0x3B, 0x00, 0x21, 0xC0, 0x84, 0xE3, 0x10, 0x86, -0x41, 0x98, 0x00, 0xED, 0x18, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE1, -0x00, 0xF4, 0x11, 0x12, 0xCB, 0x40, 0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x2D, 0x10, 0x84, 0x2A, 0xD8, 0x0A, -0x61, 0x2B, 0x60, 0x31, 0x50, 0x94, 0x23, 0x51, 0x06, 0x50, 0x3A, 0x98, 0xED, -0x08, 0xB4, 0x23, 0xD0, 0x0E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x94, 0x43, 0x99, -0x0F, 0x44, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, -0x20, 0x31, 0x00, 0x0D, 0x47, 0x04, 0x00, 0xD8, 0x58, 0x40, 0xB3, 0x02, 0x01, -0x53, 0x04, 0x07, 0x58, 0x34, 0x40, 0x12, 0x80, 0xCD, 0x41, 0x24, 0x33, 0xD0, -0x3C, 0x40, 0x23, 0x50, 0xC1, 0x42, 0x34, 0x46, 0x98, 0x0C, 0x40, 0x11, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0x9D, -0x00, 0x4C, 0x02, 0xD0, 0x19, 0xC0, 0x93, 0x40, 0x13, 0x01, 0xDC, 0x0B, 0x70, -0x05, 0xC0, 0x06, 0x00, 0xFF, 0x03, 0xFC, 0x0B, 0xF8, 0x3F, 0xC4, 0x27, 0x00, -0xF3, 0x0F, 0x5C, 0x02, 0xB4, 0x0D, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0, -0x09, 0xC0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13, 0x90, 0x45, 0xC0, 0x05, 0x00, -0xDF, 0x10, 0x74, 0x03, 0xF0, 0x4D, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x00, -0x70, 0x0D, 0x88, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x84, 0x08, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xC0, 0x03, 0xC8, 0x1F, 0x00, -0x3B, 0x02, 0x7C, 0x03, 0xF0, 0x07, 0xC0, 0x18, 0x00, 0xFA, 0x00, 0xAC, 0x03, -0xB0, 0x0F, 0xC8, 0x06, 0x10, 0xEF, 0x00, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x13, -0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, -0x9D, 0x01, 0x74, 0x05, 0xD0, 0x11, 0x40, 0x37, 0x00, 0xD1, 0x83, 0x74, 0x03, -0xD0, 0x14, 0x40, 0x94, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xC4, -0x04, 0xDD, 0x00, 0x44, 0x1C, 0xD2, 0x0D, 0x42, 0x17, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x06, -0xD0, 0x69, 0x40, 0x27, 0x00, 0x19, 0x10, 0x74, 0x03, 0xD0, 0x35, 0x60, 0x14, -0x00, 0xD5, 0x00, 0x64, 0x03, 0xD0, 0x0C, 0x60, 0x65, 0x00, 0xDD, 0x20, 0x54, -0x04, 0xD8, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x28, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33, -0x00, 0x00, 0x20, 0x34, 0x83, 0xD0, 0x05, 0x40, 0x10, 0x00, 0xC5, 0x00, 0x34, -0x03, 0x10, 0x0C, 0x60, 0x20, 0x00, 0xCD, 0x00, 0x06, 0x00, 0xD8, 0x08, 0x40, -0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, -0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x20, 0xFC, -0x03, 0xF2, 0x05, 0xD0, 0x14, 0x10, 0xD7, 0x00, 0xEC, 0x03, 0xB0, 0x0F, 0xC0, -0x04, 0x10, 0xFF, 0x20, 0x5C, 0x02, 0xF0, 0x0D, 0xC8, 0x03, 0xC0, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x3F, 0x00, 0x2F, 0x00, 0xFC, -0x80, 0xF1, 0x0B, 0xC0, 0x3B, 0x00, 0x2F, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, -0x1F, 0x20, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x20, 0xFF, 0x00, -0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xA0, 0x5F, 0x40, 0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x17, 0xC0, -0x7F, 0x00, 0x73, 0x81, 0xFC, 0x10, 0xF1, 0xC3, 0xC0, 0x2C, 0x02, 0x33, 0x81, -0xCC, 0x23, 0x30, 0x0F, 0xC0, 0x48, 0x10, 0xBF, 0x20, 0xFC, 0x05, 0x30, 0x1F, -0xC0, 0x0C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, -0x77, 0x08, 0x91, 0x4B, 0x74, 0x2E, 0xD2, 0x19, 0x00, 0x7F, 0x00, 0x51, 0x01, -0x74, 0x2C, 0xD0, 0xE1, 0x40, 0xA4, 0x01, 0x11, 0x01, 0xC4, 0x1B, 0x51, 0xBB, -0x48, 0x64, 0x00, 0x8D, 0x4E, 0x74, 0x07, 0x10, 0x0F, 0x48, 0x04, 0x60, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x81, 0x40, -0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x00, 0xD0, 0x09, -0x40, 0xA0, 0x80, 0x15, 0x00, 0x04, 0x1B, 0x10, 0x0C, 0x40, 0x00, 0x00, 0x8D, -0x10, 0x34, 0x82, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x20, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x0D, -0x40, 0x37, 0x00, 0x91, 0x82, 0x74, 0x04, 0xD0, 0x09, 0x48, 0x25, 0x84, 0x11, -0x01, 0x45, 0x07, 0x53, 0x89, 0x40, 0x64, 0x00, 0x9D, 0x40, 0x34, 0x43, 0x10, -0x0D, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x88, 0x23, 0x00, 0xD3, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0x44, 0x33, 0x40, 0xD3, -0x00, 0x7C, 0x0C, 0xF0, 0x88, 0xC0, 0x64, 0x40, 0x13, 0x81, 0x4C, 0x05, 0x30, -0x1D, 0x90, 0x44, 0x00, 0x9E, 0x40, 0x7C, 0x2D, 0x34, 0x0D, 0xC0, 0x00, 0x20, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0xAD, 0x00, 0xBF, -0x81, 0xFC, 0x13, 0xD0, 0x4B, 0x48, 0x3F, 0x00, 0xFF, 0x09, 0x7C, 0x00, 0xF0, -0x1B, 0xC0, 0x6E, 0x2A, 0x3E, 0x10, 0xBC, 0x83, 0xF0, 0x09, 0xC4, 0x2F, 0x28, -0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x02, 0xD3, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x37, 0x02, 0x93, 0x02, 0x7C, 0x00, 0x34, 0x09, 0xE0, 0x24, 0x20, -0x1B, 0x01, 0x7C, 0x03, 0x30, 0x0D, 0xC8, 0x04, 0x44, 0xD3, 0x00, 0x4C, 0x02, -0xF0, 0x0D, 0xC5, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x02, -0x95, 0x00, 0x74, 0x04, 0x10, 0x0B, 0x42, 0x64, 0x04, 0x01, 0x03, 0x5C, 0xAF, -0x51, 0x18, 0xC0, 0xE6, 0x18, 0xD1, 0x01, 0x6C, 0x03, 0xD0, 0x6D, 0x40, 0x4C, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x12, 0x04, -0x81, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x10, -0x12, 0x00, 0x01, 0x64, 0x88, 0x09, 0x00, 0x34, 0x0F, 0x51, 0xBC, 0x41, 0x81, -0x10, 0x85, 0x11, 0x04, 0x82, 0xD2, 0x2D, 0x42, 0x1C, 0x00, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x82, 0xA1, 0x21, 0xB4, 0x16, -0xD0, 0x1A, 0x40, 0x73, 0x08, 0xA5, 0x01, 0xB4, 0x04, 0x18, 0x92, 0x40, 0x68, -0x08, 0x29, 0x01, 0x14, 0x27, 0x52, 0x1E, 0x64, 0x6F, 0x00, 0xA5, 0x29, 0xA4, -0x06, 0xD0, 0x1E, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x10, 0x20, 0x00, 0xC3, 0x08, 0x3C, 0x02, 0xF0, 0x08, 0x42, 0x33, -0x02, 0x83, 0x00, 0x34, 0x48, 0x30, 0x08, 0x40, 0x20, 0x01, 0x0B, 0x00, 0x3C, -0x43, 0x70, 0x0C, 0xC0, 0x01, 0x04, 0x87, 0x50, 0x0A, 0x02, 0xF0, 0x0D, 0xC0, -0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x29, -0x40, 0xFF, 0x08, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x7D, 0x08, 0xBF, 0x00, 0xFC, -0x00, 0xD0, 0x0E, 0x52, 0x2B, 0x00, 0x37, 0x00, 0xFC, 0x0B, 0xF0, 0x0F, 0xE0, -0x3E, 0x10, 0x9B, 0x00, 0xFC, 0x22, 0xF0, 0x1F, 0xC0, 0x0B, 0x60, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x77, 0x00, 0x93, 0x00, 0x7C, -0x23, 0x30, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0xFC, 0x00, 0xF0, 0x09, 0xC0, -0x06, 0x10, 0x93, 0x80, 0x3C, 0x08, 0x34, 0x4D, 0xE1, 0x07, 0x08, 0x9F, 0x01, -0x4C, 0x02, 0xF0, 0x0D, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xA1, 0x04, 0xB4, 0x13, 0x10, 0x0A, 0x40, -0xBB, 0x28, 0xEC, 0x20, 0xB4, 0x82, 0xD0, 0x6E, 0x48, 0x08, 0x00, 0xA1, 0x00, -0xB4, 0x02, 0x50, 0x0E, 0x4A, 0x3B, 0x00, 0xBD, 0x40, 0xBC, 0x02, 0xD0, 0x4E, -0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -0xED, 0x00, 0xE9, 0x09, 0x34, 0x0F, 0x10, 0x1A, 0x40, 0x7B, 0x01, 0xAD, 0x01, -0xB4, 0x04, 0xD0, 0x18, 0x40, 0x48, 0x00, 0xA1, 0x01, 0xB4, 0x07, 0x90, 0x1E, -0x40, 0x6B, 0x10, 0xED, 0x01, 0xA4, 0x06, 0xD0, 0x9E, 0x50, 0x0C, 0x00, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0xE3, 0x00, 0xC9, 0x88, -0x34, 0x07, 0x10, 0x28, 0x41, 0x33, 0x00, 0x8D, 0x23, 0x34, 0x07, 0xD0, 0x0D, -0x40, 0x14, 0x02, 0xC1, 0x01, 0x34, 0xCB, 0xD0, 0x0C, 0x40, 0x73, 0x04, 0xCD, -0x00, 0x34, 0x02, 0xD0, 0x0D, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x17, 0xA8, 0xDD, 0x20, 0x5B, 0x21, 0x7C, 0x05, 0x34, 0x07, -0xC0, 0x17, 0x00, 0x7F, 0x03, 0xFC, 0x01, 0xF1, 0x07, 0xC0, 0x5C, 0x40, 0x73, -0x05, 0xBC, 0x1D, 0xB0, 0x05, 0xC4, 0xDF, 0x21, 0x5F, 0x00, 0xEC, 0x01, 0xF0, -0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, -0x00, 0x87, 0x41, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, -0x08, 0x6C, 0x30, 0xF0, 0x31, 0xD0, 0x45, 0x00, 0x1F, 0x01, 0x7C, 0x00, 0x70, -0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x21, 0xC8, 0x4B, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x8F, -0x80, 0x4C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x10, 0x4C, 0x02, 0xF0, -0x09, 0xC0, 0x66, 0x01, 0x9B, 0x01, 0x4C, 0x02, 0xB0, 0x19, 0xC0, 0x27, 0x00, -0x9F, 0x04, 0x7C, 0x82, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x01, 0xBD, 0x00, 0x85, 0x02, 0x10, -0x08, 0xC0, 0x2C, 0x00, 0x9D, 0x00, 0x54, 0x0A, 0xD2, 0x29, 0x40, 0xE4, 0x20, -0x81, 0x4F, 0x54, 0x02, 0xB0, 0xD9, 0x46, 0xA7, 0x1E, 0x9D, 0x00, 0x34, 0x02, -0x10, 0x6B, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0xA0, 0x24, 0x80, 0x9D, 0x00, 0x44, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00, -0x8D, 0x00, 0x40, 0x2A, 0xD0, 0x19, 0x60, 0x26, 0x00, 0xD1, 0x20, 0x44, 0x2A, -0x80, 0x09, 0x20, 0x37, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x60, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x10, -0x8D, 0x02, 0x04, 0x02, 0x10, 0x29, 0x40, 0x20, 0x00, 0x8D, 0x02, 0x14, 0x52, -0xD0, 0x48, 0x41, 0x20, 0x0D, 0x91, 0x20, 0x54, 0x52, 0x98, 0x48, 0x49, 0x23, -0x00, 0x8D, 0x95, 0x76, 0x0A, 0x10, 0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x01, 0x4C, 0x84, -0x30, 0x01, 0xD0, 0x44, 0x00, 0x1D, 0x00, 0x4C, 0x10, 0xF0, 0x45, 0xD0, 0x12, -0x01, 0x13, 0x00, 0x4C, 0x90, 0xB0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x24, 0x7C, -0x00, 0x34, 0x10, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x19, 0xB8, 0x3B, 0x10, 0xBF, 0x03, 0xFC, 0x0A, 0xC0, 0x1F, 0xC0, 0xA5, -0x00, 0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x4B, 0xC3, 0x2F, 0x45, 0xBF, 0x00, 0xFC, -0x52, 0x80, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x06, 0xF0, 0x69, 0xC1, -0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, -0x00, 0x9F, 0x07, 0xCC, 0x86, 0x34, 0x29, 0xC0, 0x6C, 0x04, 0x8F, 0x00, 0xFC, -0x06, 0xF0, 0x5F, 0xC0, 0x6C, 0x05, 0xBB, 0x40, 0xCC, 0x06, 0x30, 0x1B, 0xC2, -0x2C, 0x08, 0xF3, 0x05, 0x4C, 0x0A, 0xF0, 0x7B, 0xC0, 0x64, 0x00, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x01, 0x44, -0x80, 0x10, 0x11, 0x50, 0x84, 0x00, 0x1D, 0x21, 0x74, 0x20, 0xD0, 0x50, 0xC1, -0x42, 0x01, 0x11, 0x00, 0x44, 0x6D, 0x50, 0x01, 0x50, 0x04, 0x00, 0x01, 0x55, -0x44, 0x05, 0xD0, 0x61, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x02, 0x05, 0x0A, 0x10, 0x08, 0x40, -0x22, 0x00, 0x8D, 0x14, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x05, 0x85, 0x00, -0x05, 0x92, 0x58, 0x88, 0x40, 0x60, 0x40, 0x81, 0x08, 0x04, 0x82, 0xD0, 0x88, -0x40, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, -0x25, 0x80, 0x8D, 0x01, 0x44, 0x12, 0x10, 0x08, 0x40, 0x26, 0x00, 0x9D, 0x80, -0x74, 0x22, 0xD0, 0x09, 0x50, 0x26, 0x20, 0x95, 0x08, 0x04, 0x02, 0x58, 0x09, -0x40, 0x34, 0x02, 0x91, 0x00, 0x45, 0x22, 0xD0, 0x09, 0x40, 0x62, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0xBF, 0x80, -0x4C, 0x06, 0x30, 0x1B, 0xC0, 0x26, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x49, -0xC0, 0x64, 0x00, 0x97, 0x00, 0x4C, 0x86, 0x72, 0x09, 0xCA, 0x64, 0x20, 0x93, -0x21, 0xCC, 0x0E, 0xF0, 0x09, 0xD0, 0x16, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x02, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x49, -0xC0, 0x25, 0x04, 0x9F, 0x03, 0x7C, 0x06, 0xF0, 0x58, 0xD0, 0x27, 0x02, 0x93, -0x20, 0x7C, 0x22, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x8F, 0x09, 0x7C, 0x02, 0xD0, -0x09, 0xC0, 0x51, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, -0x08, 0x05, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x40, 0x13, -0x02, 0x4D, 0x00, 0x32, 0x21, 0xF0, 0x00, 0x00, 0x13, 0x44, 0x4C, 0x20, 0x34, -0x41, 0xC0, 0x04, 0x0A, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x81, 0xC6, 0x50, 0x20, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x5C, 0x00, 0x51, -0x00, 0xB4, 0x01, 0xD0, 0x05, 0x40, 0x1F, 0x80, 0x51, 0x00, 0xC4, 0x09, 0x50, -0x27, 0x50, 0x1D, 0x00, 0x61, 0xD2, 0xC4, 0x05, 0x20, 0x07, 0x40, 0x18, 0x00, -0x75, 0x08, 0x6C, 0x01, 0xD0, 0x17, 0xD0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x62, 0x00, 0xC9, 0x00, 0x34, 0x02, 0xD0, -0x0C, 0x40, 0x23, 0x08, 0xC1, 0x00, 0x04, 0x4A, 0x10, 0x3C, 0x49, 0x30, 0x00, -0xC0, 0x01, 0x05, 0x17, 0x19, 0x28, 0x40, 0x30, 0x84, 0xC1, 0x01, 0x04, 0x03, -0xD0, 0x19, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0x80, 0xFC, 0x00, 0xE9, 0x04, 0xB4, 0x42, 0xD0, 0x4E, 0x40, 0xFB, 0x00, -0xF5, 0x25, 0x84, 0x46, 0x50, 0x6E, 0x68, 0x69, 0x21, 0x21, 0x20, 0x84, 0x01, -0x18, 0x06, 0x41, 0x38, 0x00, 0xE5, 0x10, 0xA6, 0x13, 0xD0, 0x0E, 0x40, 0x12, -0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00, -0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x3E, 0xC0, 0x6B, 0x00, 0xE1, 0x03, 0x8C, 0x06, -0x32, 0x72, 0x40, 0x28, 0x41, 0x23, 0x01, 0x84, 0x07, 0x32, 0x10, 0xC0, 0x78, -0x00, 0xE3, 0x01, 0x8C, 0x0F, 0xF0, 0x10, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x31, 0x40, 0xD7, 0x00, 0x7C, 0x02, -0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xDB, 0x00, 0x3C, 0x02, 0xF0, 0x01, 0xD8, 0x27, -0x02, 0x0F, 0x20, 0x3C, 0x00, 0xF0, 0x01, 0xD2, 0x33, 0x10, 0x5F, 0x12, 0x7C, -0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0x6F, 0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x6C, -0x00, 0xEF, 0x01, 0xCC, 0x07, 0x32, 0x1F, 0xC0, 0x78, 0x10, 0x23, 0x01, 0x8C, -0x05, 0x30, 0x13, 0xC0, 0x7F, 0x08, 0x7F, 0x01, 0xBC, 0x07, 0x30, 0x1F, 0xC0, -0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, -0x00, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0xA8, 0x00, 0xED, 0x08, 0x84, -0x03, 0xB0, 0x2F, 0x40, 0x28, 0x01, 0x21, 0x80, 0x94, 0x00, 0x52, 0x02, 0x40, -0x3B, 0x0A, 0x6D, 0x04, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x01, 0x84, -0x03, 0xD0, 0x1F, 0x40, 0x28, 0x00, 0xFD, 0x01, 0x84, 0x22, 0x10, 0x8E, 0x40, -0x2C, 0x10, 0x39, 0x08, 0x84, 0x03, 0x10, 0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00, -0xF4, 0x07, 0x10, 0x06, 0x40, 0x63, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x04, 0x28, 0x23, 0x01, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0C, 0x41, -0x20, 0x00, 0xCD, 0x00, 0x06, 0x45, 0x90, 0x1C, 0x40, 0x20, 0x00, 0x09, 0x01, -0x16, 0x19, 0x50, 0x90, 0x40, 0xB3, 0x00, 0x5D, 0x00, 0x34, 0x6F, 0x10, 0x0C, -0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, -0xA5, 0x00, 0xDF, 0x04, 0x4C, 0x12, 0xF0, 0x0D, 0xD0, 0x24, 0x00, 0xDF, 0x00, -0x4D, 0x12, 0x30, 0x1B, 0xC0, 0x3C, 0x41, 0x1B, 0x05, 0x4C, 0x01, 0x34, 0x01, -0xC0, 0x47, 0x12, 0x9F, 0x00, 0x7C, 0x0F, 0x36, 0x01, 0xC8, 0x57, 0x20, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x40, -0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x80, -0xC0, 0xA7, 0x00, 0x17, 0x40, 0x7C, 0x08, 0xF1, 0x00, 0xC0, 0xD7, 0x00, 0x1F, -0x40, 0x7C, 0x03, 0xF0, 0x0D, 0xCC, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x00, 0xEF, 0x00, 0x8C, 0x0E, 0x30, 0x0F, -0xC0, 0x2C, 0x00, 0xF3, 0x00, 0xCC, 0x02, 0xF0, 0x33, 0xC4, 0x0C, 0x00, 0x33, -0x00, 0xBC, 0x09, 0x30, 0x03, 0xC0, 0x1C, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30, -0x0B, 0xD0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, -0x20, 0xD6, 0x10, 0xDD, 0x40, 0x44, 0x4A, 0x10, 0x0D, 0x40, 0xF5, 0x50, 0xD1, -0x00, 0x44, 0x02, 0xD0, 0x31, 0x42, 0x01, 0x08, 0x11, 0x23, 0x74, 0x0D, 0x10, -0x51, 0xC0, 0xB6, 0x00, 0x1D, 0x61, 0x44, 0x03, 0x11, 0x2D, 0x40, 0x04, 0x02, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD, -0x00, 0x44, 0x02, 0x10, 0x0C, 0x40, 0x24, 0x02, 0xC1, 0x20, 0x44, 0x03, 0xD0, -0x0D, 0x40, 0xB4, 0x90, 0x19, 0x51, 0x74, 0x09, 0x10, 0x11, 0x00, 0x14, 0x02, -0x1D, 0x03, 0x05, 0x83, 0x10, 0x24, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0x14, -0x0C, 0x40, 0x11, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x04, 0x40, 0x25, 0x00, -0x01, 0x00, 0x34, 0x01, 0x14, 0x00, 0x60, 0x32, 0x00, 0x1D, 0x00, 0x04, 0x03, -0x10, 0x0C, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xB0, 0x26, 0x00, 0xEF, 0x00, 0x4D, 0x01, 0x30, 0x0F, 0xC0, 0x24, 0x00, -0xF3, 0x00, 0x45, 0x02, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x01, -0x30, 0x01, 0xC0, 0x14, 0x00, 0x3F, 0x00, 0xCC, 0x03, 0x34, 0x0D, 0xC8, 0x04, -0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, -0xFF, 0x00, 0xFC, 0x81, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xBC, 0x01, -0xE2, 0x07, 0x98, 0x0F, 0x40, 0x3F, 0x40, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x3F, -0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFB, 0x10, 0x9C, 0x07, -0xF0, 0x1F, 0xC0, 0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x05, 0xF0, 0x17, 0xC8, 0x2E, -0x10, 0xBF, 0x04, 0xFC, 0x03, 0x30, 0x1F, 0xC0, 0x7F, 0x08, 0xB6, 0x00, 0xFC, -0x27, 0x70, 0x02, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x08, 0x77, 0x00, 0xFD, 0x03, 0x44, 0x06, 0x10, 0x1D, 0x40, 0x47, -0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x1D, 0x40, 0xE4, 0x02, 0x1D, 0x04, 0xF4, -0x5B, 0x10, 0x01, 0x40, 0x47, 0x08, 0x9D, 0x01, 0x74, 0x03, 0xD0, 0x19, 0x40, -0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, -0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x8D, 0x40, 0x74, -0x51, 0x90, 0x05, 0x48, 0x02, 0x00, 0x0D, 0x12, 0x34, 0x1B, 0x10, 0x4C, 0x49, -0x33, 0x00, 0x0D, 0x02, 0x34, 0x13, 0xD0, 0x00, 0x40, 0x4E, 0x80, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x40, -0x07, 0x10, 0x0D, 0x40, 0x67, 0x00, 0xDD, 0x23, 0x74, 0x81, 0x14, 0x1D, 0x41, -0x44, 0x00, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x01, 0x40, 0x07, 0x08, 0x9D, 0x51, -0x74, 0x03, 0xD0, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0xDF, 0x00, 0x54, 0x1F, 0xF0, 0x0D, 0xC0, -0x47, 0x00, 0x9F, 0x01, 0x7C, 0x19, 0xF0, 0x14, 0xC0, 0xC6, 0x00, 0x9F, 0x07, -0x74, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x01, 0x7C, 0x03, 0x79, 0x39, -0xC0, 0x22, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, -0x3C, 0x00, 0xEF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x40, -0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x03, -0xC4, 0x0F, 0x30, 0x1F, 0x20, 0xFE, 0xA7, 0xF0, 0x0B, 0x40, 0x1F, 0x00, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, -0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x5C, 0x49, 0xB0, 0x25, -0xC0, 0x06, 0x00, 0x9B, 0x00, 0x4E, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0x17, -0x02, 0x4C, 0x13, 0xF2, 0x29, 0xC5, 0x29, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xFD, 0x00, 0x34, 0x07, 0x10, 0x0D, -0xC0, 0x07, 0x00, 0xDD, 0x05, 0x04, 0x1D, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x11, -0x00, 0xEC, 0x63, 0xD0, 0x71, 0x40, 0x84, 0x0B, 0x11, 0x01, 0x44, 0x43, 0xD0, -0x18, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x3B, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xCD, -0x00, 0x14, 0x0B, 0x94, 0x00, 0x42, 0x62, 0x00, 0x89, 0x80, 0x54, 0x07, 0xD0, -0x4C, 0x40, 0xF1, 0x10, 0x85, 0x00, 0x04, 0x03, 0xD0, 0xB0, 0x40, 0x0D, 0x00, -0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x80, 0xED, -0x41, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x49, 0x30, 0xED, 0xC9, 0x94, 0x06, 0x10, -0x17, 0x00, 0x78, 0x00, 0xF0, 0x49, 0xB4, 0x07, 0xD0, 0x13, 0x40, 0x48, 0x00, -0xE1, 0x11, 0x84, 0x07, 0xD0, 0x16, 0x40, 0x3E, 0x20, 0x08, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30, -0x8C, 0x40, 0x03, 0x00, 0xCF, 0x00, 0x5C, 0x33, 0xB0, 0x00, 0xC0, 0x32, 0x04, -0x5B, 0x80, 0x14, 0x03, 0xF2, 0x0C, 0xD0, 0x30, 0x03, 0x46, 0x08, 0x0D, 0x03, -0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xB0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC2, 0x37, 0x00, -0xCF, 0x00, 0x6C, 0xA3, 0xF0, 0x0C, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x6C, 0x43, -0xF0, 0x80, 0xC0, 0x03, 0x0A, 0xDF, 0x08, 0x7C, 0x23, 0xF0, 0x8D, 0xC0, 0x09, -0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, -0xDF, 0x1E, 0x7C, 0x03, 0x30, 0x0D, 0xC4, 0x07, 0x00, 0xDF, 0x00, 0x5C, 0x01, -0xF0, 0x15, 0xC0, 0x14, 0x00, 0xDF, 0x00, 0x4C, 0x4F, 0x71, 0x0D, 0xC8, 0x34, -0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03, -0x10, 0x0E, 0x48, 0x0B, 0x10, 0xED, 0x00, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x38, -0x08, 0xFD, 0x80, 0x04, 0x03, 0x12, 0x02, 0x40, 0x08, 0x04, 0xED, 0x00, 0xB4, -0x03, 0xD0, 0x06, 0x60, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x14, 0x1E, 0x40, 0x4B, -0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x50, 0x58, 0x00, 0xED, 0x01, 0x85, -0x07, 0x50, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x87, 0xD0, 0x1C, 0x40, -0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, -0x00, 0xCD, 0x00, 0x34, 0x4F, 0x90, 0x0C, 0x48, 0xC3, 0x83, 0xCD, 0x12, 0x04, -0x4B, 0xD0, 0x7C, 0x40, 0xB0, 0x0C, 0xCD, 0x02, 0x04, 0x03, 0x10, 0x01, 0x40, -0x00, 0x00, 0xCD, 0x88, 0x30, 0x22, 0xD0, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0xBC, -0x49, 0x30, 0x05, 0xC2, 0x9F, 0x00, 0x6F, 0x02, 0x9C, 0x09, 0xF0, 0x27, 0xC8, -0x1C, 0x00, 0x7F, 0x00, 0x4C, 0x01, 0x70, 0x05, 0xD0, 0x14, 0x00, 0x7D, 0x21, -0x7C, 0x05, 0xD0, 0x27, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x18, -0x7C, 0x00, 0xF0, 0x23, 0xC0, 0x8F, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1, -0xD1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, -0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08, -0x6C, 0x26, 0x71, 0x09, 0xC0, 0x27, 0x00, 0x9E, 0x00, 0x4C, 0x16, 0xF0, 0x09, -0xC0, 0x25, 0x20, 0x93, 0x38, 0x78, 0x0E, 0xF2, 0x18, 0xC0, 0x40, 0x20, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, -0x74, 0x02, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x06, 0x11, 0x09, -0x44, 0x27, 0x00, 0x9D, 0x80, 0x44, 0x8E, 0xD1, 0x29, 0x40, 0x20, 0x04, 0x91, -0x01, 0x74, 0x06, 0xD0, 0x89, 0x41, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0x1C, 0x09, -0x40, 0x27, 0x00, 0x9D, 0x00, 0x64, 0x42, 0x40, 0x09, 0x42, 0x37, 0x80, 0x8D, -0x00, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x2D, 0x40, 0x91, 0x00, 0x74, 0x42, 0xD0, -0x09, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D, -0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x23, 0x05, 0x8D, 0x34, 0x04, 0x52, 0xD0, -0x0A, 0x40, 0x2C, 0x20, 0x81, 0x14, 0x34, 0x02, 0xD0, 0x48, 0x51, 0x50, 0xA0, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06, 0x00, 0x1F, -0x04, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x6C, 0x00, 0x70, -0x01, 0xC0, 0x07, 0x21, 0x1F, 0x04, 0x4C, 0x11, 0xF0, 0x01, 0xC0, 0x0D, 0x00, -0x13, 0xC4, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x19, 0xB0, 0x27, 0x00, 0x9F, 0x00, 0xBC, 0x03, 0xF0, -0x09, 0xC0, 0x2F, 0x00, 0xEF, 0x80, 0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, -0xBF, 0x14, 0x7D, 0x52, 0xF0, 0x48, 0xC5, 0x27, 0x00, 0xBF, 0x40, 0xFC, 0x52, -0xF0, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0xA0, 0x27, 0x00, 0x9F, 0x01, 0xFC, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x60, -0xB3, 0x00, 0x9C, 0x0A, 0x70, 0x09, 0xC0, 0x3D, 0x00, 0x93, 0x02, 0xCC, 0xC6, -0xF0, 0x2B, 0xC2, 0x2F, 0x00, 0xBF, 0x80, 0xCC, 0x0A, 0xD0, 0x0B, 0xC0, 0x67, -0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, -0x1D, 0x0A, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11, 0x00, 0x44, 0x04, -0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40, 0x07, -0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x74, 0x02, -0x90, 0x08, 0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x02, 0x52, 0x09, 0x40, 0xA1, -0x00, 0x81, 0x22, 0x04, 0x42, 0xD2, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04, -0x02, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x06, 0x10, 0x09, 0x40, 0x27, -0x00, 0x91, 0x00, 0x44, 0x1A, 0x12, 0x29, 0x42, 0x24, 0x40, 0x91, 0x80, 0x45, -0x82, 0xD0, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x29, 0x40, -0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, -0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC4, 0xE3, 0x04, 0x93, 0x02, 0x5C, -0x0E, 0x70, 0x08, 0xC0, 0xE5, 0x04, 0x92, 0x1B, 0x48, 0x02, 0xE0, 0x09, 0xC0, -0x27, 0x00, 0x9F, 0x19, 0x4D, 0x06, 0xF0, 0x09, 0xC0, 0x17, 0x28, 0x0E, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C, -0x02, 0xF0, 0x09, 0xC4, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, -0x27, 0x01, 0x8F, 0x21, 0x7C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x8F, 0x01, -0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC0, -0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0x31, 0x21, 0xC8, 0x87, 0x00, 0x1E, 0x02, -0x7C, 0x00, 0x32, 0x81, 0x81, 0x04, 0x04, 0x1F, 0x80, 0x4C, 0x00, 0x34, 0x01, -0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, -0x14, 0x00, 0x5D, 0x00, 0x84, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x6D, 0x80, -0xB4, 0x05, 0x10, 0x05, 0x40, 0x13, 0x00, 0x5D, 0x00, 0xF4, 0x01, 0x10, 0x27, -0x40, 0xDC, 0x00, 0x5D, 0x05, 0xC4, 0x61, 0x12, 0x07, 0x40, 0x53, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, -0x24, 0x05, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x34, 0x0F, 0x14, 0x0C, -0x40, 0x33, 0x02, 0xCD, 0x00, 0x34, 0x1F, 0x50, 0x2C, 0x44, 0xD0, 0x20, 0x8D, -0x00, 0x04, 0x0F, 0x10, 0x2C, 0x41, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x01, 0x84, 0x0B, 0xD0, 0x0E, -0x40, 0x3B, 0x80, 0xAD, 0x00, 0xF4, 0x43, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED, -0x48, 0xB4, 0x47, 0x50, 0x1E, 0x50, 0x38, 0x04, 0xED, 0x00, 0x84, 0x05, 0x10, -0x2E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0x10, 0x78, 0x00, 0xCF, 0x01, 0xAC, 0x05, 0xF0, 0x1E, 0xC4, 0x7B, 0x10, 0xAF, -0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x8D, 0xFC, 0x07, 0x70, -0x17, 0xC0, 0x78, 0x08, 0xEE, 0x01, 0xCD, 0x07, 0x30, 0x1E, 0xC0, 0x47, 0x40, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, -0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, -0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x42, 0x7C, 0x03, 0xB4, 0x0D, 0xC0, 0x37, 0x00, -0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x85, 0xF0, -0x1F, 0xC0, 0x7F, 0x02, 0x2F, 0x09, 0x8C, 0x05, 0xF0, 0x9F, 0xC2, 0x6D, 0x02, -0xFB, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x20, 0xFF, 0x01, 0xFC, 0x07, -0x30, 0x1F, 0xC0, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x15, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, -0x2D, 0x10, 0x84, 0x01, 0x12, 0x0E, 0x40, 0x38, 0x04, 0xE9, 0x00, 0x84, 0x11, -0x10, 0x06, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xA4, 0x11, 0x18, 0x0A, 0x40, 0x54, -0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, -0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x39, 0x20, 0x3D, 0x00, 0xC5, 0x01, -0xD0, 0x0F, 0x09, 0x29, 0x00, 0xED, 0x40, 0x96, 0x83, 0x14, 0x06, 0x40, 0x3B, -0x02, 0xED, 0x00, 0xF4, 0x83, 0x10, 0x0E, 0x41, 0x22, 0x00, 0x04, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD, 0x40, 0x34, 0x03, -0xD0, 0x0C, 0x64, 0xB3, 0x04, 0x0D, 0x07, 0x04, 0x0C, 0x90, 0x3C, 0x40, 0x70, -0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0xA1, 0x44, 0x73, 0x00, 0xCD, 0x02, 0x64, -0x24, 0x10, 0x10, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x0D, 0xC0, 0x77, -0x14, 0x9F, 0x03, 0x0C, 0x4E, 0xF0, 0x9D, 0xC0, 0xF5, 0x00, 0xFF, 0x12, 0x78, -0x00, 0x30, 0x39, 0x40, 0x73, 0x01, 0xDD, 0x10, 0x7C, 0x02, 0x14, 0x1D, 0xC0, -0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, -0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x9F, 0x02, 0x7C, -0x08, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDB, 0x04, 0x7C, 0x0A, 0xF0, 0x09, 0xC4, -0x37, 0x00, 0xDF, 0x30, 0x6C, 0x82, 0xF0, 0x6D, 0xC0, 0xA7, 0x00, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x80, 0xFC, -0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0xDC, 0x42, 0x70, 0x0F, 0xC0, -0x3D, 0x04, 0xDF, 0x40, 0x78, 0x00, 0xE0, 0x03, 0x01, 0x3C, 0x24, 0xF2, 0x80, -0xFC, 0x00, 0x30, 0x09, 0xE0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x1F, 0xD0, 0x0D, 0xC0, -0x35, 0x00, 0x8D, 0x41, 0x46, 0x16, 0x10, 0x0C, 0x46, 0x24, 0x20, 0xDD, 0x00, -0x74, 0x0E, 0xD0, 0x19, 0xC1, 0xF6, 0x01, 0xD1, 0x00, 0x74, 0x04, 0x30, 0x41, -0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, -0x34, 0x80, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x0D, 0x48, 0x35, 0x10, 0x9D, 0x03, -0x54, 0x06, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xDD, 0x00, 0x54, 0x0C, 0xD0, 0x19, -0x60, 0x75, 0x10, 0xD5, 0x04, 0x74, 0x06, 0x10, 0x85, 0x40, 0x05, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00, -0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x00, 0xDD, 0x20, 0x44, 0x00, 0x18, 0x0D, -0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x09, 0x48, 0x27, 0x80, 0xC5, -0x00, 0x34, 0x02, 0x93, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, -0xC0, 0x35, 0x00, 0x9F, 0x00, 0x54, 0x02, 0x70, 0x0D, 0xC0, 0x25, 0x20, 0xFD, -0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x35, 0x80, 0xD7, 0x80, 0x7C, 0x02, 0x24, -0x01, 0xC0, 0x07, 0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, -0xB8, 0x3F, 0x10, 0xFF, 0x20, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3D, 0x00, 0xBF, -0x80, 0xF4, 0x02, 0xF2, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, -0x0B, 0xC0, 0x2E, 0x40, 0xFB, 0x00, 0xBC, 0x02, 0x70, 0x03, 0xC8, 0x17, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x7F, -0x41, 0xFC, 0x85, 0xF0, 0x1B, 0xC0, 0x5C, 0x02, 0xAF, 0x14, 0xCC, 0x04, 0xF0, -0xC3, 0xC0, 0x0C, 0x04, 0xB3, 0x10, 0xCC, 0x0C, 0x30, 0x8B, 0xC0, 0x3F, 0x00, -0xB3, 0x14, 0xCC, 0x53, 0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x57, 0x00, 0x9D, 0x01, 0x74, 0x05, 0xD1, -0x15, 0x44, 0x14, 0x21, 0xFD, 0x03, 0x44, 0x10, 0xD0, 0xE1, 0x00, 0x84, 0x01, -0xAB, 0x06, 0x44, 0x00, 0x10, 0xE9, 0x40, 0x77, 0x00, 0xB5, 0x06, 0xD4, 0x0F, -0x10, 0x09, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x11, 0xA0, 0x33, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x20, -0xCD, 0x00, 0x16, 0x40, 0xD2, 0x01, 0x50, 0x04, 0x44, 0x81, 0x10, 0x05, 0x10, -0x10, 0x00, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x04, 0x03, 0xD0, 0x48, 0x41, 0x44, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x01, -0x9D, 0x04, 0x74, 0x02, 0xD0, 0x85, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x55, 0x04, -0xD0, 0x01, 0x46, 0x64, 0x00, 0x99, 0x48, 0x44, 0x04, 0x10, 0x31, 0x48, 0x37, -0x00, 0xC5, 0x00, 0x54, 0x03, 0xD0, 0x09, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA7, 0x01, 0xDF, 0x01, 0x7C, 0x27, -0xF0, 0x0D, 0xD0, 0x74, 0x12, 0x8F, 0x00, 0x5C, 0x44, 0xF0, 0x20, 0xC1, 0xC0, -0x00, 0x93, 0x00, 0x4C, 0x14, 0x34, 0x1D, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x4C, -0x03, 0xF4, 0x39, 0xD0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x07, 0x80, 0x6D, 0x00, 0xBF, 0x01, 0xF8, 0x07, 0xF0, 0x0F, 0xC8, 0x3F, -0x00, 0xF8, 0x10, 0xEC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, -0x40, 0xF0, 0x0F, 0xC0, 0x3B, 0x10, 0x9F, 0x09, 0xB8, 0x83, 0x30, 0x3B, 0xC0, -0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, -0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x80, 0x4C, -0x00, 0x32, 0x01, 0xD0, 0x8C, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x25, 0xC0, -0x34, 0x00, 0xD3, 0x04, 0x4D, 0x03, 0xF0, 0x28, 0xC0, 0x0B, 0x20, 0x04, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0x9C, 0x00, 0x70, -0x02, 0xD0, 0x0C, 0x60, 0x67, 0x00, 0xDD, 0x03, 0x40, 0x2C, 0x10, 0x03, 0x40, -0x64, 0x00, 0x91, 0x0F, 0x6D, 0x08, 0x91, 0xB5, 0x40, 0xBC, 0x40, 0xD5, 0x13, -0xC4, 0x03, 0xC0, 0x49, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x07, 0xA0, 0x22, 0x20, 0x4D, 0x80, 0x34, 0x02, 0xC0, 0x04, 0x48, -0x63, 0x00, 0x8D, 0x01, 0x24, 0x04, 0x10, 0x08, 0x42, 0x40, 0x00, 0x91, 0x01, -0x44, 0x04, 0xD1, 0x18, 0x40, 0xB0, 0x04, 0xC1, 0x02, 0x04, 0x03, 0xD0, 0x08, -0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, -0x68, 0x00, 0xED, 0x21, 0xB4, 0x06, 0xD0, 0x16, 0x40, 0x6B, 0x06, 0xED, 0x11, -0xA5, 0x44, 0x14, 0x98, 0x50, 0x6C, 0x04, 0xE1, 0x09, 0xA4, 0x04, 0x90, 0x1E, -0x40, 0x78, 0x02, 0xE5, 0x21, 0x84, 0x07, 0xD1, 0x16, 0x40, 0x13, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x00, -0x3C, 0x02, 0xF0, 0x04, 0x40, 0x23, 0x0A, 0xCF, 0x00, 0x6C, 0x00, 0x32, 0x88, -0xC8, 0x80, 0x40, 0xC3, 0x08, 0x0C, 0x40, 0xF2, 0x8D, 0xD1, 0x30, 0x02, 0xC3, -0x00, 0x0D, 0x03, 0xF0, 0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xBF, 0x80, 0xF0, 0x02, 0xF0, 0x07, -0xC0, 0x2F, 0x0A, 0xFF, 0x02, 0xDC, 0x00, 0xF0, 0x8B, 0xD0, 0x3B, 0x42, 0xFF, -0x08, 0xF4, 0x00, 0xB0, 0x8F, 0xC0, 0x3B, 0x02, 0xFF, 0x00, 0xFC, 0x43, 0xF0, -0x87, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, -0xA0, 0x67, 0x00, 0xD3, 0x20, 0x7C, 0x07, 0x34, 0x05, 0xC0, 0x70, 0x00, 0x93, -0x06, 0x5C, 0x00, 0xF0, 0x81, 0xD0, 0x00, 0x10, 0x93, 0x86, 0x4D, 0x04, 0x30, -0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x04, 0x0D, 0x13, 0x31, 0x05, 0xC0, 0x54, 0x00, -0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xE1, -0x00, 0xB4, 0x03, 0x10, 0x06, 0xC0, 0x3A, 0x10, 0xE1, 0x00, 0x84, 0x02, 0xD0, -0x43, 0x40, 0x29, 0x00, 0xEB, 0x08, 0x84, 0x01, 0x51, 0x0E, 0x40, 0x3B, 0x01, -0xF1, 0x08, 0x94, 0x43, 0x10, 0x0F, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x6D, 0x00, 0xA1, 0x01, 0xF6, 0x06, 0x10, -0x16, 0x40, 0x6C, 0x10, 0xF0, 0x01, 0xB4, 0x04, 0xD0, 0x3A, 0x40, 0x4C, 0x00, -0xC1, 0x01, 0xC6, 0x04, 0x10, 0x3E, 0x40, 0x73, 0x02, 0xE9, 0x01, 0x84, 0x03, -0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x12, 0x28, 0x63, 0x00, 0x81, 0x04, 0x36, 0x16, 0x10, 0x14, 0x44, 0x22, 0x02, -0xC1, 0x00, 0x24, 0x0B, 0xD1, 0x0D, 0x41, 0x30, 0x08, 0xC9, 0x00, 0x04, 0x1F, -0x50, 0x1D, 0x40, 0x33, 0x10, 0xD9, 0x00, 0x15, 0x03, 0x10, 0xEC, 0x40, 0x4A, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x01, -0x73, 0x80, 0xFC, 0x05, 0x33, 0xE7, 0xCC, 0xDC, 0x40, 0x53, 0xC0, 0xBC, 0x15, -0xF1, 0x27, 0xD0, 0x1C, 0x08, 0x53, 0x00, 0xCD, 0x05, 0x32, 0x17, 0xC0, 0x17, -0x40, 0x5B, 0x00, 0x4C, 0x01, 0x30, 0x37, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x54, 0x1F, 0x00, 0x7C, 0x20, -0xF0, 0x01, 0xC0, 0x07, 0x24, 0x1F, 0x02, 0x5C, 0x48, 0xF0, 0x01, 0xC0, 0x03, -0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x20, 0x7C, -0x80, 0xF0, 0x00, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, -0x00, 0x9F, 0x05, 0x4C, 0x0E, 0x30, 0x09, 0xC0, 0x64, 0x20, 0x8A, 0x01, 0x6C, -0x02, 0xF0, 0x09, 0xC8, 0x60, 0x00, 0x93, 0x00, 0x4C, 0x22, 0xF0, 0x89, 0xC2, -0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, -0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x8C, 0x00, 0x44, -0x12, 0x10, 0x09, 0x40, 0x65, 0x08, 0x9B, 0x01, 0x6C, 0x02, 0xD0, 0xA9, 0x41, -0xE4, 0x01, 0x91, 0x02, 0x45, 0x06, 0xD0, 0x19, 0x40, 0x04, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x20, 0x70, -0x03, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0x9C, 0x10, 0x44, 0x02, 0x14, 0x09, 0x40, -0x24, 0x02, 0x9D, 0x48, 0x65, 0x12, 0xD2, 0x09, 0x40, 0x24, 0x42, 0x91, 0x14, -0x44, 0x82, 0xD0, 0x0D, 0x44, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0xA0, 0x10, 0x8D, 0x02, 0x34, 0x0A, 0xD0, 0x28, 0x40, -0x21, 0x10, 0x9D, 0x14, 0x46, 0x02, 0x18, 0x48, 0x45, 0x21, 0x45, 0xCD, 0x14, -0x24, 0x02, 0xD0, 0x48, 0x71, 0x20, 0x85, 0x81, 0x14, 0x04, 0x52, 0xD0, 0x48, -0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, -0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0, 0x00, 0x40, 0x04, 0x10, 0x1F, 0x04, -0x4C, 0x00, 0x30, 0x41, 0xC4, 0x14, 0x21, 0x1F, 0x44, 0x6C, 0x00, 0xF1, 0x41, -0xC0, 0x04, 0x01, 0x13, 0xC4, 0x4C, 0x10, 0xF0, 0x41, 0xD0, 0x74, 0xC0, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x7B, 0x00, 0xFF, 0x01, -0xBC, 0x06, 0xF0, 0x1B, 0xC0, 0x2F, 0x05, 0xAE, 0x00, 0xFD, 0x52, 0xF1, 0x4F, -0xC1, 0x2F, 0x45, 0xBB, 0x14, 0xBC, 0x52, 0xF0, 0x4B, 0xC1, 0x27, 0x40, 0xBF, -0x14, 0x7C, 0x02, 0xF2, 0x4B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x19, 0xA0, 0xA7, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x30, 0x28, -0xC0, 0xAF, 0x00, 0xAF, 0x01, 0xDC, 0x0A, 0xF0, 0x39, 0xC0, 0xED, 0x05, 0xB3, -0x03, 0xDC, 0x02, 0x32, 0x5B, 0xC1, 0x2C, 0x00, 0xB3, 0x01, 0xCC, 0x06, 0x30, -0x6A, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, -0x08, 0x47, 0x01, 0x1B, 0x01, 0x6C, 0x14, 0xB0, 0x51, 0x40, 0x47, 0x00, 0x1D, -0x02, 0x45, 0x04, 0xD1, 0x10, 0x40, 0xC0, 0x00, 0x11, 0x01, 0x45, 0x14, 0x10, -0x75, 0xC0, 0x07, 0x10, 0x11, 0x05, 0x54, 0x00, 0x10, 0x61, 0x40, 0x70, 0x20, -0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x81, -0x20, 0x04, 0x42, 0x10, 0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x14, 0x12, 0xD0, -0x28, 0x40, 0x21, 0x00, 0x85, 0x02, 0x14, 0x46, 0x10, 0x08, 0x49, 0x21, 0x00, -0x81, 0x12, 0x04, 0x0A, 0x10, 0x28, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x21, 0x00, 0x89, 0x00, 0x24, 0x42, 0x90, -0x09, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x19, 0x40, 0xA4, 0x00, -0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x90, 0x04, 0x54, 0x02, -0x10, 0x39, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x05, 0xA8, 0x2F, 0x02, 0xB3, 0x00, 0xCC, 0x0A, 0x30, 0x0B, 0xC0, 0xA7, 0x04, -0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x29, 0xC8, 0x25, 0x40, 0x97, 0x00, 0x5C, 0x0A, -0x34, 0x09, 0xC8, 0x25, 0x40, 0x93, 0x00, 0x4D, 0x02, 0x34, 0x29, 0xD0, 0x14, -0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x00, -0x9F, 0x03, 0x7C, 0x0A, 0xE0, 0x09, 0xC0, 0xA7, 0x00, 0x8F, 0x00, 0x7C, 0x02, -0xF0, 0x08, 0xC4, 0x27, 0x01, 0x8B, 0x45, 0x7C, 0x02, 0xF0, 0x98, 0xE0, 0x21, -0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x00, 0x4D, 0x08, -0xF0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x10, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04, -0x40, 0x13, 0x00, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x04, 0x03, 0x80, 0x7C, -0x00, 0x34, 0x20, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x14, 0xA0, 0x14, 0x10, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x54, -0x01, 0x75, 0x02, 0xC4, 0x05, 0xD0, 0x05, 0x50, 0xD8, 0x40, 0x75, 0x00, 0xC4, -0x11, 0x10, 0x47, 0x50, 0x1C, 0x00, 0x71, 0x00, 0x74, 0x01, 0x10, 0x15, 0x40, -0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, -0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0xC1, 0x0A, 0x24, -0x26, 0xD0, 0x0C, 0x44, 0xF0, 0x86, 0xC4, 0x09, 0x65, 0x07, 0x50, 0x0C, 0x00, -0xF0, 0x00, 0xC5, 0x20, 0x34, 0x02, 0x10, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x3C, 0x01, 0xF1, 0x04, 0x84, -0xA3, 0xD0, 0x1F, 0x40, 0x78, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x4E, 0x40, -0x28, 0x00, 0x65, 0x00, 0x85, 0x13, 0x50, 0x0A, 0x40, 0x90, 0x00, 0xA5, 0x00, -0xB0, 0x02, 0x10, 0x0F, 0x41, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xE3, 0x07, 0x8C, 0x17, 0xF0, 0x7E, 0xD0, -0x6C, 0x00, 0xA3, 0x01, 0xAC, 0x05, 0xF0, 0x3E, 0xC1, 0x68, 0x00, 0x77, 0x01, -0xED, 0x0F, 0x74, 0x13, 0x84, 0x48, 0x00, 0xA7, 0x01, 0x3C, 0x06, 0x30, 0x1E, -0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, -0x31, 0x40, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00, -0xFD, 0x00, 0xF0, 0x2D, 0xC0, 0x27, 0x02, 0x5D, 0x00, 0x7C, 0x03, 0x90, 0x01, -0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x04, 0xF3, 0x01, -0xCC, 0x27, 0x3C, 0x1F, 0xC0, 0x7B, 0x00, 0x37, 0x01, 0xDC, 0x06, 0x72, 0x1F, -0xC0, 0x6D, 0x00, 0xF7, 0x81, 0xCC, 0x06, 0x31, 0x1B, 0xC0, 0x4C, 0x10, 0xE3, -0x01, 0xCC, 0x06, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xE1, 0x00, 0xAC, 0x23, 0x18, 0x4E, -0x40, 0x3B, 0x00, 0x21, 0x04, 0x84, 0x80, 0xD0, 0x4E, 0x40, 0x2C, 0x00, 0x61, -0x02, 0x8C, 0x02, 0x10, 0x0A, 0x40, 0x09, 0x00, 0xAB, 0x00, 0x94, 0x02, 0xD0, -0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, -0x00, 0x79, 0x00, 0xE1, 0x11, 0x84, 0x07, 0x12, 0x1E, 0x40, 0x3B, 0x00, 0x05, -0x00, 0x90, 0x00, 0x50, 0x0E, 0x44, 0x09, 0x04, 0x3D, 0x10, 0x84, 0x03, 0x10, -0x02, 0x41, 0x0A, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x2E, 0x40, 0x03, 0x00, -0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x40, 0xC1, -0x10, 0x24, 0x03, 0x11, 0x8C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x04, 0x0C, 0xD0, -0x8C, 0x40, 0x80, 0x01, 0x09, 0x40, 0x24, 0x0F, 0x11, 0x11, 0x44, 0x03, 0x00, -0x09, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30, -0x3D, 0xC0, 0x37, 0x00, 0x87, 0x00, 0x5C, 0x1E, 0x70, 0x1F, 0xC0, 0x4D, 0x00, -0x9F, 0x00, 0xCD, 0x13, 0x34, 0x09, 0xC0, 0x06, 0x08, 0xD3, 0x00, 0x4C, 0x03, -0xF3, 0x0D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC1, 0x37, 0x00, -0x1F, 0x08, 0x7C, 0x40, 0xF0, 0x0D, 0xC4, 0x83, 0x00, 0x47, 0x00, 0x5C, 0x00, -0xF0, 0x01, 0xC0, 0x85, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x8D, 0xC4, 0x07, -0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00, -0xFF, 0x00, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0xB3, 0x40, 0xEC, 0x00, -0x30, 0x0D, 0xC0, 0x4D, 0x00, 0xB3, 0x02, 0xCC, 0x43, 0x10, 0x01, 0x40, 0x04, -0x00, 0xBF, 0x01, 0xCC, 0x16, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xCD, 0x00, 0x44, 0x03, -0x14, 0x0D, 0x44, 0x73, 0x02, 0x91, 0x01, 0x04, 0x04, 0x14, 0x0D, 0x50, 0x04, -0x86, 0x51, 0x02, 0x6C, 0x3C, 0x50, 0x31, 0x40, 0xC5, 0x01, 0x1D, 0x01, 0x44, -0x02, 0xB0, 0x09, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37, -0x00, 0x11, 0x01, 0x64, 0x06, 0x10, 0x0C, 0x4A, 0x04, 0x00, 0x95, 0x00, 0x04, -0x02, 0x50, 0x39, 0x40, 0x45, 0x10, 0xDD, 0x04, 0x40, 0x03, 0x11, 0x1D, 0x40, -0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, -0x00, 0xDD, 0x00, 0x45, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x40, 0x01, 0x00, 0x44, -0x00, 0x10, 0x0C, 0x40, 0x01, 0x80, 0x41, 0x00, 0x24, 0x00, 0x40, 0x00, 0x40, -0x01, 0x00, 0xCD, 0x00, 0x05, 0x03, 0x80, 0x0C, 0x40, 0x43, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3A, 0x10, 0xEF, 0x00, 0x8C, -0x03, 0x30, 0x0F, 0x40, 0x37, 0x00, 0x13, 0x00, 0x6C, 0x00, 0x38, 0x0F, 0xD0, -0x04, 0x00, 0x95, 0x00, 0x0D, 0x03, 0x61, 0x01, 0x80, 0x05, 0x20, 0x9F, 0x00, -0x4D, 0x02, 0x30, 0x0D, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, -0x3F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF1, 0x0F, 0xC0, 0x0E, 0x00, 0x2E, 0x00, -0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0F, -0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, -0x82, 0xC0, 0x0E, 0x02, 0x3B, 0x08, 0xE0, 0x28, 0xB0, 0x83, 0xE0, 0x0E, 0x82, -0x38, 0x08, 0xEC, 0x20, 0x90, 0x83, 0xC8, 0x0E, 0x02, 0x1B, 0x08, 0xEC, 0x28, -0xA8, 0x83, 0xA0, 0x0E, 0x02, 0x3A, 0x08, 0xCC, 0x20, 0x98, 0x03, 0x8C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x22, 0xA0, 0x8E, 0xA0, -0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0x20, 0x8E, 0xA0, 0x3B, 0x02, 0xEA, 0x08, -0xA8, 0x23, 0xA0, 0x8E, 0xA0, 0x32, 0x02, 0x4A, 0x08, 0xA8, 0x23, 0x88, 0x8E, -0x80, 0x3A, 0x02, 0xCA, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x18, -0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, -0x01, 0x12, 0x04, 0x48, 0x18, 0x20, 0x41, 0xA0, 0x04, 0x01, 0x12, 0x04, 0x48, -0x10, 0x20, 0x01, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x21, 0x00, 0x80, 0x02, 0x80, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0xA0, 0x0E, -0x20, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x28, -0x10, 0xA8, 0x01, 0x88, 0x06, 0x80, 0x1A, 0x00, 0x68, 0x00, 0x88, 0x01, 0x04, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x12, 0xA0, 0x4E, -0x80, 0x3A, 0x01, 0xEA, 0x14, 0xA0, 0x13, 0xA0, 0x4A, 0x80, 0x3A, 0x01, 0xEA, -0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x82, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0x80, -0x4A, 0x80, 0x3A, 0x01, 0xEA, 0x0C, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, -0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, -0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, -0x60, 0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA3, 0x20, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x00, 0x08, 0x11, 0x20, -0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x11, 0x20, 0xC0, 0x80, 0x10, 0x01, -0x42, 0x00, 0x00, 0x11, 0x00, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x01, -0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xD2, 0xA0, -0x02, 0x01, 0x0A, 0x05, 0x2A, 0x10, 0xA8, 0x50, 0x80, 0x02, 0x01, 0x0A, 0x07, -0x2A, 0x1C, 0xA8, 0x50, 0xA0, 0x42, 0x83, 0x0A, 0x05, 0x2A, 0x10, 0xA0, 0x50, -0x88, 0x02, 0x01, 0x0A, 0x05, 0x2A, 0x3C, 0xA0, 0x00, 0x8C, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x80, 0xC8, 0x00, 0xAA, 0x03, -0xA8, 0x0E, 0x20, 0x38, 0x80, 0xE0, 0x00, 0xAA, 0x07, 0x08, 0x1E, 0xA0, 0x32, -0x80, 0xCA, 0x00, 0x22, 0x03, 0xA8, 0x0C, 0xA0, 0x3A, 0xA0, 0xCA, 0x00, 0x2A, -0x03, 0xA8, 0x0C, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x21, 0x72, 0x00, 0x48, 0x20, 0x18, 0x80, 0x22, 0x00, 0x00, 0x00, -0x08, 0x40, 0x20, 0x08, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x82, 0x00, 0x20, -0x00, 0x20, 0x04, 0x80, 0x00, 0x08, 0x42, 0x00, 0x18, 0x00, 0x20, 0x08, 0x00, -0x82, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16, -0x40, 0x18, 0x00, 0x41, 0x00, 0x04, 0x01, 0x1A, 0x04, 0x40, 0x10, 0x20, 0x41, -0x80, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x61, 0x00, 0x04, 0x01, 0x10, -0x04, 0x08, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A, -0x00, 0x6A, 0x02, 0x28, 0x09, 0xA0, 0x24, 0x00, 0x9B, 0x00, 0x48, 0x02, 0xA8, -0x01, 0xA0, 0x06, 0x00, 0x1A, 0x00, 0x6A, 0x00, 0xB8, 0x09, 0xA0, 0x06, 0xA0, -0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA3, 0x00, 0xC0, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xBC, -0x01, 0x90, 0x46, 0x00, 0x1B, 0x00, 0x6C, 0x00, 0xA8, 0x01, 0xC0, 0x06, 0x20, -0x1B, 0x80, 0x6C, 0x04, 0xA0, 0x01, 0xE8, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00, -0x32, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, -0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x08, 0x81, -0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x28, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x30, -0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x0C, 0x00, -0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x80, 0x00, -0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x08, -0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x34, -0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x10, 0x20, 0x43, 0x80, 0x0C, -0x01, 0x32, 0x04, 0xC8, 0x10, 0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, -0x10, 0x20, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA3, 0x42, 0xA0, 0x06, 0x83, 0x1A, 0x04, 0x6A, 0x30, 0xA8, 0x41, 0xA0, 0x06, -0x83, 0x1A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x04, 0x6A, -0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x0A, 0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x00, 0x04, -0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0, -0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00, -0x00, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x4A, 0x20, 0x06, 0x81, 0x30, 0x04, 0x62, -0x12, 0x08, 0x4B, 0x20, 0x06, 0x81, 0xB0, 0x04, 0x62, 0x12, 0x88, 0x41, 0x20, -0x26, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x00, 0x06, 0x81, 0x30, 0x04, -0x62, 0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x23, 0x06, 0xA0, 0x1A, 0x00, 0x62, 0x00, 0xAA, 0x01, 0x20, 0x04, 0xA0, -0x18, 0x00, 0x62, 0x00, 0x8A, 0x01, 0xA0, 0x06, 0xA0, 0x1A, 0x80, 0x6A, 0x80, -0xAA, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0xAA, 0x01, 0xA8, 0x02, -0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x60, 0x80, -0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06, -0x28, 0x18, 0xA0, 0x60, 0x00, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60, -0xA0, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x00, 0x01, 0x02, 0x04, -0x48, 0x12, 0x20, 0x49, 0xA0, 0x00, 0x01, 0x92, 0x04, 0x48, 0x12, 0x28, 0x41, -0x80, 0x20, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x88, 0x00, 0x01, 0x02, -0x04, 0x08, 0x12, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA3, 0x62, 0xC0, 0x8A, 0x01, 0x01, 0x06, 0xAC, 0x18, 0xB0, 0x63, -0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2A, -0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0, -0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62, -0xA0, 0x8E, 0x01, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x3A, -0x06, 0x68, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0x98, -0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xCA, 0x18, 0x88, 0x03, 0x8C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A, -0x06, 0xEC, 0x18, 0xA0, 0x61, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xE8, 0x18, 0xA0, -0x63, 0xE0, 0x8E, 0x01, 0x1B, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01, -0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x32, 0x06, 0xEA, 0x18, 0x08, -0x63, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0xEA, 0x18, 0x28, 0x61, 0x20, 0x8E, 0x81, -0x32, 0x86, 0xE8, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0xA1, 0x30, 0x06, 0xEA, 0x18, -0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x40, 0x80, 0x04, 0x01, 0x1A, 0x84, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, -0x32, 0x04, 0x48, 0x10, 0x22, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, -0x20, 0x41, 0x88, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x81, -0x1A, 0x06, 0x68, 0x18, 0xA0, 0x61, 0x80, 0x86, 0x81, 0x18, 0x06, 0x68, 0x18, -0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x68, 0x18, 0xA8, 0x61, 0x80, 0x86, -0x81, 0x1A, 0x06, 0x6A, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00, -0x22, 0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x0E, -0x80, 0x2A, 0x00, 0xEA, 0x00, 0xA8, 0x03, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xE8, -0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA2, 0x42, 0x00, 0x06, 0x01, 0x08, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x04, -0x01, 0x00, 0x0C, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04, 0x60, -0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x18, 0x04, 0x60, 0x10, 0x80, 0x01, 0x88, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x20, 0x04, -0x81, 0x10, 0x04, 0x22, 0x10, 0x88, 0x51, 0x20, 0x06, 0x81, 0x18, 0x05, 0x62, -0x10, 0x08, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x0A, 0x41, 0x20, -0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xAA, -0x30, 0xA8, 0xC2, 0xA0, 0x0A, 0x03, 0x2A, 0x04, 0xAA, 0x30, 0xA8, 0x42, 0xA0, -0x02, 0x81, 0x0A, 0x04, 0x2A, 0x10, 0xA0, 0xC0, 0xA0, 0x02, 0x21, 0x0A, 0x04, -0x28, 0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x40, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x52, 0x80, -0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C, -0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x02, -0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x42, 0x00, 0x08, 0x00, 0x20, 0x00, 0x88, 0x01, 0x00, 0x02, 0x00, 0x08, 0x80, -0x20, 0x00, 0x88, 0x10, 0x00, 0x42, 0x20, 0x08, 0x01, 0x20, 0x04, 0x82, 0x00, -0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00, 0x01, 0x01, 0x04, -0x04, 0x10, 0x10, 0x41, 0x40, 0x44, 0x01, 0x01, 0x04, 0x04, 0x14, 0x10, 0x40, -0x40, 0x00, 0x01, 0x01, 0x04, 0x00, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01, -0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0x02, 0xE0, 0x06, 0x80, 0x1B, 0x00, 0x68, 0x00, 0xA8, 0x01, -0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A, -0x00, 0x6E, 0x00, 0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8, -0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, -0xC0, 0x06, 0x00, 0x3B, 0x00, 0x6C, 0x00, 0xA0, 0x01, 0xC0, 0x06, 0x00, 0x3A, -0x00, 0x68, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xA0, -0x03, 0xC0, 0x06, 0x00, 0x3A, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x18, -0x00, 0xC2, 0x00, 0x08, 0x01, 0x28, 0x0C, 0x80, 0x18, 0x80, 0xC0, 0x00, 0x08, -0x03, 0x20, 0x0C, 0x82, 0x38, 0x00, 0xC2, 0x00, 0x88, 0x01, 0x20, 0x0C, 0x80, -0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC0, 0x02, 0x00, -0x63, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC2, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, -0x10, 0x00, 0xC0, 0x02, 0x00, 0x21, 0x00, 0x2C, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x20, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x21, 0x80, 0x8C, 0x82, -0x32, 0x02, 0x88, 0x28, 0x20, 0xA3, 0x80, 0x8C, 0x02, 0x22, 0x0A, 0xC8, 0x28, -0x28, 0xA3, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x03, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83, -0x5A, 0x0C, 0x6A, 0x31, 0xA0, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x6A, 0x31, -0xA8, 0xC5, 0xA0, 0x16, 0x83, 0x4A, 0x0C, 0x6A, 0x31, 0xA8, 0xE5, 0xA0, 0x16, -0x83, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x10, 0x01, 0x40, 0x02, -0x08, 0x21, 0x00, 0x64, 0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, -0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x91, 0x00, 0x24, 0x00, 0x00, 0x00, 0x40, -0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x80, 0x8A, 0x01, 0x26, 0x06, -0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, -0x84, 0x88, 0x01, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x84, 0x88, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x0A, -0x08, 0x2A, 0x20, 0xAA, 0x80, 0x88, 0x02, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0xAA, -0x00, 0xAA, 0x02, 0xA2, 0x0A, 0x88, 0x28, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6, -0x0A, 0x08, 0x2A, 0x20, 0xAA, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0x28, -0x44, 0xA1, 0x10, 0x8C, 0x4A, 0x10, 0x2A, 0x41, 0x28, 0x04, 0xA1, 0x10, 0x04, -0x42, 0x10, 0x0A, 0x41, 0x28, 0x84, 0x81, 0x10, 0x84, 0x4A, 0x10, 0x0A, 0x41, -0x20, 0x04, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80, -0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, -0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, -0xCA, 0x20, 0x2B, 0x03, 0x8C, 0x0C, 0x30, 0x32, 0x40, 0xC0, 0x00, 0x01, 0x03, -0x88, 0x0C, 0x30, 0x32, 0xC0, 0xCA, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x32, -0x40, 0xC0, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA4, 0x4E, 0x80, 0x3A, 0x01, -0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x41, 0xEA, 0x04, 0xA8, 0x13, -0xA0, 0x4E, 0x84, 0x3B, 0x01, 0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, -0x01, 0xE2, 0x44, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x23, 0x08, 0x8C, 0x21, 0x30, 0x80, 0xC0, -0x10, 0x02, 0x23, 0x08, 0x0C, 0x21, 0x30, 0x84, 0xC4, 0x18, 0x12, 0x43, 0x48, -0x8C, 0x21, 0x31, 0x82, 0xC0, 0x18, 0x12, 0xA3, 0x48, 0x8C, 0x21, 0x31, 0x84, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, -0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, -0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, -0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 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, 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, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0xBE, -0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xED, 0x37, 0x34, 0xDB, 0xD0, 0x7E, -0x43, 0xB3, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xED, -0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0x32, 0xF3, -0xC8, 0xFC, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCC, 0x23, 0x33, -0xBF, 0xFC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3, 0x8F, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x7B, -0x48, 0xEC, 0x27, 0x31, 0x86, 0xC4, 0x78, 0x12, 0x7B, 0x48, 0x8C, 0x27, 0xB1, -0x9F, 0xDC, 0x7E, 0x72, 0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x87, 0xC4, 0x7E, 0x72, -0x7B, 0xC8, 0xED, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x8E, 0x02, 0x39, 0x08, 0xE4, 0x20, -0x80, 0x83, 0x40, 0x0E, 0x02, 0x39, 0x08, 0xE4, 0x20, 0x90, 0x83, 0x40, 0x0E, -0x02, 0x39, 0x08, 0xE0, 0x20, 0x90, 0x83, 0x40, 0x8E, 0x02, 0x39, 0x0A, 0xE0, -0x28, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x20, 0xA0, 0x8E, 0x81, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E, -0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA, -0x08, 0xAA, 0x23, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0xB8, 0x03, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04, -0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, -0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, -0x84, 0x01, 0x12, 0x06, 0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x18, 0x00, 0x60, -0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20, -0x06, 0x00, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, -0x62, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x93, 0x20, -0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4A, 0x80, 0x38, 0x01, -0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, -0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, -0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x28, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x64, 0x80, 0x10, 0x01, -0x42, 0x0A, 0x08, 0x31, 0x20, 0x44, 0x80, 0x10, 0x01, 0x42, 0x0C, 0x08, 0x09, -0x20, 0x44, 0x80, 0x90, 0x00, 0x42, 0x04, 0x08, 0x11, 0x20, 0x64, 0x80, 0x90, -0x00, 0x42, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xD4, 0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x11, 0x80, 0x54, -0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x15, 0x88, 0x44, 0x00, 0x52, 0x81, 0x48, -0x04, 0x20, 0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x48, 0x0C, 0x20, 0x11, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30, -0x00, 0xC8, 0x00, 0x28, 0x03, 0xA0, 0x3C, 0x20, 0x30, 0x00, 0xCA, 0x00, 0x00, -0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80, -0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x04, 0x00, 0x02, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x28, 0x00, 0x08, -0x00, 0x20, 0x0E, 0x80, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x18, 0x80, -0x18, 0x00, 0x02, 0x00, 0x88, 0x01, 0x60, 0x00, 0x80, 0x00, 0x00, 0x22, 0x00, -0x88, 0x01, 0x20, 0x0A, 0x08, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x20, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, -0x02, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, -0x10, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, -0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x0C, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x40, 0x06, 0x00, -0x19, 0x00, 0x64, 0x04, 0x80, 0x01, 0x40, 0x06, 0x00, 0x18, 0x00, 0x64, 0x00, -0x90, 0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x90, 0x01, 0x40, 0x06, -0x00, 0x19, 0x01, 0x62, 0x00, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, -0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x28, 0x0C, -0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, -0x10, 0x18, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, -0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, -0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0C, -0x01, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0, -0x10, 0x00, 0xC3, 0x20, 0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x10, 0x00, 0x43, 0x00, -0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, -0x30, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0xC1, 0x20, -0x06, 0x81, 0x18, 0x0C, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x0C, -0x60, 0x10, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x42, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00, -0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x10, 0x04, -0xC0, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0xC0, 0x10, 0x80, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20, -0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x18, 0x04, -0x62, 0x10, 0x88, 0x41, 0x20, 0x0C, 0x81, 0x18, 0x04, 0xC2, 0x10, 0x88, 0x41, -0x20, 0x06, 0x81, 0x18, 0x04, 0xC0, 0x30, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, -0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x02, -0x00, 0x08, 0x80, 0x28, 0x00, 0x80, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28, -0x80, 0x80, 0x00, 0x00, 0x42, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, -0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, -0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, -0x80, 0x00, 0x01, 0x12, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x81, 0x02, -0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20, -0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x01, 0x2B, -0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, -0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, -0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x98, -0x63, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x40, 0x8E, 0x81, -0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20, 0x8E, 0x81, 0x38, 0x86, 0xE6, 0x18, -0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, -0x62, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0x40, 0x8E, 0x01, -0x39, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, -0x90, 0x63, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x03, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xA2, 0x62, 0xA0, 0x8E, 0x81, -0x3A, 0x06, 0xE8, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0xA1, 0x3A, 0x06, 0xEA, 0x18, -0xA8, 0x63, 0x20, 0x8C, 0x81, 0x3A, 0x06, 0xC2, 0x18, 0xA8, 0x63, 0xA0, 0x8E, -0x81, 0x3A, 0x06, 0xC2, 0x18, 0x18, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x00, 0x48, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x12, -0x20, 0x4B, 0x80, 0x24, 0x01, 0x12, 0x04, 0x48, 0x12, 0x20, 0x41, 0x80, 0x0E, -0x01, 0x12, 0x04, 0xE8, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0xE8, -0x12, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0x00, 0x60, 0x00, 0x86, 0x01, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61, 0x00, 0x86, -0x01, 0x18, 0x06, 0x60, 0x18, 0x80, 0x61, 0x20, 0x86, 0x01, 0x18, 0x06, 0x62, -0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18, 0x06, 0x62, 0x18, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06, 0x20, 0x1E, -0x80, 0x70, 0x00, 0xE2, 0x01, 0x08, 0x07, 0x20, 0x1E, 0x80, 0x70, 0x00, 0xE2, -0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, -0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x4A, 0x00, 0x06, 0x01, 0x10, 0x04, 0x60, -0x12, 0x00, 0x49, 0x00, 0x26, 0x01, 0x10, 0x04, 0x60, 0x12, 0x80, 0x41, 0x00, -0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04, -0x40, 0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x42, 0x20, 0x04, 0x81, 0x18, 0x04, 0x42, 0x10, 0x88, 0x41, 0x20, -0x44, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, -0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, -0x02, 0x83, 0x28, 0x04, 0x22, 0x30, 0x80, 0x42, 0x20, 0x02, 0x83, 0x28, 0x04, -0x22, 0x10, 0x88, 0x40, 0x00, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x88, 0x40, -0x20, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x80, 0x00, 0x88, 0x0A, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A, 0x03, 0x28, 0x0C, -0xA0, 0x30, 0x80, 0xC2, 0x00, 0x4A, 0x01, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, -0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, -0x0C, 0xA0, 0x10, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x00, 0x10, 0x00, 0x06, 0x00, 0x08, 0x01, 0x20, 0x00, 0x80, 0x10, -0x00, 0x02, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, -0x00, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x20, 0x04, 0x88, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, -0x40, 0x40, 0x01, 0x01, 0x04, 0x00, 0x14, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, -0x04, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10, -0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18, -0x00, 0x66, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, -0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80, -0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0x80, 0x02, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x02, 0x80, -0x0B, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x0E, 0x00, -0x98, 0x00, 0xE0, 0x00, 0x90, 0x01, 0x40, 0x06, 0x80, 0x99, 0x00, 0xE0, 0x00, -0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, -0x06, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x05, 0x20, 0x1C, 0x82, -0x70, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20, 0x16, 0x00, 0x70, 0x00, 0x62, 0x01, -0x08, 0x07, 0x28, 0x1C, 0x00, 0x70, 0x00, 0x62, 0x01, 0x18, 0x01, 0x88, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x0C, 0x02, -0x30, 0x0E, 0xC0, 0x20, 0x00, 0xE1, 0x00, 0x0C, 0x02, 0x30, 0x0A, 0xC0, 0x20, -0x00, 0x83, 0x00, 0x04, 0x02, 0x30, 0x08, 0x40, 0x20, 0x00, 0x83, 0x00, 0x0C, -0x02, 0x30, 0x0A, 0x40, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x2A, -0x08, 0xAB, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x28, 0x00, 0xA3, 0x20, 0x8C, -0x02, 0xB0, 0x0A, 0xC2, 0x28, 0x00, 0xA3, 0x00, 0x8C, 0x82, 0xB0, 0x1E, 0xC2, -0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, -0xA2, 0xC2, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1, 0x20, 0x06, -0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0C, 0x62, -0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x1E, 0x62, 0x30, 0x88, 0x01, 0x88, -0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x44, -0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x08, 0x40, -0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62, -0x80, 0x88, 0x11, 0x20, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x11, 0x22, -0x46, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x11, 0x22, 0x46, 0x08, 0x18, 0x40, -0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0xA2, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x80, 0x02, 0x20, -0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x88, 0x02, 0x02, 0x0A, 0x88, 0x28, 0x20, -0xA0, 0x80, 0x88, 0x02, 0x22, 0x0A, 0x08, 0x28, 0x20, 0xA0, 0x40, 0x80, 0x02, -0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04, -0x42, 0x00, 0x28, 0x41, 0x20, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x0A, 0x41, -0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41, 0xA0, 0x04, 0x81, 0x10, -0x04, 0x42, 0x00, 0x08, 0x00, 0xA0, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, -0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20, 0x50, -0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, -0x6D, 0x00, 0x94, 0x28, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0xA2, 0xB2, 0xC0, 0xCA, 0x02, 0x21, 0x0B, 0xAC, 0x2C, 0x10, 0xB2, -0xC0, 0xCA, 0x02, 0x23, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A, -0x0B, 0x84, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A, 0x2B, 0x84, 0x6C, 0xB0, -0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, -0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x98, 0x13, 0x20, 0x4E, 0x80, 0x38, -0x01, 0xE2, 0x04, 0x80, 0x13, 0x60, 0x4E, 0x80, 0x39, 0x01, 0xE6, 0x04, 0x88, -0x13, 0x20, 0x4E, 0x80, 0x38, 0x09, 0xE6, 0x00, 0x89, 0x03, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x02, 0x23, 0x08, -0x8C, 0x21, 0x30, 0x80, 0xC0, 0x10, 0x02, 0x43, 0x08, 0x8C, 0x21, 0x31, 0x84, -0xC4, 0x08, 0x12, 0x63, 0x08, 0x8C, 0x20, 0x31, 0x86, 0xC4, 0x18, 0x12, 0x23, -0x08, 0x8C, 0x20, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, -0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, -0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, -0xBF, 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, 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, 0x34, 0xDB, 0xD0, 0xEC, -0xCB, 0xB7, 0x0D, 0xED, 0x37, 0xFC, 0xDF, 0xD0, 0x6C, 0xC3, 0xB7, 0x0D, 0xED, -0x37, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, -0xEC, 0xCB, 0xB7, 0x2F, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x23, 0xF3, -0x8F, 0xFC, 0x3F, 0x32, 0xF3, 0xC8, 0xCF, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32, -0xF3, 0xC8, 0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x2F, -0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xDC, 0x78, 0x12, 0xFB, 0xC9, 0xED, 0x27, 0xB1, 0x87, 0xDC, 0x7E, 0x12, -0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x9F, 0xDC, 0x1E, 0x72, 0xFB, 0x49, 0xEC, 0x21, -0xB7, 0x9F, 0xDC, 0x7E, 0x72, 0xFB, 0x49, 0xEC, 0x21, 0x37, 0x86, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00, -0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE, -0x50, 0x30, 0x43, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x38, 0x43, 0xE1, -0x0C, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, -0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, -0x00, 0x80, 0x00, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x00, -0x02, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21, -0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, -0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x18, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, -0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, -0xCE, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03, -0xE0, 0x4C, 0x80, 0x00, 0x01, 0xCE, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x30, 0x03, -0x01, 0x00, 0x04, 0x33, 0x10, 0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0xCC, 0x40, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, -0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, -0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, -0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, -0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x33, 0x01, 0x00, 0x04, 0x30, -0x13, 0x00, 0x40, 0x00, 0x33, 0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x01, 0xCC, 0x04, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x38, -0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, -0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x00, 0x54, -0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, -0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x86, 0x04, 0x08, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, -0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, -0x08, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0x84, 0x00, 0x10, 0x86, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x00, 0x00, 0xCE, 0x00, -0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, -0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, -0x00, 0x08, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0x84, 0x33, 0x10, 0x02, 0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x33, 0x10, 0xCE, -0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, -0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00, -0x10, 0x08, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00, -0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x08, 0x00, 0x01, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, -0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x20, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 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, -0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 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, 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, 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, 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, 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, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, -0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, -0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, -0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, -0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01, -0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, -0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, -0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, -0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, -0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, -0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, -0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00, -0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, -0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, -0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, -0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, -0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, -0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, -0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, -0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, -0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, -0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54, -0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, -0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, -0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, -0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, -0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, -0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, -0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00, -0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, -0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, -0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, -0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, -0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, -0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, -0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, -0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, -0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, -0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x3C, 0x3C, 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, 0x00, 0x00, 0x00, 0x00, -0xF0, 0xF0, 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, 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, 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, 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, -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, -0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, -0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, -0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, -0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, -0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 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, 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, 0x0C, 0x00, 0x04, 0x80, -0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xC2, 0x30, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80, 0x40, -0x40, 0x00, 0x00, 0x0C, 0x00, 0xC2, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 0x00, 0x0C, 0x00, -0x00, 0x80, 0x00, 0x00, 0xA4, 0x07, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, -0xC0, 0x0C, 0x00, 0x02, 0x30, 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, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0x5A, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00 -}; -- cgit v1.2.3 From a8fcffbde4cedf319f7009cec21baddf9422685e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Sep 2009 21:29:37 -0700 Subject: Staging: meilhaus: remove the drivers The comedi drivers should be used instead, no need to have these in here as well. Cc: David Kiliani Cc: Meilhaus Support Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/meilhaus/Kconfig | 128 - drivers/staging/meilhaus/Makefile | 43 - drivers/staging/meilhaus/TODO | 10 - drivers/staging/meilhaus/me0600_device.c | 213 - drivers/staging/meilhaus/me0600_device.h | 97 - drivers/staging/meilhaus/me0600_dio.c | 415 -- drivers/staging/meilhaus/me0600_dio.h | 68 - drivers/staging/meilhaus/me0600_dio_reg.h | 41 - drivers/staging/meilhaus/me0600_ext_irq.c | 469 -- drivers/staging/meilhaus/me0600_ext_irq.h | 58 - drivers/staging/meilhaus/me0600_ext_irq_reg.h | 18 - drivers/staging/meilhaus/me0600_optoi.c | 243 - drivers/staging/meilhaus/me0600_optoi.h | 58 - drivers/staging/meilhaus/me0600_optoi_reg.h | 35 - drivers/staging/meilhaus/me0600_relay.c | 359 -- drivers/staging/meilhaus/me0600_relay.h | 63 - drivers/staging/meilhaus/me0600_relay_reg.h | 36 - drivers/staging/meilhaus/me0600_ttli.c | 238 - drivers/staging/meilhaus/me0600_ttli.h | 58 - drivers/staging/meilhaus/me0600_ttli_reg.h | 35 - drivers/staging/meilhaus/me0900_device.c | 178 - drivers/staging/meilhaus/me0900_device.h | 92 - drivers/staging/meilhaus/me0900_di.c | 245 - drivers/staging/meilhaus/me0900_di.h | 65 - drivers/staging/meilhaus/me0900_do.c | 314 -- drivers/staging/meilhaus/me0900_do.h | 68 - drivers/staging/meilhaus/me0900_reg.h | 40 - drivers/staging/meilhaus/me1000_device.c | 206 - drivers/staging/meilhaus/me1000_device.h | 59 - drivers/staging/meilhaus/me1000_dio.c | 438 -- drivers/staging/meilhaus/me1000_dio.h | 71 - drivers/staging/meilhaus/me1000_dio_reg.h | 50 - drivers/staging/meilhaus/me1400_device.c | 253 -- drivers/staging/meilhaus/me1400_device.h | 108 - drivers/staging/meilhaus/me1400_ext_irq.c | 507 --- drivers/staging/meilhaus/me1400_ext_irq.h | 62 - drivers/staging/meilhaus/me1400_ext_irq_reg.h | 56 - drivers/staging/meilhaus/me1600_ao.c | 1017 ----- drivers/staging/meilhaus/me1600_ao.h | 128 - drivers/staging/meilhaus/me1600_ao_reg.h | 66 - drivers/staging/meilhaus/me1600_device.c | 259 -- drivers/staging/meilhaus/me1600_device.h | 101 - drivers/staging/meilhaus/me4600_ai.c | 3405 -------------- drivers/staging/meilhaus/me4600_ai.h | 175 - drivers/staging/meilhaus/me4600_ai_reg.h | 107 - drivers/staging/meilhaus/me4600_ao.c | 5974 ------------------------- drivers/staging/meilhaus/me4600_ao.h | 259 -- drivers/staging/meilhaus/me4600_ao_reg.h | 113 - drivers/staging/meilhaus/me4600_device.c | 371 -- drivers/staging/meilhaus/me4600_device.h | 151 - drivers/staging/meilhaus/me4600_di.c | 256 -- drivers/staging/meilhaus/me4600_di.h | 64 - drivers/staging/meilhaus/me4600_dio.c | 510 --- drivers/staging/meilhaus/me4600_dio.h | 69 - drivers/staging/meilhaus/me4600_dio_reg.h | 63 - drivers/staging/meilhaus/me4600_do.c | 433 -- drivers/staging/meilhaus/me4600_do.h | 65 - drivers/staging/meilhaus/me4600_ext_irq.c | 457 -- drivers/staging/meilhaus/me4600_ext_irq.h | 78 - drivers/staging/meilhaus/me4600_ext_irq_reg.h | 41 - drivers/staging/meilhaus/me4600_reg.h | 46 - drivers/staging/meilhaus/me6000_ao.c | 3709 --------------- drivers/staging/meilhaus/me6000_ao.h | 195 - drivers/staging/meilhaus/me6000_ao_reg.h | 177 - drivers/staging/meilhaus/me6000_device.c | 209 - drivers/staging/meilhaus/me6000_device.h | 149 - drivers/staging/meilhaus/me6000_dio.c | 415 -- drivers/staging/meilhaus/me6000_dio.h | 68 - drivers/staging/meilhaus/me6000_dio_reg.h | 43 - drivers/staging/meilhaus/me6000_reg.h | 35 - drivers/staging/meilhaus/me8100_device.c | 185 - drivers/staging/meilhaus/me8100_device.h | 97 - drivers/staging/meilhaus/me8100_di.c | 684 --- drivers/staging/meilhaus/me8100_di.h | 89 - drivers/staging/meilhaus/me8100_di_reg.h | 47 - drivers/staging/meilhaus/me8100_do.c | 391 -- drivers/staging/meilhaus/me8100_do.h | 70 - drivers/staging/meilhaus/me8100_do_reg.h | 36 - drivers/staging/meilhaus/me8100_reg.h | 41 - drivers/staging/meilhaus/me8200_device.c | 192 - drivers/staging/meilhaus/me8200_device.h | 97 - drivers/staging/meilhaus/me8200_di.c | 832 ---- drivers/staging/meilhaus/me8200_di.h | 92 - drivers/staging/meilhaus/me8200_di_reg.h | 75 - drivers/staging/meilhaus/me8200_dio.c | 418 -- drivers/staging/meilhaus/me8200_dio.h | 68 - drivers/staging/meilhaus/me8200_dio_reg.h | 43 - drivers/staging/meilhaus/me8200_do.c | 591 --- drivers/staging/meilhaus/me8200_do.h | 75 - drivers/staging/meilhaus/me8200_do_reg.h | 40 - drivers/staging/meilhaus/me8200_reg.h | 46 - drivers/staging/meilhaus/me8254.c | 1176 ----- drivers/staging/meilhaus/me8254.h | 80 - drivers/staging/meilhaus/me8254_reg.h | 172 - drivers/staging/meilhaus/me8255.c | 462 -- drivers/staging/meilhaus/me8255.h | 59 - drivers/staging/meilhaus/me8255_reg.h | 50 - drivers/staging/meilhaus/mecirc_buf.h | 131 - drivers/staging/meilhaus/mecommon.h | 26 - drivers/staging/meilhaus/medebug.h | 125 - drivers/staging/meilhaus/medefines.h | 449 -- drivers/staging/meilhaus/medevice.c | 1740 ------- drivers/staging/meilhaus/medevice.h | 304 -- drivers/staging/meilhaus/medlist.c | 127 - drivers/staging/meilhaus/medlist.h | 91 - drivers/staging/meilhaus/medlock.c | 195 - drivers/staging/meilhaus/medlock.h | 76 - drivers/staging/meilhaus/medriver.h | 350 -- drivers/staging/meilhaus/medummy.c | 1264 ------ drivers/staging/meilhaus/medummy.h | 40 - drivers/staging/meilhaus/meerror.h | 100 - drivers/staging/meilhaus/mefirmware.c | 137 - drivers/staging/meilhaus/mefirmware.h | 57 - drivers/staging/meilhaus/meids.h | 31 - drivers/staging/meilhaus/meinternal.h | 363 -- drivers/staging/meilhaus/meioctl.h | 515 --- drivers/staging/meilhaus/memain.c | 2084 --------- drivers/staging/meilhaus/memain.h | 266 -- drivers/staging/meilhaus/meplx_reg.h | 53 - drivers/staging/meilhaus/meslist.c | 173 - drivers/staging/meilhaus/meslist.h | 108 - drivers/staging/meilhaus/meslock.c | 136 - drivers/staging/meilhaus/meslock.h | 73 - drivers/staging/meilhaus/mesubdevice.c | 317 -- drivers/staging/meilhaus/mesubdevice.h | 197 - drivers/staging/meilhaus/metempl_device.c | 135 - drivers/staging/meilhaus/metempl_device.h | 92 - drivers/staging/meilhaus/metempl_sub.c | 149 - drivers/staging/meilhaus/metempl_sub.h | 64 - drivers/staging/meilhaus/metempl_sub_reg.h | 35 - drivers/staging/meilhaus/metypes.h | 95 - 133 files changed, 41014 deletions(-) delete mode 100644 drivers/staging/meilhaus/Kconfig delete mode 100644 drivers/staging/meilhaus/Makefile delete mode 100644 drivers/staging/meilhaus/TODO delete mode 100644 drivers/staging/meilhaus/me0600_device.c delete mode 100644 drivers/staging/meilhaus/me0600_device.h delete mode 100644 drivers/staging/meilhaus/me0600_dio.c delete mode 100644 drivers/staging/meilhaus/me0600_dio.h delete mode 100644 drivers/staging/meilhaus/me0600_dio_reg.h delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq.c delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq.h delete mode 100644 drivers/staging/meilhaus/me0600_ext_irq_reg.h delete mode 100644 drivers/staging/meilhaus/me0600_optoi.c delete mode 100644 drivers/staging/meilhaus/me0600_optoi.h delete mode 100644 drivers/staging/meilhaus/me0600_optoi_reg.h delete mode 100644 drivers/staging/meilhaus/me0600_relay.c delete mode 100644 drivers/staging/meilhaus/me0600_relay.h delete mode 100644 drivers/staging/meilhaus/me0600_relay_reg.h delete mode 100644 drivers/staging/meilhaus/me0600_ttli.c delete mode 100644 drivers/staging/meilhaus/me0600_ttli.h delete mode 100644 drivers/staging/meilhaus/me0600_ttli_reg.h delete mode 100644 drivers/staging/meilhaus/me0900_device.c delete mode 100644 drivers/staging/meilhaus/me0900_device.h delete mode 100644 drivers/staging/meilhaus/me0900_di.c delete mode 100644 drivers/staging/meilhaus/me0900_di.h delete mode 100644 drivers/staging/meilhaus/me0900_do.c delete mode 100644 drivers/staging/meilhaus/me0900_do.h delete mode 100644 drivers/staging/meilhaus/me0900_reg.h delete mode 100644 drivers/staging/meilhaus/me1000_device.c delete mode 100644 drivers/staging/meilhaus/me1000_device.h delete mode 100644 drivers/staging/meilhaus/me1000_dio.c delete mode 100644 drivers/staging/meilhaus/me1000_dio.h delete mode 100644 drivers/staging/meilhaus/me1000_dio_reg.h delete mode 100644 drivers/staging/meilhaus/me1400_device.c delete mode 100644 drivers/staging/meilhaus/me1400_device.h delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq.c delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq.h delete mode 100644 drivers/staging/meilhaus/me1400_ext_irq_reg.h delete mode 100644 drivers/staging/meilhaus/me1600_ao.c delete mode 100644 drivers/staging/meilhaus/me1600_ao.h delete mode 100644 drivers/staging/meilhaus/me1600_ao_reg.h delete mode 100644 drivers/staging/meilhaus/me1600_device.c delete mode 100644 drivers/staging/meilhaus/me1600_device.h delete mode 100644 drivers/staging/meilhaus/me4600_ai.c delete mode 100644 drivers/staging/meilhaus/me4600_ai.h delete mode 100644 drivers/staging/meilhaus/me4600_ai_reg.h delete mode 100644 drivers/staging/meilhaus/me4600_ao.c delete mode 100644 drivers/staging/meilhaus/me4600_ao.h delete mode 100644 drivers/staging/meilhaus/me4600_ao_reg.h delete mode 100644 drivers/staging/meilhaus/me4600_device.c delete mode 100644 drivers/staging/meilhaus/me4600_device.h delete mode 100644 drivers/staging/meilhaus/me4600_di.c delete mode 100644 drivers/staging/meilhaus/me4600_di.h delete mode 100644 drivers/staging/meilhaus/me4600_dio.c delete mode 100644 drivers/staging/meilhaus/me4600_dio.h delete mode 100644 drivers/staging/meilhaus/me4600_dio_reg.h delete mode 100644 drivers/staging/meilhaus/me4600_do.c delete mode 100644 drivers/staging/meilhaus/me4600_do.h delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq.c delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq.h delete mode 100644 drivers/staging/meilhaus/me4600_ext_irq_reg.h delete mode 100644 drivers/staging/meilhaus/me4600_reg.h delete mode 100644 drivers/staging/meilhaus/me6000_ao.c delete mode 100644 drivers/staging/meilhaus/me6000_ao.h delete mode 100644 drivers/staging/meilhaus/me6000_ao_reg.h delete mode 100644 drivers/staging/meilhaus/me6000_device.c delete mode 100644 drivers/staging/meilhaus/me6000_device.h delete mode 100644 drivers/staging/meilhaus/me6000_dio.c delete mode 100644 drivers/staging/meilhaus/me6000_dio.h delete mode 100644 drivers/staging/meilhaus/me6000_dio_reg.h delete mode 100644 drivers/staging/meilhaus/me6000_reg.h delete mode 100644 drivers/staging/meilhaus/me8100_device.c delete mode 100644 drivers/staging/meilhaus/me8100_device.h delete mode 100644 drivers/staging/meilhaus/me8100_di.c delete mode 100644 drivers/staging/meilhaus/me8100_di.h delete mode 100644 drivers/staging/meilhaus/me8100_di_reg.h delete mode 100644 drivers/staging/meilhaus/me8100_do.c delete mode 100644 drivers/staging/meilhaus/me8100_do.h delete mode 100644 drivers/staging/meilhaus/me8100_do_reg.h delete mode 100644 drivers/staging/meilhaus/me8100_reg.h delete mode 100644 drivers/staging/meilhaus/me8200_device.c delete mode 100644 drivers/staging/meilhaus/me8200_device.h delete mode 100644 drivers/staging/meilhaus/me8200_di.c delete mode 100644 drivers/staging/meilhaus/me8200_di.h delete mode 100644 drivers/staging/meilhaus/me8200_di_reg.h delete mode 100644 drivers/staging/meilhaus/me8200_dio.c delete mode 100644 drivers/staging/meilhaus/me8200_dio.h delete mode 100644 drivers/staging/meilhaus/me8200_dio_reg.h delete mode 100644 drivers/staging/meilhaus/me8200_do.c delete mode 100644 drivers/staging/meilhaus/me8200_do.h delete mode 100644 drivers/staging/meilhaus/me8200_do_reg.h delete mode 100644 drivers/staging/meilhaus/me8200_reg.h delete mode 100644 drivers/staging/meilhaus/me8254.c delete mode 100644 drivers/staging/meilhaus/me8254.h delete mode 100644 drivers/staging/meilhaus/me8254_reg.h delete mode 100644 drivers/staging/meilhaus/me8255.c delete mode 100644 drivers/staging/meilhaus/me8255.h delete mode 100644 drivers/staging/meilhaus/me8255_reg.h delete mode 100644 drivers/staging/meilhaus/mecirc_buf.h delete mode 100644 drivers/staging/meilhaus/mecommon.h delete mode 100644 drivers/staging/meilhaus/medebug.h delete mode 100644 drivers/staging/meilhaus/medefines.h delete mode 100644 drivers/staging/meilhaus/medevice.c delete mode 100644 drivers/staging/meilhaus/medevice.h delete mode 100644 drivers/staging/meilhaus/medlist.c delete mode 100644 drivers/staging/meilhaus/medlist.h delete mode 100644 drivers/staging/meilhaus/medlock.c delete mode 100644 drivers/staging/meilhaus/medlock.h delete mode 100644 drivers/staging/meilhaus/medriver.h delete mode 100644 drivers/staging/meilhaus/medummy.c delete mode 100644 drivers/staging/meilhaus/medummy.h delete mode 100644 drivers/staging/meilhaus/meerror.h delete mode 100644 drivers/staging/meilhaus/mefirmware.c delete mode 100644 drivers/staging/meilhaus/mefirmware.h delete mode 100644 drivers/staging/meilhaus/meids.h delete mode 100644 drivers/staging/meilhaus/meinternal.h delete mode 100644 drivers/staging/meilhaus/meioctl.h delete mode 100644 drivers/staging/meilhaus/memain.c delete mode 100644 drivers/staging/meilhaus/memain.h delete mode 100644 drivers/staging/meilhaus/meplx_reg.h delete mode 100644 drivers/staging/meilhaus/meslist.c delete mode 100644 drivers/staging/meilhaus/meslist.h delete mode 100644 drivers/staging/meilhaus/meslock.c delete mode 100644 drivers/staging/meilhaus/meslock.h delete mode 100644 drivers/staging/meilhaus/mesubdevice.c delete mode 100644 drivers/staging/meilhaus/mesubdevice.h delete mode 100644 drivers/staging/meilhaus/metempl_device.c delete mode 100644 drivers/staging/meilhaus/metempl_device.h delete mode 100644 drivers/staging/meilhaus/metempl_sub.c delete mode 100644 drivers/staging/meilhaus/metempl_sub.h delete mode 100644 drivers/staging/meilhaus/metempl_sub_reg.h delete mode 100644 drivers/staging/meilhaus/metypes.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d76f6b356de..982e9445606 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -47,8 +47,6 @@ source "drivers/staging/slicoss/Kconfig" source "drivers/staging/sxg/Kconfig" -source "drivers/staging/meilhaus/Kconfig" - source "drivers/staging/go7007/Kconfig" source "drivers/staging/usbip/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 01bf2284520..4eabb440a18 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_SXG) += sxg/ -obj-$(CONFIG_MEILHAUS) += meilhaus/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig deleted file mode 100644 index 923af22a468..00000000000 --- a/drivers/staging/meilhaus/Kconfig +++ /dev/null @@ -1,128 +0,0 @@ -# -# Meilhaus configuration -# - -menuconfig MEILHAUS - tristate "Meilhaus support" - depends on m - ---help--- - If you have a Meilhaus card, say Y (or M) here. - - You need both this driver, and the driver for the particular - data collection card. - - To compile this driver as a module, choose M here. The module will - be called memain. - -if MEILHAUS - -config ME0600 - tristate "Meilhaus ME-600 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-600 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me0600. - -config ME0900 - tristate "Meilhaus ME-900 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-900 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me0900. - -config ME1000 - tristate "Meilhaus ME-1000 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-1000 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me1000. - -config ME1400 - tristate "Meilhaus ME-1400 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-1400 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me1400. - -config ME1600 - tristate "Meilhaus ME-1600 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-1600 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me1600. - -config ME4600 - tristate "Meilhaus ME-4600 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-4600 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me4600. - -config ME6000 - tristate "Meilhaus ME-6000 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-6000 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me6000. - -config ME8100 - tristate "Meilhaus ME-8100 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-8100 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me8100. - -config ME8200 - tristate "Meilhaus ME-8200 support" - default n - depends on PCI && m - help - This driver supports the Meilhaus ME-8200 family of boards - that do data collection and multipurpose I/O. - - To compile this driver as a module, choose M here: the module - will be called me8200. - -config MEDUMMY - tristate "Meilhaus dummy driver" - default n - depends on PCI && m - help - This provides a dummy driver for the Meilhaus driver package - - To compile this driver as a module, choose M here: the module - will be called medummy. - -endif # MEILHAUS diff --git a/drivers/staging/meilhaus/Makefile b/drivers/staging/meilhaus/Makefile deleted file mode 100644 index 5ab2c1c9c86..00000000000 --- a/drivers/staging/meilhaus/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# Makefile for Meilhaus linux driver system -# - -obj-$(CONFIG_MEILHAUS) += memain.o -obj-$(CONFIG_ME1600) += me1600.o -obj-$(CONFIG_ME1000) += me1000.o -obj-$(CONFIG_ME1400) += me1400.o -obj-$(CONFIG_ME4600) += me4600.o -obj-$(CONFIG_ME6000) += me6000.o -obj-$(CONFIG_ME0600) += me0600.o -obj-$(CONFIG_ME8100) += me8100.o -obj-$(CONFIG_ME8200) += me8200.o -obj-$(CONFIG_ME0900) += me0900.o -obj-$(CONFIG_MEDUMMY) += medummy.o - - -me1600-objs := medevice.o medlist.o medlock.o me1600_device.o -me1600-objs += mesubdevice.o meslist.o meslock.o me1600_ao.o - -me1000-objs := medevice.o medlist.o medlock.o me1000_device.o -me1000-objs += mesubdevice.o meslist.o meslock.o me1000_dio.o - -me1400-objs := medevice.o medlist.o medlock.o me1400_device.o -me1400-objs += mesubdevice.o meslist.o meslock.o me8254.o me8255.o me1400_ext_irq.o - -me4600-objs := medevice.o medlist.o medlock.o mefirmware.o me4600_device.o -me4600-objs += mesubdevice.o meslist.o meslock.o me4600_do.o me4600_di.o me4600_dio.o me8254.o me4600_ai.o me4600_ao.o me4600_ext_irq.o - -me6000-objs := medevice.o medlist.o medlock.o mefirmware.o me6000_device.o -me6000-objs += mesubdevice.o meslist.o meslock.o me6000_dio.o me6000_ao.o - -me0600-objs := medevice.o medlist.o medlock.o me0600_device.o -me0600-objs += mesubdevice.o meslist.o meslock.o me0600_relay.o me0600_ttli.o me0600_optoi.o me0600_dio.o me0600_ext_irq.o - -me8100-objs := medevice.o medlist.o medlock.o me8100_device.o -me8100-objs += mesubdevice.o meslist.o meslock.o me8100_di.o me8100_do.o me8254.o - -me8200-objs := medevice.o medlist.o medlock.o me8200_device.o -me8200-objs += mesubdevice.o meslist.o meslock.o me8200_di.o me8200_do.o me8200_dio.o - -me0900-objs := medevice.o medlist.o medlock.o me0900_device.o -me0900-objs += mesubdevice.o meslist.o meslock.o me0900_do.o me0900_di.o diff --git a/drivers/staging/meilhaus/TODO b/drivers/staging/meilhaus/TODO deleted file mode 100644 index d6ce39823de..00000000000 --- a/drivers/staging/meilhaus/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - checkpatch.pl cleanups - - sparse issues - - Lindent - - audit userspace interface - - handle firmware properly - - possible comedi merge - -Please send cleanup patches to Greg Kroah-Hartman -and CC: David Kiliani and Meilhaus Support diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c deleted file mode 100644 index bae17d26416..00000000000 --- a/drivers/staging/meilhaus/me0600_device.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file me0600_device.c - * - * @brief ME-630 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "me0600_device.h" -#include "mesubdevice.h" -#include "me0600_relay.h" -#include "me0600_ttli.h" -#include "me0600_optoi.h" -#include "me0600_dio.h" -#include "me0600_ext_irq.h" - -me_device_t *me0600_pci_constructor(struct pci_dev *pci_device) -{ - me0600_device_t *me0600_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me0600_device = kmalloc(sizeof(me0600_device_t), GFP_KERNEL); - - if (!me0600_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me0600_device, 0, sizeof(me0600_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me0600_device, pci_device); - - if (err) { - kfree(me0600_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - me0600_versions_get_device_index(me0600_device->base.info.pci. - device_id); - - // Initialize spin lock . - spin_lock_init(&me0600_device->dio_ctrl_reg_lock); - spin_lock_init(&me0600_device->intcsr_lock); - - // Create subdevice instances. - - for (i = 0; i < me0600_versions[version_idx].optoi_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0600_optoi_constructor(me0600_device-> - base.info.pci. - reg_bases[2]); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0600_device); - kfree(me0600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0600_device->base.slist, - subdevice); - } - - for (i = 0; i < me0600_versions[version_idx].relay_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0600_relay_constructor(me0600_device-> - base.info.pci. - reg_bases[2]); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0600_device); - kfree(me0600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0600_device->base.slist, - subdevice); - } - - for (i = 0; i < me0600_versions[version_idx].ttli_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0600_ttli_constructor(me0600_device-> - base.info.pci. - reg_bases[2]); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0600_device); - kfree(me0600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0600_device->base.slist, - subdevice); - } - - for (i = 0; i < me0600_versions[version_idx].dio_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0600_dio_constructor(me0600_device-> - base.info.pci. - reg_bases[2], i, - &me0600_device-> - dio_ctrl_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0600_device); - kfree(me0600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0600_device->base.slist, - subdevice); - } - - for (i = 0; i < me0600_versions[version_idx].ext_irq_subdevices; i++) { - subdevice = - (me_subdevice_t *) - me0600_ext_irq_constructor(me0600_device->base.info.pci. - reg_bases[1], - me0600_device->base.info.pci. - reg_bases[2], - &me0600_device->intcsr_lock, i, - me0600_device->base.irq); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0600_device); - kfree(me0600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0600_device->base.slist, - subdevice); - } - - return (me_device_t *) me0600_device; -} -EXPORT_SYMBOL(me0600_pci_constructor); - -// Init and exit of module. - -static int __init me0600_init(void) -{ - PDEBUG("executed.\n"); - return 0; -} - -static void __exit me0600_exit(void) -{ - PDEBUG("executed.\n"); -} - -module_init(me0600_init); - -module_exit(me0600_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me0600_device.h b/drivers/staging/meilhaus/me0600_device.h deleted file mode 100644 index 75bd3b7351d..00000000000 --- a/drivers/staging/meilhaus/me0600_device.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file me0600_device.h - * - * @brief ME-630 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_DEVICE_H -#define _ME0600_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-630 device capabilities. - */ -typedef struct me0600_version { - uint16_t device_id; - unsigned int relay_subdevices; - unsigned int ttli_subdevices; - unsigned int optoi_subdevices; - unsigned int dio_subdevices; - unsigned int ext_irq_subdevices; -} me0600_version_t; - -/** - * @brief Device capabilities. - */ -static me0600_version_t me0600_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME0630, 1, 1, 1, 2, 2}, - {0}, -}; - -#define ME0600_DEVICE_VERSIONS (ARRAY_SIZE(me0600_versions) - 1) /**< Returns the number of entries in #me0600_versions. */ - -/** - * @brief Returns the index of the device entry in #me0600_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me0600_versions. - */ -static inline unsigned int me0600_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME0600_DEVICE_VERSIONS; i++) - if (me0600_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-630 device class structure. - */ -typedef struct me0600_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t dio_ctrl_reg_lock; - spinlock_t intcsr_lock; -} me0600_device_t; - -/** - * @brief The ME-630 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-630 device instance. \n - * NULL on error. - */ -me_device_t *me0600_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c deleted file mode 100644 index d29303518be..00000000000 --- a/drivers/staging/meilhaus/me0600_dio.c +++ /dev/null @@ -1,415 +0,0 @@ -/** - * @file me0600_dio.c - * - * @brief ME-630 digital input/output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me0600_dio_reg.h" -#include "me0600_dio.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me0600_dio_subdevice_t *instance; - uint8_t mode; - - PDEBUG("executed.\n"); - - instance = (me0600_dio_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - mode &= ~(0x3 << (instance->dio_idx * 2)); - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - - outb(0x00, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0x00); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me0600_dio_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me0600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - int size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - - PDEBUG("executed.\n"); - - instance = (me0600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - mode &= - ~((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - mode &= - ~((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - mode |= - ME0600_DIO_CONFIG_BIT_OUT_0 << (instance-> - dio_idx * - 2); - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_dio_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - - PDEBUG("executed.\n"); - - instance = (me0600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - - if ((mode == - (ME0600_DIO_CONFIG_BIT_OUT_0 << - (instance->dio_idx * 2))) || !mode) { - *value = - inb(instance-> - port_reg) & (0x0001 << channel); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - - if ((mode == - (ME0600_DIO_CONFIG_BIT_OUT_0 << - (instance->dio_idx * 2))) || !mode) { - *value = inb(instance->port_reg) & 0x00FF; - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - - break; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_dio_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me0600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - uint8_t byte; - - PDEBUG("executed.\n"); - - instance = (me0600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - - if (mode == - (ME0600_DIO_CONFIG_BIT_OUT_0 << - (instance->dio_idx * 2))) { - byte = inb(instance->port_reg); - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outb(byte, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) << - (instance->dio_idx * 2)); - - if (mode == - (ME0600_DIO_CONFIG_BIT_OUT_0 << - (instance->dio_idx * 2))) { - outb(value, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - - break; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_dio_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_DIR_BYTE; - return ME_ERRNO_SUCCESS; -} - -me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t *ctrl_reg_lock) -{ - me0600_dio_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0600_dio_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0600_dio_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - /* Initialize spin locks. */ - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save digital i/o index */ - subdevice->dio_idx = dio_idx; - - /* Save the subdevice index */ - subdevice->ctrl_reg = reg_base + ME0600_DIO_CONFIG_REG; - subdevice->port_reg = reg_base + ME0600_DIO_PORT_REG + dio_idx; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0600_dio_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0600_dio_io_single_config; - subdevice->base.me_subdevice_io_single_read = me0600_dio_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me0600_dio_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me0600_dio_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0600_dio_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0600_dio_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0600_dio.h b/drivers/staging/meilhaus/me0600_dio.h deleted file mode 100644 index 5d075c7d688..00000000000 --- a/drivers/staging/meilhaus/me0600_dio.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file me0600_dio.h - * - * @brief ME-630 digital input/output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_DIO_H_ -#define _ME0600_DIO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0600_dio_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - unsigned int dio_idx; /**< The index of the digital i/o on the device. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me0600_dio_subdevice_t; - -/** - * @brief The constructor to generate a ME-630 digital input/ouput subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param dio_idx The index of the digital i/o port on the device. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_dio_reg.h b/drivers/staging/meilhaus/me0600_dio_reg.h deleted file mode 100644 index f116ea3b79d..00000000000 --- a/drivers/staging/meilhaus/me0600_dio_reg.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file me0600_dio_reg.h - * - * @brief ME-630 digital input/output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_DIO_REG_H_ -#define _ME0600_DIO_REG_H_ - -#ifdef __KERNEL__ - -#define ME0600_DIO_CONFIG_REG 0x0007 -#define ME0600_DIO_PORT_0_REG 0x0008 -#define ME0600_DIO_PORT_1_REG 0x0009 -#define ME0600_DIO_PORT_REG ME0600_DIO_PORT_0_REG - -#define ME0600_DIO_CONFIG_BIT_OUT_0 0x0001 -#define ME0600_DIO_CONFIG_BIT_OUT_1 0x0004 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c deleted file mode 100644 index 1d098420a54..00000000000 --- a/drivers/staging/meilhaus/me0600_ext_irq.c +++ /dev/null @@ -1,469 +0,0 @@ -/** - * @file me0600_ext_irq.c - * - * @brief ME-630 external interrupt subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "meids.h" -#include "medebug.h" - -#include "meplx_reg.h" -#include "me0600_ext_irq_reg.h" -#include "me0600_ext_irq.h" - -/* - * Functions - */ - -static int me0600_ext_irq_io_irq_start(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me0600_ext_irq_subdevice_t *instance; - uint32_t tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me0600_ext_irq_subdevice_t *) subdevice; - - if (flags & ~ME_IO_IRQ_START_DIO_BIT) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (instance->lintno > 1) { - PERROR("Wrong idx=%d.\n", instance->lintno); - return ME_ERRNO_INVALID_SUBDEVICE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (irq_source != ME_IRQ_SOURCE_DIO_LINE) { - PERROR("Invalid irq source specified.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - if (irq_edge != ME_IRQ_EDGE_RISING) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->intcsr_lock); - tmp = inl(instance->intcsr); - switch (instance->lintno) { - case 0: - tmp |= - PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL | - PLX_INTCSR_PCI_INT_EN; - break; - case 1: - tmp |= - PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL | - PLX_INTCSR_PCI_INT_EN; - break; - } - outl(tmp, instance->intcsr); - PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp); - spin_unlock(instance->intcsr_lock); - instance->rised = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me0600_ext_irq_io_irq_wait(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me0600_ext_irq_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me0600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - (instance->rised != - 0), t); - - if (t == 0) { - PERROR("Wait on interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - instance->rised = 0; - *irq_count = instance->n; - *value = 1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_ext_irq_io_irq_stop(struct me_subdevice *subdevice, - struct file *filep, - int channel, int flags) -{ - me0600_ext_irq_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me0600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (instance->lintno > 1) { - PERROR("Wrong idx=%d.\n", instance->lintno); - return ME_ERRNO_INVALID_SUBDEVICE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->intcsr_lock); - tmp = inl(instance->intcsr); - switch (instance->lintno) { - case 0: - tmp &= ~PLX_INTCSR_LOCAL_INT1_EN; - break; - case 1: - tmp &= ~PLX_INTCSR_LOCAL_INT2_EN; - break; - } - outl(tmp, instance->intcsr); - PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp); - spin_unlock(instance->intcsr_lock); - instance->rised = -1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me0600_ext_irq_subdevice_t *instance; - uint32_t tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me0600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->intcsr_lock); - tmp = inl(instance->intcsr); - switch (instance->lintno) { - case 0: - tmp |= PLX_INTCSR_LOCAL_INT1_POL | PLX_INTCSR_PCI_INT_EN; - tmp &= ~PLX_INTCSR_LOCAL_INT1_EN; - break; - case 1: - tmp |= PLX_INTCSR_LOCAL_INT2_POL | PLX_INTCSR_PCI_INT_EN; - tmp &= ~PLX_INTCSR_LOCAL_INT2_EN; - break; - } - outl(tmp, instance->intcsr); - PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp); - spin_unlock(instance->intcsr_lock); - - instance->rised = -1; - instance->n = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me0600_ext_irq_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 1; - return ME_ERRNO_SUCCESS; -} - -static int me0600_ext_irq_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_EXT_IRQ; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0600_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_EXT_IRQ_EDGE_RISING; - return ME_ERRNO_SUCCESS; -} - -static void me0600_ext_irq_destructor(struct me_subdevice *subdevice) -{ - me0600_ext_irq_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me0600_ext_irq_subdevice_t *) subdevice; - - free_irq(instance->irq, (void *)instance); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -static irqreturn_t me0600_isr(int irq, void *dev_id) -{ - me0600_ext_irq_subdevice_t *instance; - uint32_t status; - uint32_t mask = PLX_INTCSR_PCI_INT_EN; - irqreturn_t ret = IRQ_HANDLED; - - instance = (me0600_ext_irq_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - if (instance->lintno > 1) { - PERROR_CRITICAL - ("%s():Wrong subdevice index=%d plx:irq_status_reg=0x%04X.\n", - __func__, instance->lintno, inl(instance->intcsr)); - return IRQ_NONE; - } - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->intcsr_lock); - status = inl(instance->intcsr); - switch (instance->lintno) { - case 0: - mask |= PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_LOCAL_INT1_EN; - break; - case 1: - mask |= PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_LOCAL_INT2_EN; - break; - } - - if ((status & mask) == mask) { - instance->rised = 1; - instance->n++; - inb(instance->reset_reg); - PDEBUG("Interrupt detected.\n"); - } else { - PINFO - ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n", - jiffies, __func__, status); - ret = IRQ_NONE; - } - spin_unlock(instance->intcsr_lock); - spin_unlock(&instance->subdevice_lock); - - wake_up_interruptible_all(&instance->wait_queue); - - return ret; -} - -me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base, - uint32_t me0600_reg_base, - spinlock_t *intcsr_lock, - unsigned ext_irq_idx, - int irq) -{ - me0600_ext_irq_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0600_ext_irq_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for 630_ext_irq instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0600_ext_irq_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->intcsr_lock = intcsr_lock; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - subdevice->lintno = ext_irq_idx; - - /* Request interrupt line */ - subdevice->irq = irq; - - err = request_irq(subdevice->irq, me0600_isr, - IRQF_DISABLED | IRQF_SHARED, - ME0600_NAME, (void *)subdevice); - - if (err) { - PERROR("Cannot get interrupt line.\n"); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - - /* Initialize registers */ - subdevice->intcsr = plx_reg_base + PLX_INTCSR; - subdevice->reset_reg = - me0600_reg_base + ME0600_INT_0_RESET_REG + ext_irq_idx; - - /* Initialize the subdevice methods */ - subdevice->base.me_subdevice_io_irq_start = me0600_ext_irq_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me0600_ext_irq_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me0600_ext_irq_io_irq_stop; - subdevice->base.me_subdevice_io_reset_subdevice = - me0600_ext_irq_io_reset_subdevice; - subdevice->base.me_subdevice_query_number_channels = - me0600_ext_irq_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0600_ext_irq_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0600_ext_irq_query_subdevice_caps; - subdevice->base.me_subdevice_destructor = me0600_ext_irq_destructor; - - subdevice->rised = 0; - subdevice->n = 0; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0600_ext_irq.h b/drivers/staging/meilhaus/me0600_ext_irq.h deleted file mode 100644 index f5f2204b49a..00000000000 --- a/drivers/staging/meilhaus/me0600_ext_irq.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file me0600_ext_irq.h - * - * @brief ME-630 external interrupt implementation. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME0600_EXT_IRQ_H_ -#define _ME0600_EXT_IRQ_H_ - -#include - -#include "mesubdevice.h" -#include "meslock.h" - -#ifdef __KERNEL__ - -/** - * @brief The ME-630 external interrupt subdevice class. - */ -typedef struct me0600_ext_irq_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *intcsr_lock; /**< Spin lock to protect #intcsr. */ - - wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */ - - int irq; /**< The irq number assigned by PCI BIOS. */ - int rised; /**< If true an interrupt has occured. */ - unsigned int n; /**< The number of interrupt since the driver was loaded. */ - unsigned int lintno; /**< The number of the local PCI interrupt. */ - - uint32_t intcsr; /**< The PLX interrupt control and status register. */ - uint32_t reset_reg; /**< The control register. */ -} me0600_ext_irq_subdevice_t; - -/** - * @brief The constructor to generate a ME-630 external interrupt instance. - * - * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS. - * @param me0600_reg_base The register base address of the ME-630 device as returned by the PCI BIOS. - * @param irq The irq assigned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base, - uint32_t me0600_reg_base, - spinlock_t * intcsr_lock, - unsigned int ext_irq_idx, - int irq); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_ext_irq_reg.h b/drivers/staging/meilhaus/me0600_ext_irq_reg.h deleted file mode 100644 index f6198fa6d2b..00000000000 --- a/drivers/staging/meilhaus/me0600_ext_irq_reg.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @file me0600_ext_irq_reg.h - * - * @brief ME-630 external interrupt register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME0600_EXT_IRQ_REG_H_ -#define _ME0600_EXT_IRQ_REG_H_ - -#ifdef __KERNEL__ - -#define ME0600_INT_0_RESET_REG 0x0005 -#define ME0600_INT_1_RESET_REG 0x0006 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c deleted file mode 100644 index 43f710ffd27..00000000000 --- a/drivers/staging/meilhaus/me0600_optoi.c +++ /dev/null @@ -1,243 +0,0 @@ -/** - * @file me0600_optoi.c - * - * @brief ME-630 Optoisolated input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me0600_optoi_reg.h" -#include "me0600_optoi.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - PDEBUG("executed.\n"); - return ME_ERRNO_SUCCESS; -} - -static int me0600_optoi_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, - int trig_edge, int flags) -{ - me0600_optoi_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_optoi_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) { - PERROR("Invalid port direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - - break; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_optoi_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0600_optoi_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_optoi_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base) -{ - me0600_optoi_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - /* Initialize spin locks. */ - spin_lock_init(&subdevice->subdevice_lock); - - /* Save the subdevice index */ - subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG; - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0600_optoi_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0600_optoi_io_single_config; - subdevice->base.me_subdevice_io_single_read = - me0600_optoi_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me0600_optoi_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0600_optoi_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0600_optoi_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0600_optoi.h b/drivers/staging/meilhaus/me0600_optoi.h deleted file mode 100644 index e7e69bcde9c..00000000000 --- a/drivers/staging/meilhaus/me0600_optoi.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file me0600_optoi.h - * - * @brief ME-630 Optoisolated input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_OPTOI_H_ -#define _ME0600_OPTOI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0600_optoi_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - uint32_t port_reg; /**< Register holding the port status. */ -} me0600_optoi_subdevice_t; - -/** - * @brief The constructor to generate a ME-630 Optoisolated input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_optoi_reg.h b/drivers/staging/meilhaus/me0600_optoi_reg.h deleted file mode 100644 index e0bc4505400..00000000000 --- a/drivers/staging/meilhaus/me0600_optoi_reg.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file me0600_optoi_reg.h - * - * @brief ME-630 Optoisolated input subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_OPTOI_REG_H_ -#define _ME0600_OPTOI_REG_H_ - -#ifdef __KERNEL__ - -#define ME0600_OPTO_INPUT_REG 0x0004 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c deleted file mode 100644 index 03835e3df25..00000000000 --- a/drivers/staging/meilhaus/me0600_relay.c +++ /dev/null @@ -1,359 +0,0 @@ -/** - * @file me0600_relay.c - * - * @brief ME-630 relay subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me0600_relay_reg.h" -#include "me0600_relay.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me0600_relay_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me0600_relay_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - outb(0x0, instance->port_0_reg); - PDEBUG_REG("port_0_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_0_reg - instance->reg_base, 0); - outb(0x0, instance->port_1_reg); - PDEBUG_REG("port_1_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_1_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me0600_relay_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, - int trig_edge, int flags) -{ - me0600_relay_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_relay_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_WORD: - if (channel == 0) { - if (single_config != ME_SINGLE_CONFIG_DIO_OUTPUT) { - PERROR("Invalid word direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - - break; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_relay_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0600_relay_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_relay_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_0_reg) & (0x1 << channel); - } else if ((channel >= 8) && (channel < 16)) { - *value = - inb(instance->port_1_reg) & (0x1 << (channel - 8)); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_0_reg); - } else if (channel == 1) { - *value = inb(instance->port_1_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_WORD: - if (channel == 0) { - *value = (uint32_t) inb(instance->port_1_reg) << 8; - *value |= inb(instance->port_0_reg); - } else { - PERROR("Invalid word number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_relay_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me0600_relay_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t state; - - PDEBUG("executed.\n"); - - instance = (me0600_relay_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - state = inb(instance->port_0_reg); - state = - value ? (state | (0x1 << channel)) : (state & - ~(0x1 << - channel)); - outb(state, instance->port_0_reg); - } else if ((channel >= 8) && (channel < 16)) { - state = inb(instance->port_1_reg); - state = - value ? (state | (0x1 << (channel - 8))) : (state & - ~(0x1 << - (channel - - - 8))); - outb(state, instance->port_1_reg); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - outb(value, instance->port_0_reg); - } else if (channel == 1) { - outb(value, instance->port_1_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_WORD: - if (channel == 0) { - outb(value, instance->port_0_reg); - outb(value >> 8, instance->port_1_reg); - } else { - PERROR("Invalid word number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - break; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_relay_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 16; - return ME_ERRNO_SUCCESS; -} - -static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base) -{ - me0600_relay_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0600_relay_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0600_relay_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - /* Save the subdevice index */ - subdevice->port_0_reg = reg_base + ME0600_RELAIS_0_REG; - subdevice->port_1_reg = reg_base + ME0600_RELAIS_1_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0600_relay_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0600_relay_io_single_config; - subdevice->base.me_subdevice_io_single_read = - me0600_relay_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me0600_relay_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me0600_relay_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0600_relay_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0600_relay_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0600_relay.h b/drivers/staging/meilhaus/me0600_relay.h deleted file mode 100644 index 2ce7dcab8b3..00000000000 --- a/drivers/staging/meilhaus/me0600_relay.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file me0600_relay.h - * - * @brief ME-630 relay subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_RELAY_H_ -#define _ME0600_RELAY_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0600_relay_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - unsigned long port_0_reg; /**< Register holding the port status. */ - unsigned long port_1_reg; /**< Register holding the port status. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me0600_relay_subdevice_t; - -/** - * @brief The constructor to generate a ME-630 relay subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_relay_reg.h b/drivers/staging/meilhaus/me0600_relay_reg.h deleted file mode 100644 index ba4db2e223c..00000000000 --- a/drivers/staging/meilhaus/me0600_relay_reg.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file me0600_relay_reg.h - * - * @brief ME-630 relay subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_RELAY_REG_H_ -#define _ME0600_RELAY_REG_H_ - -#ifdef __KERNEL__ - -#define ME0600_RELAIS_0_REG 0x0001 -#define ME0600_RELAIS_1_REG 0x0002 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c deleted file mode 100644 index 7d970f584cc..00000000000 --- a/drivers/staging/meilhaus/me0600_ttli.c +++ /dev/null @@ -1,238 +0,0 @@ -/** - * @file me0600_ttli.c - * - * @brief ME-630 TTL input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me0600_ttli_reg.h" -#include "me0600_ttli.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - PDEBUG("executed.\n"); - return ME_ERRNO_SUCCESS; -} - -static int me0600_ttli_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me0600_ttli_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_ttli_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) { - PERROR("Invalid port direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - - break; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_ttli_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0600_ttli_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0600_ttli_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base) -{ - me0600_ttli_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0600_ttli_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0600_ttli_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - /* Save the subdevice index */ - subdevice->port_reg = reg_base + ME0600_TTL_INPUT_REG; - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0600_ttli_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0600_ttli_io_single_config; - subdevice->base.me_subdevice_io_single_read = - me0600_ttli_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me0600_ttli_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0600_ttli_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0600_ttli_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0600_ttli.h b/drivers/staging/meilhaus/me0600_ttli.h deleted file mode 100644 index 6c903961486..00000000000 --- a/drivers/staging/meilhaus/me0600_ttli.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file me0600_ttli.h - * - * @brief ME-630 TTL input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_TTLI_H_ -#define _ME0600_TTLI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0600_ttli_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - uint32_t port_reg; /**< Register holding the port status. */ -} me0600_ttli_subdevice_t; - -/** - * @brief The constructor to generate a ME-630 TTL input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0600_ttli_reg.h b/drivers/staging/meilhaus/me0600_ttli_reg.h deleted file mode 100644 index 4f986d16093..00000000000 --- a/drivers/staging/meilhaus/me0600_ttli_reg.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file me0600_ttli_reg.h - * - * @brief ME-630 TTL input subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0600_TTLI_REG_H_ -#define _ME0600_TTLI_REG_H_ - -#ifdef __KERNEL__ - -#define ME0600_TTL_INPUT_REG 0x0003 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c deleted file mode 100644 index e9c6884b5d2..00000000000 --- a/drivers/staging/meilhaus/me0900_device.c +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file me0900_device.c - * - * @brief ME-9x device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) -*/ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "me0900_device.h" -#include "me0900_reg.h" -#include "mesubdevice.h" -#include "me0900_do.h" -#include "me0900_di.h" - -me_device_t *me0900_pci_constructor(struct pci_dev *pci_device) -{ - me0900_device_t *me0900_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - int port_shift; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me0900_device = kmalloc(sizeof(me0900_device_t), GFP_KERNEL); - - if (!me0900_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me0900_device, 0, sizeof(me0900_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me0900_device, pci_device); - - if (err) { - kfree(me0900_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - me0900_versions_get_device_index(me0900_device->base.info.pci. - device_id); - - /* Initialize 8255 chip to desired mode */ - if (me0900_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME0940) { - outb(0x9B, - me0900_device->base.info.pci.reg_bases[2] + - ME0900_CTRL_REG); - } else if (me0900_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME0950) { - outb(0x89, - me0900_device->base.info.pci.reg_bases[2] + - ME0900_CTRL_REG); - outb(0x00, - me0900_device->base.info.pci.reg_bases[2] + - ME0900_WRITE_ENABLE_REG); - } else if (me0900_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME0960) { - outb(0x8B, - me0900_device->base.info.pci.reg_bases[2] + - ME0900_CTRL_REG); - outb(0x00, - me0900_device->base.info.pci.reg_bases[2] + - ME0900_WRITE_ENABLE_REG); - } - - port_shift = - (me0900_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME0960) ? 1 : 0; - // Create subdevice instances. - - for (i = 0; i < me0900_versions[version_idx].di_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0900_di_constructor(me0900_device-> - base.info.pci. - reg_bases[2], - i + port_shift); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0900_device); - kfree(me0900_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0900_device->base.slist, - subdevice); - } - - for (i = 0; i < me0900_versions[version_idx].do_subdevices; i++) { - subdevice = - (me_subdevice_t *) me0900_do_constructor(me0900_device-> - base.info.pci. - reg_bases[2], i); - - if (!subdevice) { - me_device_deinit((me_device_t *) me0900_device); - kfree(me0900_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me0900_device->base.slist, - subdevice); - } - - return (me_device_t *) me0900_device; -} -EXPORT_SYMBOL(me0900_pci_constructor); - -// Init and exit of module. - -static int __init me0900_init(void) -{ - PDEBUG("executed.\n."); - return 0; -} - -static void __exit me0900_exit(void) -{ - PDEBUG("executed.\n."); -} - -module_init(me0900_init); -module_exit(me0900_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for ME-9x Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me0900_device.h b/drivers/staging/meilhaus/me0900_device.h deleted file mode 100644 index 53c05e83675..00000000000 --- a/drivers/staging/meilhaus/me0900_device.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file me0900_device.h - * - * @brief ME-0900 (ME-9x) device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0900_DEVICE_H -#define _ME0900_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-0900 (ME-9x) device capabilities. - */ -typedef struct me0900_version { - uint16_t device_id; - unsigned int di_subdevices; - unsigned int do_subdevices; -} me0900_version_t; - -/** - * @brief Device capabilities. - */ -static me0900_version_t me0900_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME0940, 2, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME0950, 0, 2}, - {PCI_DEVICE_ID_MEILHAUS_ME0960, 1, 1}, - {0}, -}; - -#define ME0900_DEVICE_VERSIONS (ARRAY_SIZE(me0900_versions) - 1) /**< Returns the number of entries in #me0900_versions. */ - -/** - * @brief Returns the index of the device entry in #me0900_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me0900_versions. - */ -static inline unsigned int me0900_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME0900_DEVICE_VERSIONS; i++) - if (me0900_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-0900 (ME-9x) device class structure. - */ -typedef struct me0900_device { - me_device_t base; /**< The Meilhaus device base class. */ -} me0900_device_t; - -/** - * @brief The ME-9x device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-0900 (ME-9x) device instance. \n - * NULL on error. - */ -me_device_t *me0900_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c deleted file mode 100644 index b8c448f58e3..00000000000 --- a/drivers/staging/meilhaus/me0900_di.c +++ /dev/null @@ -1,245 +0,0 @@ -/** - * @file me0900_di.c - * - * @brief ME-9x digital input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "meids.h" -#include "medebug.h" -#include "meplx_reg.h" -#include "me0900_reg.h" -#include "me0900_di.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - PDEBUG("executed.\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - return ME_ERRNO_SUCCESS; -} - -static int me0900_di_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me0900_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0900_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - } else { - PERROR("Invalid byte direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0900_di_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0900_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0900_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = (~inb(instance->port_reg)) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = ~inb(instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0900_di_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me0900_di_subdevice_t *me0900_di_constructor(uint32_t reg_base, - unsigned int di_idx) -{ - me0900_di_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0900_di_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0900_di_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - /* Save the subdevice index. */ - subdevice->di_idx = di_idx; - - /* Initialize registers */ - if (di_idx == 0) { - subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; - subdevice->port_reg = reg_base + ME0900_PORT_A_REG; - } else { - subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; - subdevice->port_reg = reg_base + ME0900_PORT_B_REG; - } -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0900_di_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0900_di_io_single_config; - subdevice->base.me_subdevice_io_single_read = me0900_di_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me0900_di_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0900_di_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0900_di_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0900_di.h b/drivers/staging/meilhaus/me0900_di.h deleted file mode 100644 index 014f1348fc9..00000000000 --- a/drivers/staging/meilhaus/me0900_di.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file me0900_di.h - * - * @brief ME-9x digital input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0900_DI_H_ -#define _ME0900_DI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0900_di_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - unsigned int di_idx; - - unsigned long ctrl_reg; - unsigned long port_reg; -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me0900_di_subdevice_t; - -/** - * @brief The constructor to generate a ME-9x digital input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0900_di_subdevice_t *me0900_di_constructor(uint32_t me0900_reg_base, - unsigned int di_idx); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c deleted file mode 100644 index a2275faf1a0..00000000000 --- a/drivers/staging/meilhaus/me0900_do.c +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @file me0900_do.c - * - * @brief ME-9x digital output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me0900_reg.h" -#include "me0900_do.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me0900_do_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me0900_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - outb(0xFF, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0xff); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me0900_do_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me0900_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0900_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - } else { - PERROR("Invalid byte direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0900_do_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me0900_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me0900_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = (~inb(instance->port_reg)) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = ~inb(instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0900_do_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me0900_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long state; - - PDEBUG("executed.\n"); - - instance = (me0900_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - state = inb(instance->port_reg); - state = - (!value) ? (state | (0x1 << channel)) : (state & - ~(0x1 << - channel)); - outb(state, instance->port_reg); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - outb(~(value), instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me0900_do_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base, - unsigned int do_idx) -{ - me0900_do_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me0900_do_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me0900_do_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - /* Save the subdevice index */ - subdevice->do_idx = do_idx; - - /* Initialize registers */ - if (do_idx == 0) { - subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; - subdevice->port_reg = reg_base + ME0900_PORT_A_REG; - subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG; - subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG; - } else { - subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; - subdevice->port_reg = reg_base + ME0900_PORT_B_REG; - subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG; - subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG; - } -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me0900_do_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me0900_do_io_single_config; - subdevice->base.me_subdevice_io_single_read = me0900_do_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me0900_do_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me0900_do_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me0900_do_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me0900_do_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me0900_do.h b/drivers/staging/meilhaus/me0900_do.h deleted file mode 100644 index 13e8a8b94cf..00000000000 --- a/drivers/staging/meilhaus/me0900_do.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file me0900_do.h - * - * @brief ME-9x digital output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0900_DO_H_ -#define _ME0900_DO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me0900_do_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - unsigned int do_idx; - - unsigned long ctrl_reg; - unsigned long port_reg; - unsigned long enable_reg; - unsigned long disable_reg; -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me0900_do_subdevice_t; - -/** - * @brief The constructor to generate a ME-9x digital output subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param do_idx The index of the digital output subdevice on this device. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base, - unsigned int do_idx); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me0900_reg.h b/drivers/staging/meilhaus/me0900_reg.h deleted file mode 100644 index 3bf163b6ac4..00000000000 --- a/drivers/staging/meilhaus/me0900_reg.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file me0900_reg.h - * - * @brief ME-9x register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME0900_REG_H_ -#define _ME0900_REG_H_ - -#ifdef __KERNEL__ - -#define ME0900_PORT_A_REG 0x00 -#define ME0900_PORT_B_REG 0x01 -#define ME0900_PORT_C_REG 0x02 -#define ME0900_CTRL_REG 0x03 // ( ,w) -#define ME0900_WRITE_ENABLE_REG 0x04 // (r,w) -#define ME0900_WRITE_DISABLE_REG 0x08 // (r,w) - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c deleted file mode 100644 index cf0fb92f24c..00000000000 --- a/drivers/staging/meilhaus/me1000_device.c +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @file me1000_device.c - * - * @brief ME-1000 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "me1000_device.h" -#include "mesubdevice.h" -#include "me1000_dio.h" - -static int me1000_config_load(me_device_t *me_device, struct file *filep, - me_cfg_device_entry_t *config) -{ - me1000_device_t *me1000_device; - me1000_dio_subdevice_t *dio; - - PDEBUG("executed.\n"); - - me1000_device = (me1000_device_t *) me_device; - - if (config->count == 2) { - if (me_slist_get_number_subdevices(&me1000_device->base.slist) - == 2) { - // Nothing to do. - } else { - // Remove 2 extra subdevices - dio = - (me1000_dio_subdevice_t *) - me_slist_del_subdevice_tail(&me1000_device->base. - slist); - if (dio) - dio->base. - me_subdevice_destructor((me_subdevice_t *) - dio); - - dio = - (me1000_dio_subdevice_t *) - me_slist_del_subdevice_tail(&me1000_device->base. - slist); - if (dio) - dio->base. - me_subdevice_destructor((me_subdevice_t *) - dio); - } - } else if (config->count == 4) { - //Add 2 subdevices - if (me_slist_get_number_subdevices(&me1000_device->base.slist) - == 2) { - dio = - me1000_dio_constructor(me1000_device->base.info.pci. - reg_bases[2], 2, - &me1000_device->ctrl_lock); - if (!dio) { - PERROR("Cannot create dio subdevice.\n"); - return ME_ERRNO_INTERNAL; - } - me_slist_add_subdevice_tail(&me1000_device->base.slist, - (me_subdevice_t *) dio); - - dio = - me1000_dio_constructor(me1000_device->base.info.pci. - reg_bases[2], 3, - &me1000_device->ctrl_lock); - if (!dio) { - dio = - (me1000_dio_subdevice_t *) - me_slist_del_subdevice_tail(&me1000_device-> - base.slist); - if (dio) - dio->base. - me_subdevice_destructor((me_subdevice_t *) dio); - - PERROR("Cannot create dio subdevice.\n"); - return ME_ERRNO_INTERNAL; - } - me_slist_add_subdevice_tail(&me1000_device->base.slist, - (me_subdevice_t *) dio); - } else { - // Nothing to do. - } - } else { - PERROR("Invalid configuration.\n"); - return ME_ERRNO_INTERNAL; - } - - return ME_ERRNO_SUCCESS; -} - -me_device_t *me1000_pci_constructor(struct pci_dev * pci_device) -{ - me1000_device_t *me1000_device; - me_subdevice_t *subdevice; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me1000_device = kmalloc(sizeof(me1000_device_t), GFP_KERNEL); - - if (!me1000_device) { - PERROR("Cannot get memory for ME-1000 device instance.\n"); - return NULL; - } - - memset(me1000_device, 0, sizeof(me1000_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me1000_device, pci_device); - - if (err) { - kfree(me1000_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - // Initialize spin lock . - spin_lock_init(&me1000_device->ctrl_lock); - - for (i = 0; i < 4; i++) { - subdevice = - (me_subdevice_t *) me1000_dio_constructor(me1000_device-> - base.info.pci. - reg_bases[2], i, - &me1000_device-> - ctrl_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me1000_device); - kfree(me1000_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me1000_device->base.slist, - subdevice); - } - - // Overwrite base class methods. - me1000_device->base.me_device_config_load = me1000_config_load; - - return (me_device_t *) me1000_device; -} -EXPORT_SYMBOL(me1000_pci_constructor); - -// Init and exit of module. -static int __init me1000_init(void) -{ - PDEBUG("executed.\n"); - return 0; -} - -static void __exit me1000_exit(void) -{ - PDEBUG("executed.\n"); -} - -module_init(me1000_init); -module_exit(me1000_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me1000_device.h b/drivers/staging/meilhaus/me1000_device.h deleted file mode 100644 index cbbe1263017..00000000000 --- a/drivers/staging/meilhaus/me1000_device.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file me1000_device.h - * - * @brief ME-1000 device class instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1000_H_ -#define _ME1000_H_ - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -#define ME1000_MAGIC_NUMBER 1000 - -/** - * @brief The ME-1000 device class structure. - */ -typedef struct me1000_device { - me_device_t base; /**< The Meilhaus device base class. */ - spinlock_t ctrl_lock; /**< Guards the DIO mode register. */ -} me1000_device_t; - -/** - * @brief The ME-1000 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-1000 device instance. \n - * NULL on error. - */ -me_device_t *me1000_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c deleted file mode 100644 index 2d7ed07d1f3..00000000000 --- a/drivers/staging/meilhaus/me1000_dio.c +++ /dev/null @@ -1,438 +0,0 @@ -/** - * @file me1000_dio.c - * - * @brief ME-1000 DIO subdevice instance. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "medebug.h" - -#include "me1000_dio_reg.h" -#include "me1000_dio.h" - -/* - * Defines - */ -#define ME1000_DIO_MAGIC_NUMBER 0x1000 /**< The magic number of the class structure. */ - -/* - * Functions - */ - -static int me1000_dio_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me1000_dio_subdevice_t *instance; - uint32_t tmp; - - PDEBUG("executed.\n"); - - instance = (me1000_dio_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp &= ~(0x1 << instance->dio_idx); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->ctrl_reg_lock); - - outl(0x00000000, instance->port_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me1000_dio_io_single_config(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me1000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - int ctrl; - int size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - - PDEBUG("executed.\n"); - - instance = (me1000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - ctrl = inl(instance->ctrl_reg); - - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_DWORD: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - ctrl &= ~(0x1 << instance->dio_idx); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - ctrl |= 0x1 << instance->dio_idx; - } else { - PERROR("Invalid port direction.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1000_dio_io_single_read(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me1000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me1000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 32)) { - *value = inl(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if ((channel >= 0) && (channel < 4)) { - *value = - (inl(instance->port_reg) >> (channel * 8)) & 0xFF; - } else { - PERROR("Invalid byte number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_WORD: - if ((channel >= 0) && (channel < 2)) { - *value = - (inl(instance->port_reg) >> (channel * 16)) & - 0xFFFF; - } else { - PERROR("Invalid word number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_DWORD: - if (channel == 0) { - *value = inl(instance->port_reg); - } else { - PERROR("Invalid dword number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1000_dio_io_single_write(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me1000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t config; - uint32_t state; - - PDEBUG("executed.\n"); - - instance = (me1000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - config = inl(instance->ctrl_reg) & (0x1 << instance->dio_idx); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 32)) { - if (config) { - state = inl(instance->port_reg); - state = - value ? (state | (0x1 << channel)) : (state - & - ~(0x1 - << - channel)); - outl(state, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, state); - } else { - PERROR("Port is not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if ((channel >= 0) && (channel < 4)) { - if (config) { - state = inl(instance->port_reg); - state &= ~(0xFF << (channel * 8)); - state |= (value & 0xFF) << (channel * 8); - outl(state, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, state); - } else { - PERROR("Port is not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_WORD: - if ((channel >= 0) && (channel < 2)) { - if (config) { - state = inl(instance->port_reg); - state &= ~(0xFFFF << (channel * 16)); - state |= (value & 0xFFFF) << (channel * 16); - outl(state, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, state); - } else { - PERROR("Port is not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid word number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_DWORD: - if (channel == 0) { - if (config) { - outl(value, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, value); - } else { - PERROR("Port is not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid dword number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1000_dio_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = ME1000_DIO_NUMBER_CHANNELS; - return ME_ERRNO_SUCCESS; -} - -static int me1000_dio_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - me1000_dio_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me1000_dio_subdevice_t *) subdevice; - - *caps = ME_CAPS_DIO_DIR_DWORD; - - return ME_ERRNO_SUCCESS; -} - -me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t *ctrl_reg_lock) -{ - me1000_dio_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me1000_dio_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for ME-1000 DIO instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me1000_dio_subdevice_t)); - - /* Check if counter index is out of range */ - - if (dio_idx >= ME1000_DIO_NUMBER_PORTS) { - PERROR("DIO index is out of range.\n"); - kfree(subdevice); - return NULL; - } - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the DIO index */ - subdevice->dio_idx = dio_idx; - - /* Initialize registers. */ -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - subdevice->ctrl_reg = reg_base + ME1000_PORT_MODE; - subdevice->port_reg = - reg_base + ME1000_PORT + (dio_idx * ME1000_PORT_STEP); - - /* Override base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me1000_dio_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me1000_dio_io_single_config; - subdevice->base.me_subdevice_io_single_read = me1000_dio_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me1000_dio_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me1000_dio_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me1000_dio_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me1000_dio_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me1000_dio.h b/drivers/staging/meilhaus/me1000_dio.h deleted file mode 100644 index d26e93f531a..00000000000 --- a/drivers/staging/meilhaus/me1000_dio.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file me1000_dio.h - * - * @brief Meilhaus ME-1000 digital i/o implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1000_DIO_H_ -#define _ME1000_DIO_H_ - -#include "mesubdevice.h" -#include "meslock.h" - -#ifdef __KERNEL__ - -/** - * @brief The ME-1000 DIO subdevice class. - */ -typedef struct me1000_dio_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ -// uint32_t magic; /**< The magic number unique for this structure. */ - - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */ - int dio_idx; /**< The index of the DIO port on the device. */ - - unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */ - unsigned long ctrl_reg; /**< Register to configure the DIO modes. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me1000_dio_subdevice_t; - -/** - * @brief The constructor to generate a ME-1000 DIO instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param dio_idx The index of the DIO on the device. - * @param ctrl_reg_lock Pointer to spin lock protecting the control register and from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1000_dio_reg.h b/drivers/staging/meilhaus/me1000_dio_reg.h deleted file mode 100644 index 4d5b38df437..00000000000 --- a/drivers/staging/meilhaus/me1000_dio_reg.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file me1000_dio_reg.h - * - * @brief ME-1000 digital i/o register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1000_DIO_REG_H_ -# define _ME1000_DIO_REG_H_ - -# ifdef __KERNEL__ - -# define ME1000_DIO_NUMBER_CHANNELS 32 /**< The number of channels per DIO port. */ -# define ME1000_DIO_NUMBER_PORTS 4 /**< The number of ports per ME-1000. */ - -// # define ME1000_PORT_A 0x0000 /**< Port A base register offset. */ -// # define ME1000_PORT_B 0x0004 /**< Port B base register offset. */ -// # define ME1000_PORT_C 0x0008 /**< Port C base register offset. */ -// # define ME1000_PORT_D 0x000C /**< Port D base register offset. */ -# define ME1000_PORT 0x0000 /**< Base for port's register. */ -# define ME1000_PORT_STEP 4 /**< Distance between port's register. */ - -# define ME1000_PORT_MODE 0x0010 /**< Configuration register to switch the port direction. */ -// # define ME1000_PORT_MODE_OUTPUT_A (1 << 0) /**< If set, port A is in output, otherwise in input mode. */ -// # define ME1000_PORT_MODE_OUTPUT_B (1 << 1) /**< If set, port B is in output, otherwise in input mode. */ -// # define ME1000_PORT_MODE_OUTPUT_C (1 << 2) /**< If set, port C is in output, otherwise in input mode. */ -// # define ME1000_PORT_MODE_OUTPUT_D (1 << 3) /**< If set, port D is in output, otherwise in input mode. */ - -# endif //__KERNEL__ -#endif //_ME1000_DIO_REG_H_ diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c deleted file mode 100644 index a018b5f7a19..00000000000 --- a/drivers/staging/meilhaus/me1400_device.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * @file me1400_device.c - * - * @brief ME-1400 device instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * User application could also include the kernel header files. But the - * real kernel functions are protected by #ifdef __KERNEL__. - */ -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * This must be defined before module.h is included. Not needed, when - * it is a built in driver. - */ -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" - -#include "me1400_device.h" -#include "me8254.h" -#include "me8254_reg.h" -#include "me8255.h" -#include "me1400_ext_irq.h" - -me_device_t *me1400_pci_constructor(struct pci_dev *pci_device) -{ - int err; - me1400_device_t *me1400_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - unsigned int me8255_idx; - unsigned int dio_idx; - unsigned int me8254_idx; - unsigned int ctr_idx; - unsigned int ext_irq_idx; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me1400_device = kmalloc(sizeof(me1400_device_t), GFP_KERNEL); - - if (!me1400_device) { - PERROR("Cannot get memory for 1400ate device instance.\n"); - return NULL; - } - - memset(me1400_device, 0, sizeof(me1400_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me1400_device, pci_device); - - if (err) { - kfree(me1400_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Check for ME1400 extension device. If detected we fake a ME-1400 D device id. */ - if (me1400_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME140C) { - uint8_t ctrl; - ctrl = - inb(me1400_device->base.info.pci.reg_bases[2] + - ME1400D_CLK_SRC_2_REG); - PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n", - me1400_device->base.info.pci.reg_bases[2], - ME1400D_CLK_SRC_2_REG, ctrl); - outb(ctrl | 0xF0, - me1400_device->base.info.pci.reg_bases[2] + - ME1400D_CLK_SRC_2_REG); - PDEBUG_REG("xxx_reg outb(0x%X+0x%X)=0x%x\n", - me1400_device->base.info.pci.reg_bases[2], - ME1400D_CLK_SRC_2_REG, ctrl | 0xF0); - ctrl = - inb(me1400_device->base.info.pci.reg_bases[2] + - ME1400D_CLK_SRC_2_REG); - PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n", - me1400_device->base.info.pci.reg_bases[2], - ME1400D_CLK_SRC_2_REG, ctrl); - - if ((ctrl & 0xF0) == 0xF0) { - PINFO("ME1400 D detected.\n"); - me1400_device->base.info.pci.device_id = - PCI_DEVICE_ID_MEILHAUS_ME140D; - } - } - - /* Initialize global stuff of digital i/o subdevices. */ - for (me8255_idx = 0; me8255_idx < ME1400_MAX_8255; me8255_idx++) { - me1400_device->dio_current_mode[me8255_idx] = 0; - spin_lock_init(&me1400_device->dio_ctrl_reg_lock[me8255_idx]); - } - - /* Initialize global stuff of counter subdevices. */ - spin_lock_init(&me1400_device->clk_src_reg_lock); - - for (me8254_idx = 0; me8254_idx < ME1400_MAX_8254; me8254_idx++) - spin_lock_init(&me1400_device->ctr_ctrl_reg_lock[me8254_idx]); - - /* Get the index in the device version information table. */ - version_idx = - me1400_versions_get_device_index(me1400_device->base.info.pci. - device_id); - - /* Generate DIO subdevice instances. */ - for (me8255_idx = 0; - me8255_idx < me1400_versions[version_idx].dio_chips; - me8255_idx++) { - for (dio_idx = 0; dio_idx < 3; dio_idx++) { - subdevice = - (me_subdevice_t *) - me8255_constructor(me1400_versions[version_idx]. - device_id, - me1400_device->base.info.pci. - reg_bases[2], me8255_idx, - dio_idx, - &me1400_device-> - dio_current_mode[me8255_idx], - &me1400_device-> - dio_ctrl_reg_lock[me8255_idx]); - - if (!subdevice) { - me_device_deinit((me_device_t *) me1400_device); - kfree(me1400_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me1400_device->base.slist, - subdevice); - } - } - - /* Generate counter subdevice instances. */ - for (me8254_idx = 0; - me8254_idx < me1400_versions[version_idx].ctr_chips; - me8254_idx++) { - for (ctr_idx = 0; ctr_idx < 3; ctr_idx++) { - subdevice = - (me_subdevice_t *) - me8254_constructor(me1400_device->base.info.pci. - device_id, - me1400_device->base.info.pci. - reg_bases[2], me8254_idx, - ctr_idx, - &me1400_device-> - ctr_ctrl_reg_lock[me8254_idx], - &me1400_device-> - clk_src_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me1400_device); - kfree(me1400_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me1400_device->base.slist, - subdevice); - } - } - - /* Generate external interrupt subdevice instances. */ - for (ext_irq_idx = 0; - ext_irq_idx < me1400_versions[version_idx].ext_irq_subdevices; - ext_irq_idx++) { - subdevice = - (me_subdevice_t *) - me1400_ext_irq_constructor(me1400_device->base.info.pci. - device_id, - me1400_device->base.info.pci. - reg_bases[1], - me1400_device->base.info.pci. - reg_bases[2], - &me1400_device->clk_src_reg_lock, - me1400_device->base.irq); - - if (!subdevice) { - me_device_deinit((me_device_t *) me1400_device); - kfree(me1400_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me1400_device->base.slist, - subdevice); - } - - return (me_device_t *) me1400_device; -} -EXPORT_SYMBOL(me1400_pci_constructor); - -// Init and exit of module. - -static int __init me1400_init(void) -{ - PDEBUG("executed.\n"); - return 0; -} - -static void __exit me1400_exit(void) -{ - PDEBUG("executed.\n"); -} - -module_init(me1400_init); -module_exit(me1400_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me1400_device.h b/drivers/staging/meilhaus/me1400_device.h deleted file mode 100644 index d20112d8da6..00000000000 --- a/drivers/staging/meilhaus/me1400_device.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file me1400_device.c - * - * @brief ME-1400 device family instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1400_DEVICE_H_ -#define _ME1400_DEVICE_H_ - -#include "metypes.h" -#include "medefines.h" -#include "meinternal.h" - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure to store device capabilities. - */ -typedef struct me1400_version { - uint16_t device_id; /**< The PCI device id of the device. */ - unsigned int dio_chips; /**< The number of 8255 chips on the device. */ - unsigned int ctr_chips; /**< The number of 8254 chips on the device. */ - unsigned int ext_irq_subdevices; /**< The number of external interrupt inputs on the device. */ -} me1400_version_t; - -/** - * @brief Defines for each ME-1400 device version its capabilities. - */ -static me1400_version_t me1400_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME1400, 1, 0, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME140A, 1, 1, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME140B, 2, 2, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME14E0, 1, 0, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME14EA, 1, 1, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME14EB, 2, 2, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME140C, 1, 5, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME140D, 2, 10, 1}, - {0} -}; - -#define ME1400_DEVICE_VERSIONS (ARRAY_SIZE(me1400_versions) - 1) /**< Returns the number of entries in #me1400_versions. */ - -/** - * @brief Returns the index of the device entry in #me1400_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me1400_versions. - */ -static inline unsigned int me1400_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME1400_DEVICE_VERSIONS; i++) - if (me1400_versions[i].device_id == device_id) - break; - return i; -} - -#define ME1400_MAX_8254 10 /**< The maximum number of 8254 counter subdevices available on any ME-1400 device. */ -#define ME1400_MAX_8255 2 /**< The maximum number of 8255 digital i/o subdevices available on any ME-1400 device. */ - -/** - * @brief The ME-1400 device class. - */ -typedef struct me1400_device { - me_device_t base; /**< The Meilhaus device base class. */ - - spinlock_t clk_src_reg_lock; /**< Guards the 8254 clock source registers. */ - spinlock_t ctr_ctrl_reg_lock[ME1400_MAX_8254]; /**< Guards the 8254 ctrl registers. */ - - int dio_current_mode[ME1400_MAX_8255]; /**< Saves the current mode setting of a single 8255 DIO chip. */ - spinlock_t dio_ctrl_reg_lock[ME1400_MAX_8255]; /**< Guards the 8255 ctrl register and #dio_current_mode. */ -} me1400_device_t; - -/** - * @brief The ME-1400 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-1400 device instance. \n - * NULL on error. - */ -me_device_t *me1400_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c deleted file mode 100644 index 6841f41860a..00000000000 --- a/drivers/staging/meilhaus/me1400_ext_irq.c +++ /dev/null @@ -1,507 +0,0 @@ -/** - * @file me1400_ext_irq.c - * - * @brief ME-1400 external interrupt subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "medebug.h" -#include "meids.h" - -#include "me1400_ext_irq.h" -#include "me1400_ext_irq_reg.h" - -/* - * Defines - */ -#define ME1400_EXT_IRQ_MAGIC_NUMBER 0x1401 /**< The magic number of the class structure. */ -#define ME1400_EXT_IRQ_NUMBER_CHANNELS 1 /**< One channel per counter. */ - -/* - * Functions - */ - -static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me1400_ext_irq_subdevice_t *instance; - unsigned long cpu_flags; - uint8_t tmp; - - PDEBUG("executed.\n"); - - instance = (me1400_ext_irq_subdevice_t *) subdevice; - - if (flags & ~ME_IO_IRQ_START_DIO_BIT) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (irq_source != ME_IRQ_SOURCE_DIO_LINE) { - PERROR("Invalid irq source.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - if (irq_edge != ME_IRQ_EDGE_RISING) { - PERROR("Invalid irq edge.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - spin_lock(instance->clk_src_reg_lock); -// // Enable IRQ on PLX -// tmp = inb(instance->plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN); -// outb(tmp, instance->plx_intcs_reg); -// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp); - - // Enable IRQ - switch (instance->device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME140C: - case PCI_DEVICE_ID_MEILHAUS_ME140D: - tmp = inb(instance->ctrl_reg); - tmp |= ME1400CD_EXT_IRQ_CLK_EN; - outb(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - break; - - default: - outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ME1400AB_EXT_IRQ_IRQ_EN); - break; - } - spin_unlock(instance->clk_src_reg_lock); - instance->rised = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me1400_ext_irq_subdevice_t *instance; - unsigned long cpu_flags; - long t = 0; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me1400_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid time out.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - /* Convert to ticks */ - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - (instance->rised != - 0), t); - - if (t == 0) { - PERROR("Wait on interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - instance->rised = 0; - *irq_count = instance->n; - *value = 1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice, - struct file *filep, - int channel, int flags) -{ - me1400_ext_irq_subdevice_t *instance; - unsigned long cpu_flags; - uint8_t tmp; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me1400_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->clk_src_reg_lock); -// // Disable IRQ on PLX -// tmp = inb(instance->plx_intcs_reg) & ( ~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN)); -// outb(tmp, instance->plx_intcs_reg); -// PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp); - - switch (instance->device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME140C: - case PCI_DEVICE_ID_MEILHAUS_ME140D: - tmp = inb(instance->ctrl_reg); - tmp &= ~ME1400CD_EXT_IRQ_CLK_EN; - outb(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - break; - - default: - outb(0x00, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, 0x00); - break; - } - spin_unlock(instance->clk_src_reg_lock); - instance->rised = -1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me1400_ext_irq_subdevice_t *instance = - (me1400_ext_irq_subdevice_t *) subdevice; - - PDEBUG("executed.\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - instance->n = 0; - return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags); -} - -static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = ME1400_EXT_IRQ_NUMBER_CHANNELS; - return ME_ERRNO_SUCCESS; -} - -static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_EXT_IRQ; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_EXT_IRQ_EDGE_RISING; - return ME_ERRNO_SUCCESS; -} - -static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice - *subdevice, int cap, - int *args, int count) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id) -{ - me1400_ext_irq_subdevice_t *instance; - uint32_t status; - uint8_t tmp; - - instance = (me1400_ext_irq_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - spin_lock(&instance->subdevice_lock); - status = inl(instance->plx_intcs_reg); -// if (!((status & PLX_LOCAL_INT1_STATE) && (status & PLX_LOCAL_INT1_EN) && (status & PLX_PCI_INT_EN))) - if ((status & - (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) != - (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) { - spin_unlock(&instance->subdevice_lock); - PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n", - jiffies, __func__, status); - return IRQ_NONE; - } - - inl(instance->ctrl_reg); - - PDEBUG("executed.\n"); - - instance->n++; - instance->rised = 1; - - switch (instance->device_id) { - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - case PCI_DEVICE_ID_MEILHAUS_ME140D: - spin_lock(instance->clk_src_reg_lock); - tmp = inb(instance->ctrl_reg); - tmp &= ~ME1400CD_EXT_IRQ_CLK_EN; - outb(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - tmp |= ME1400CD_EXT_IRQ_CLK_EN; - outb(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->clk_src_reg_lock); - - break; - - default: - outb(0, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, 0); - outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ME1400AB_EXT_IRQ_IRQ_EN); - break; - } - - spin_unlock(&instance->subdevice_lock); - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -static void me1400_ext_irq_destructor(struct me_subdevice *subdevice) -{ - me1400_ext_irq_subdevice_t *instance; - uint8_t tmp; - - PDEBUG("executed.\n"); - - instance = (me1400_ext_irq_subdevice_t *) subdevice; - - // Disable IRQ on PLX - tmp = - inb(instance-> - plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | - PLX_PCI_INT_EN)); - outb(tmp, instance->plx_intcs_reg); - PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg, - tmp); - - free_irq(instance->irq, (void *)instance); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id, - uint32_t plx_reg_base, - uint32_t me1400_reg_base, - spinlock_t * - clk_src_reg_lock, - int irq) -{ - me1400_ext_irq_subdevice_t *subdevice; - int err; - uint8_t tmp; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for 1400_ext_irq instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->clk_src_reg_lock = clk_src_reg_lock; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - subdevice->irq = irq; - - err = request_irq(irq, me1400_ext_irq_isr, - IRQF_DISABLED | IRQF_SHARED, - ME1400_NAME, (void *)subdevice); - - if (err) { - PERROR("Can't get irq.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - - /* Initialize registers */ - subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG; - subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = me1400_reg_base; -#endif - - // Enable IRQ on PLX - tmp = - inb(subdevice-> - plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | - PLX_PCI_INT_EN); - outb(tmp, subdevice->plx_intcs_reg); - PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg, - tmp); - - /* Initialize the subdevice methods */ - subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop; - subdevice->base.me_subdevice_io_reset_subdevice = - me1400_ext_irq_io_reset_subdevice; - subdevice->base.me_subdevice_query_number_channels = - me1400_ext_irq_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me1400_ext_irq_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me1400_ext_irq_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me1400_ext_irq_query_subdevice_caps_args; - subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor; - - subdevice->rised = 0; - subdevice->n = 0; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me1400_ext_irq.h b/drivers/staging/meilhaus/me1400_ext_irq.h deleted file mode 100644 index 9b72a04701c..00000000000 --- a/drivers/staging/meilhaus/me1400_ext_irq.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file me1400_ext_irq.h - * - * @brief ME-1400 external interrupt implementation. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME1400_EXT_IRQ_H_ -#define _ME1400_EXT_IRQ_H_ - -#include - -#include "mesubdevice.h" -#include "meslock.h" - -#ifdef __KERNEL__ - -/** - * @brief The ME-1400 external interrupt subdevice class. - */ -typedef struct me1400_ext_irq_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *clk_src_reg_lock; /**< Lock protecting the clock control register. */ - - wait_queue_head_t wait_queue; /**< Queue to put on threads waiting for an interrupt. */ - - uint32_t device_id; /**< The device id of the device holding the subdevice. */ - int irq; /**< The irq number assigned by PCI BIOS. */ - int rised; /**< If true an interrupt has occured. */ - unsigned int n; /**< The number of interrupt since the driver was loaded. */ - - unsigned long plx_intcs_reg; /**< The PLX interrupt control and status register. */ - unsigned long ctrl_reg; /**< The control register. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me1400_ext_irq_subdevice_t; - -/** - * @brief The constructor to generate a ME-1400 external interrupt instance. - * - * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS. - * @param me1400_reg_base The register base address of the ME-1400 device as returned by the PCI BIOS. - * @param irq The irq assigned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id, - uint32_t plx_reg_base, - uint32_t me1400_reg_base, - spinlock_t * - clk_src_reg_lock, - int irq); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1400_ext_irq_reg.h b/drivers/staging/meilhaus/me1400_ext_irq_reg.h deleted file mode 100644 index c9740f2dd3a..00000000000 --- a/drivers/staging/meilhaus/me1400_ext_irq_reg.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file me1400_ext_irq_reg.h - * - * @brief ME-1400 external interrupt register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1400_EXT_IRQ_REG_H_ -# define _ME1400_EXT_IRQ_REG_H_ - -# ifdef __KERNEL__ - -# define PLX_INTCSR_REG 0x4C /**< The PLX interrupt control and status register offset. */ -# define PLX_ICR_REG 0x50 /**< The PLX initialization control register offset. */ - -# define PLX_LOCAL_INT1_EN 0x01 /**< If set the local interrupt 1 is enabled. */ -# define PLX_LOCAL_INT1_POL 0x02 /**< If set the local interrupt 1 polarity is high active. */ -# define PLX_LOCAL_INT1_STATE 0x04 /**< If set the local interrupt 1 is activ. */ -# define PLX_LOCAL_INT2_EN 0x08 /**< If set the local interrupt 2 is enabled. */ -# define PLX_LOCAL_INT2_POL 0x10 /**< If set the local interrupt 2 polarity is high active. */ -# define PLX_LOCAL_INT2_STATE 0x20 /**< If set the local interrupt 2 is activ. */ -# define PLX_PCI_INT_EN 0x40 /**< If set the PCI interrupt is enabled. */ -# define PLX_SOFT_INT 0x80 /**< If set an interrupt is generated. */ - -# define ME1400AB_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */ - -# define ME1400AB_EXT_IRQ_CLK_EN 0x01 /**< If this bit is set, the clock output is enabled. */ -# define ME1400AB_EXT_IRQ_IRQ_EN 0x02 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt. */ - -# define ME1400CD_EXT_IRQ_CTRL_REG 0x11 /**< The external interrupt control register offset. */ - -# define ME1400CD_EXT_IRQ_CLK_EN 0x10 /**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt.*/ - -# endif //__KERNEL__ - -#endif //_ME1400_EXT_IRQ_REG_H_ diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c deleted file mode 100644 index 12e3c70e982..00000000000 --- a/drivers/staging/meilhaus/me1600_ao.c +++ /dev/null @@ -1,1017 +0,0 @@ -/** - * @file me1600_ao.c - * - * @brief ME-1600 analog output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* Includes - */ - -#include - -#include -#include -#include -#include -#include - -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "medebug.h" - -#include "me1600_ao_reg.h" -#include "me1600_ao.h" - -/* Defines - */ - -static void me1600_ao_destructor(struct me_subdevice *subdevice); - -static void me1600_ao_work_control_task(struct work_struct *work); - -static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags); -static int me1600_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, int channel, - int single_config, int ref, int trig_chan, - int trig_type, int trig_edge, int flags); -static int me1600_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, int channel, int *value, - int time_out, int flags); -static int me1600_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, int channel, int value, - int time_out, int flags); -static int me1600_ao_query_number_channels(me_subdevice_t *subdevice, - int *number); -static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type, - int *subtype); -static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps); -static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, int *min, int *max, - int *maxdata, int *range); -static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, int unit, - int *count); -static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range, - int *unit, int *min, int *max, - int *maxdata); - -/* Functions - */ - -me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base, - unsigned int ao_idx, - int curr, - spinlock_t *config_regs_lock, - spinlock_t *ao_shadows_lock, - me1600_ao_shadow_t *ao_regs_shadows, - struct workqueue_struct *me1600_wq) -{ - me1600_ao_subdevice_t *subdevice; - int err; - - PDEBUG("executed. idx=%d\n", ao_idx); - - // Allocate memory for subdevice instance. - subdevice = kmalloc(sizeof(me1600_ao_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR - ("Cannot get memory for analog output subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me1600_ao_subdevice_t)); - - // Initialize subdevice base class. - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->config_regs_lock = config_regs_lock; - subdevice->ao_shadows_lock = ao_shadows_lock; - - // Save the subdevice index. - subdevice->ao_idx = ao_idx; - - // Initialize range lists. - subdevice->u_ranges_count = 2; - - subdevice->u_ranges[0].min = 0; //0V - subdevice->u_ranges[0].max = 9997558; //10V - - subdevice->u_ranges[1].min = -10E6; //-10V - subdevice->u_ranges[1].max = 9995117; //10V - - if (curr) { // This is version with current outputs. - subdevice->i_ranges_count = 2; - - subdevice->i_ranges[0].min = 0; //0mA - subdevice->i_ranges[0].max = 19995117; //20mA - - subdevice->i_ranges[1].min = 4E3; //4mA - subdevice->i_ranges[1].max = 19995118; //20mA - } else { // This is version without current outputs. - subdevice->i_ranges_count = 0; - - subdevice->i_ranges[0].min = 0; //0mA - subdevice->i_ranges[0].max = 0; //0mA - - subdevice->i_ranges[1].min = 0; //0mA - subdevice->i_ranges[1].max = 0; //0mA - } - - // Initialize registers. - subdevice->uni_bi_reg = reg_base + ME1600_UNI_BI_REG; - subdevice->i_range_reg = reg_base + ME1600_020_420_REG; - subdevice->sim_output_reg = reg_base + ME1600_SIM_OUTPUT_REG; - subdevice->current_on_reg = reg_base + ME1600_CURRENT_ON_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - // Initialize shadow structure. - subdevice->ao_regs_shadows = ao_regs_shadows; - - // Override base class methods. - subdevice->base.me_subdevice_destructor = me1600_ao_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me1600_ao_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me1600_ao_io_single_config; - subdevice->base.me_subdevice_io_single_read = me1600_ao_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me1600_ao_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me1600_ao_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me1600_ao_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me1600_ao_query_subdevice_caps; - subdevice->base.me_subdevice_query_range_by_min_max = - me1600_ao_query_range_by_min_max; - subdevice->base.me_subdevice_query_number_ranges = - me1600_ao_query_number_ranges; - subdevice->base.me_subdevice_query_range_info = - me1600_ao_query_range_info; - - // Initialize wait queue. - init_waitqueue_head(&subdevice->wait_queue); - - // Prepare work queue. - subdevice->me1600_workqueue = me1600_wq; - -/* workqueue API changed in kernel 2.6.20 */ - INIT_DELAYED_WORK(&subdevice->ao_control_task, - me1600_ao_work_control_task); - return subdevice; -} - -static void me1600_ao_destructor(struct me_subdevice *subdevice) -{ - me1600_ao_subdevice_t *instance; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - instance->ao_control_task_flag = 0; - - // Reset subdevice to asure clean exit. - me1600_ao_io_reset_subdevice(subdevice, NULL, - ME_IO_RESET_SUBDEVICE_NO_FLAGS); - - // Remove any tasks from work queue. This is paranoic because it was done allready in reset(). - if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue. - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(2); - } -} - -static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me1600_ao_subdevice_t *instance; - uint16_t tmp; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger. - - // Reset all settings. - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ao_shadows_lock); - (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0; - (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0; - (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Not waiting for triggering. - (instance->ao_regs_shadows)->synchronous &= ~(0x1 << instance->ao_idx); //Individual triggering. - - // Set output to default (safe) state. - spin_lock(instance->config_regs_lock); - tmp = inw(instance->uni_bi_reg); // unipolar - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->uni_bi_reg); - PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->uni_bi_reg - instance->reg_base, tmp); - - tmp = inw(instance->current_on_reg); // Volts only! - tmp &= ~(0x1 << instance->ao_idx); - tmp &= 0x00FF; - outw(tmp, instance->current_on_reg); - PDEBUG_REG("current_on_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->current_on_reg - instance->reg_base, tmp); - - tmp = inw(instance->i_range_reg); // 0..20mA <= If exists. - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->i_range_reg); - PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->i_range_reg - instance->reg_base, tmp); - - outw(0, (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - (instance->ao_regs_shadows)->registry[instance->ao_idx] - - instance->reg_base, 0); - - // Trigger output. - outw(0x0000, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, 0x0000); - outw(0xFFFF, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, 0xFFFF); - spin_unlock(instance->config_regs_lock); - spin_unlock(instance->ao_shadows_lock); - - // Set status to 'none' - instance->status = ao_status_none; - spin_unlock(&instance->subdevice_lock); - - //Signal reset if user is on wait. - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me1600_ao_subdevice_t *instance; - uint16_t tmp; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - // Checking parameters. - if (flags) { - PERROR - ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (trig_edge != ME_TRIG_EDGE_NONE) { - PERROR - ("Invalid trigger edge. Software trigger has not edge. Must be ME_TRIG_EDGE_NONE\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - - if (trig_type != ME_TRIG_TYPE_SW) { - PERROR("Invalid trigger edge. Must be ME_TRIG_TYPE_SW.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - - if ((trig_chan != ME_TRIG_CHAN_DEFAULT) - && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) { - PERROR("Invalid trigger channel specified.\n"); - return ME_ERRNO_INVALID_TRIG_CHAN; - } - - if (ref != ME_REF_AO_GROUND) { - PERROR - ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n"); - return ME_ERRNO_INVALID_REF; - } - - if (((single_config + 1) > - (instance->u_ranges_count + instance->i_ranges_count)) - || (single_config < 0)) { - PERROR("Invalid range specified.\n"); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - // Checking parameters - done. All is fine. Do config. - - ME_SUBDEVICE_ENTER; - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ao_shadows_lock); - (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger. - (instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0; - (instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0; - - spin_lock(instance->config_regs_lock); - switch (single_config) { - case 0: // 0V 10V - tmp = inw(instance->current_on_reg); // Volts - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->current_on_reg); - PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->current_on_reg - instance->reg_base, tmp); - - // 0V - outw(0, - (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[instance-> - ao_idx] - - instance->reg_base, 0); - - tmp = inw(instance->uni_bi_reg); // unipolar - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->uni_bi_reg); - PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->uni_bi_reg - instance->reg_base, tmp); - - tmp = inw(instance->i_range_reg); // 0..20mA <= If exists. - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->i_range_reg); - PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->i_range_reg - instance->reg_base, tmp); - break; - - case 1: // -10V 10V - tmp = inw(instance->current_on_reg); // Volts - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->current_on_reg); - PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->current_on_reg - instance->reg_base, tmp); - - // 0V - outw(0x0800, - (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[instance-> - ao_idx] - - instance->reg_base, 0x0800); - - tmp = inw(instance->uni_bi_reg); // bipolar - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->uni_bi_reg); - PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->uni_bi_reg - instance->reg_base, tmp); - - tmp = inw(instance->i_range_reg); // 0..20mA <= If exists. - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->i_range_reg); - PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->i_range_reg - instance->reg_base, tmp); - break; - - case 2: // 0mA 20mA - tmp = inw(instance->current_on_reg); // mAmpers - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->current_on_reg); - PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->current_on_reg - instance->reg_base, tmp); - - tmp = inw(instance->i_range_reg); // 0..20mA - tmp &= ~(0x1 << instance->ao_idx); - outw(tmp, instance->i_range_reg); - PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->i_range_reg - instance->reg_base, tmp); - - // 0mA - outw(0, - (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[instance-> - ao_idx] - - instance->reg_base, 0); - - tmp = inw(instance->uni_bi_reg); // unipolar - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->uni_bi_reg); - PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->uni_bi_reg - instance->reg_base, tmp); - break; - - case 3: // 4mA 20mA - tmp = inw(instance->current_on_reg); // mAmpers - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->current_on_reg); - PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->current_on_reg - instance->reg_base, tmp); - - tmp = inw(instance->i_range_reg); // 4..20mA - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->i_range_reg); - PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->i_range_reg - instance->reg_base, tmp); - - // 4mA - outw(0, - (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[instance-> - ao_idx] - - instance->reg_base, 0); - - tmp = inw(instance->uni_bi_reg); // unipolar - tmp |= (0x1 << instance->ao_idx); - outw(tmp, instance->uni_bi_reg); - PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->uni_bi_reg - instance->reg_base, tmp); - break; - } - - // Trigger output. - outw(0x0000, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, 0x0000); - outw(0xFFFF, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, 0xFFFF); - - if (trig_chan == ME_TRIG_CHAN_DEFAULT) { // Individual triggering. - (instance->ao_regs_shadows)->synchronous &= - ~(0x1 << instance->ao_idx); - PDEBUG("Individual triggering.\n"); - } else if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) { // Synchronous triggering. - (instance->ao_regs_shadows)->synchronous |= - (0x1 << instance->ao_idx); - PDEBUG("Synchronous triggering.\n"); - } - spin_unlock(instance->config_regs_lock); - spin_unlock(instance->ao_shadows_lock); - - instance->status = ao_status_single_configured; - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me1600_ao_subdevice_t *instance; - unsigned long delay = 0; - unsigned long j = 0; - int err = ME_ERRNO_SUCCESS; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & ~ME_IO_SINGLE_NONBLOCKING) { - PERROR("Invalid flag specified. %d\n", flags); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if ((!flags) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger. - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - j = jiffies; - - //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout. - wait_event_interruptible_timeout(instance->wait_queue, - (!((instance-> - ao_regs_shadows)-> - trigger & instance-> - ao_idx)), - (delay) ? delay : LONG_MAX); - - if (instance == ao_status_none) { // Reset was called. - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - PDEBUG("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - } - } - - *value = (instance->ao_regs_shadows)->mirror[instance->ao_idx]; - - return err; -} - -static int me1600_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me1600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long delay = 0; - int i; - unsigned long j = 0; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & - ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS | - ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (value & ~ME1600_AO_MAX_DATA) { - PERROR("Invalid value provided.\n"); - return ME_ERRNO_VALUE_OUT_OF_RANGE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - (instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx); //Cancell waiting for trigger. - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - //Write value. - spin_lock(instance->ao_shadows_lock); - (instance->ao_regs_shadows)->shadow[instance->ao_idx] = - (uint16_t) value; - - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { // Trigger all outputs from synchronous list. - for (i = 0; i < (instance->ao_regs_shadows)->count; i++) { - if (((instance->ao_regs_shadows)->synchronous & (0x1 << i)) || (i == instance->ao_idx)) { // Set all from synchronous list to correct state. - PDEBUG - ("Synchronous triggering: output %d. idx=%d\n", - i, instance->ao_idx); - (instance->ao_regs_shadows)->mirror[i] = - (instance->ao_regs_shadows)->shadow[i]; - - outw((instance->ao_regs_shadows)->shadow[i], - (instance->ao_regs_shadows)->registry[i]); - PDEBUG_REG - ("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[i] - - instance->reg_base, - (instance->ao_regs_shadows)->shadow[i]); - - (instance->ao_regs_shadows)->trigger &= - ~(0x1 << i); - } - } - - // Trigger output. - outw(0x0000, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, 0); - outw(0xFFFF, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - instance->reg_base, - 0xFFFF); - instance->status = ao_status_single_end; - } else { // Individual mode. - if ((instance->ao_regs_shadows)->synchronous & (0x1 << instance->ao_idx)) { // Put on synchronous start list. Set output as waiting for trigger. - PDEBUG("Add to synchronous list. idx=%d\n", - instance->ao_idx); - (instance->ao_regs_shadows)->trigger |= - (0x1 << instance->ao_idx); - instance->status = ao_status_single_run; - PDEBUG("Synchronous list: 0x%x.\n", - (instance->ao_regs_shadows)->synchronous); - } else { // Fired this one. - PDEBUG("Triggering. idx=%d\n", instance->ao_idx); - (instance->ao_regs_shadows)->mirror[instance->ao_idx] = - (instance->ao_regs_shadows)->shadow[instance-> - ao_idx]; - - outw((instance->ao_regs_shadows)-> - shadow[instance->ao_idx], - (instance->ao_regs_shadows)->registry[instance-> - ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)-> - registry[instance->ao_idx] - - instance->reg_base, - (instance->ao_regs_shadows)-> - shadow[instance->ao_idx]); - - // Set output as triggered. - (instance->ao_regs_shadows)->trigger &= - ~(0x1 << instance->ao_idx); - - // Trigger output. - outw(0x0000, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - - instance->reg_base, 0); - outw(0xFFFF, instance->sim_output_reg); - PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sim_output_reg - - instance->reg_base, 0xFFFF); - instance->status = ao_status_single_end; - } - } - spin_unlock(instance->ao_shadows_lock); - - //Init control task - instance->timeout.delay = delay; - instance->timeout.start_time = jiffies; - instance->ao_control_task_flag = 1; - queue_delayed_work(instance->me1600_workqueue, - &instance->ao_control_task, 1); - - if ((!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) && - ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { - /* Blocking mode. Wait for software trigger. */ - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - j = jiffies; - - //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout. - wait_event_interruptible_timeout(instance->wait_queue, - (!((instance-> - ao_regs_shadows)-> - trigger & instance-> - ao_idx)), - (delay) ? delay : LONG_MAX); - - if (instance == ao_status_none) { - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - PDEBUG("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1600_ao_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - me1600_ao_subdevice_t *instance; - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *number = 1; //Every subdevice has only 1 channel. - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type, - int *subtype) -{ - me1600_ao_subdevice_t *instance; - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *type = ME_TYPE_AO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_AO_TRIG_SYNCHRONOUS; - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - me1600_ao_subdevice_t *instance; - int i; - int r = -1; - int diff = 21E6; - - instance = (me1600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((*max - *min) < 0) { - PERROR("Invalid minimum and maximum values specified.\n"); - return ME_ERRNO_INVALID_MIN_MAX; - } - // Maximum ranges are slightly less then 10V or 20mA. For convenient we accepted this value as valid one. - if (unit == ME_UNIT_VOLT) { - for (i = 0; i < instance->u_ranges_count; i++) { - if ((instance->u_ranges[i].min <= *min) - && ((instance->u_ranges[i].max + 5000) >= *max)) { - if ((instance->u_ranges[i].max - - instance->u_ranges[i].min) - (*max - - *min) < - diff) { - r = i; - diff = - (instance->u_ranges[i].max - - instance->u_ranges[i].min) - - (*max - *min); - } - } - } - - if (r < 0) { - PERROR("No matching range found.\n"); - return ME_ERRNO_NO_RANGE; - } else { - *min = instance->u_ranges[r].min; - *max = instance->u_ranges[r].max; - *range = r; - } - } else if (unit == ME_UNIT_AMPERE) { - for (i = 0; i < instance->i_ranges_count; i++) { - if ((instance->i_ranges[i].min <= *min) - && (instance->i_ranges[i].max + 5000 >= *max)) { - if ((instance->i_ranges[i].max - - instance->i_ranges[i].min) - (*max - - *min) < - diff) { - r = i; - diff = - (instance->i_ranges[i].max - - instance->i_ranges[i].min) - - (*max - *min); - } - } - } - - if (r < 0) { - PERROR("No matching range found.\n"); - return ME_ERRNO_NO_RANGE; - } else { - *min = instance->i_ranges[r].min; - *max = instance->i_ranges[r].max; - *range = r + instance->u_ranges_count; - } - } else { - PERROR("Invalid physical unit specified.\n"); - return ME_ERRNO_INVALID_UNIT; - } - *maxdata = ME1600_AO_MAX_DATA; - - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count) -{ - me1600_ao_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me1600_ao_subdevice_t *) subdevice; - switch (unit) { - case ME_UNIT_VOLT: - *count = instance->u_ranges_count; - break; - case ME_UNIT_AMPERE: - *count = instance->i_ranges_count; - break; - case ME_UNIT_ANY: - *count = instance->u_ranges_count + instance->i_ranges_count; - break; - default: - *count = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me1600_ao_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - me1600_ao_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me1600_ao_subdevice_t *) subdevice; - - if (((range + 1) > - (instance->u_ranges_count + instance->i_ranges_count)) - || (range < 0)) { - PERROR("Invalid range number specified.\n"); - return ME_ERRNO_INVALID_RANGE; - } - - if (range < instance->u_ranges_count) { - *unit = ME_UNIT_VOLT; - *min = instance->u_ranges[range].min; - *max = instance->u_ranges[range].max; - } else if (range < instance->u_ranges_count + instance->i_ranges_count) { - *unit = ME_UNIT_AMPERE; - *min = instance->i_ranges[range - instance->u_ranges_count].min; - *max = instance->i_ranges[range - instance->u_ranges_count].max; - } - *maxdata = ME1600_AO_MAX_DATA; - - return ME_ERRNO_SUCCESS; -} - -static void me1600_ao_work_control_task(struct work_struct *work) -{ - me1600_ao_subdevice_t *instance; - int reschedule = 1; - int signaling = 0; - - instance = - container_of((void *)work, me1600_ao_subdevice_t, ao_control_task); - - PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies, - instance->ao_idx); - - if (!((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { // Output was triggerd. - // Signal the end. - signaling = 1; - reschedule = 0; - if (instance->status == ao_status_single_run) { - instance->status = ao_status_single_end; - } - - } else if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - spin_lock(instance->ao_shadows_lock); - // Restore old settings. - PDEBUG("Write old value back to register.\n"); - (instance->ao_regs_shadows)->shadow[instance->ao_idx] = - (instance->ao_regs_shadows)->mirror[instance->ao_idx]; - - outw((instance->ao_regs_shadows)->mirror[instance->ao_idx], - (instance->ao_regs_shadows)->registry[instance->ao_idx]); - PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - (instance->ao_regs_shadows)->registry[instance-> - ao_idx] - - instance->reg_base, - (instance->ao_regs_shadows)->mirror[instance-> - ao_idx]); - - //Remove from synchronous strt list. - (instance->ao_regs_shadows)->trigger &= - ~(0x1 << instance->ao_idx); - if (instance->status == ao_status_none) { - instance->status = ao_status_single_end; - } - spin_unlock(instance->ao_shadows_lock); - - // Signal the end. - signaling = 1; - reschedule = 0; - } - - if (signaling) { //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - } - - if (instance->ao_control_task_flag && reschedule) { // Reschedule task - queue_delayed_work(instance->me1600_workqueue, - &instance->ao_control_task, 1); - } else { - PINFO("<%s> Ending control task.\n", __func__); - } - -} diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h deleted file mode 100644 index 4827dcb4bf4..00000000000 --- a/drivers/staging/meilhaus/me1600_ao.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - * @file me1600_ao.h - * - * @brief Meilhaus ME-1600 analog output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1600_AO_H_ -#define _ME1600_AO_H_ - -# include -# include "mesubdevice.h" - -# ifdef __KERNEL__ - -# define ME1600_MAX_RANGES 2 /**< Specifies the maximum number of ranges in me1600_ao_subdevice_t::u_ranges und me1600_ao_subdevice_t::i_ranges. */ - -/** - * @brief Defines a entry in the range table. - */ -typedef struct me1600_ao_range_entry { - int32_t min; - int32_t max; -} me1600_ao_range_entry_t; - -typedef struct me1600_ao_timeout { - unsigned long start_time; - unsigned long delay; -} me1600_ao_timeout_t; - -typedef struct me1600_ao_shadow { - int count; - unsigned long *registry; - uint16_t *shadow; - uint16_t *mirror; - uint16_t synchronous; /**< Synchronization list. */ - uint16_t trigger; /**< Synchronization flag. */ -} me1600_ao_shadow_t; - -typedef enum ME1600_AO_STATUS { - ao_status_none = 0, - ao_status_single_configured, - ao_status_single_run, - ao_status_single_end, - ao_status_last -} ME1600_AO_STATUS; - -/** - * @brief The ME-1600 analog output subdevice class. - */ -typedef struct me1600_ao_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - int ao_idx; /**< The index of the analog output subdevice on the device. */ - - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *config_regs_lock; /**< Spin lock to protect configuration registers from concurrent access. */ - - int u_ranges_count; /**< The number of voltage ranges available on this subdevice. */ - me1600_ao_range_entry_t u_ranges[ME1600_MAX_RANGES]; /**< Array holding the voltage ranges on this subdevice. */ - int i_ranges_count; /**< The number of current ranges available on this subdevice. */ - me1600_ao_range_entry_t i_ranges[ME1600_MAX_RANGES]; /**< Array holding the current ranges on this subdevice. */ - - /* Registers */ - unsigned long uni_bi_reg; /**< Register for switching between unipoar and bipolar output mode. */ - unsigned long i_range_reg; /**< Register for switching between ranges. */ - unsigned long sim_output_reg; /**< Register used in order to update all channels simultaneously. */ - unsigned long current_on_reg; /**< Register enabling current output on the fourth subdevice. */ -# ifdef PDEBUG_REG - unsigned long reg_base; -# endif - - ME1600_AO_STATUS status; - me1600_ao_shadow_t *ao_regs_shadows; /**< Addresses and shadows of output's registers. */ - spinlock_t *ao_shadows_lock; /**< Protects the shadow's struct. */ - int mode; /**< Mode in witch output should works. */ - wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */ - me1600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */ - struct workqueue_struct *me1600_workqueue; - struct delayed_work ao_control_task; - - volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */ -} me1600_ao_subdevice_t; - -/** - * @brief The constructor to generate a subdevice template instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param ao_idx The index of the analog output subdevice on the device. - * @param current Flag indicating that analog output with #ao_idx of 3 is capable of current output. - * @param config_regs_lock Pointer to spin lock protecting the configuration registers and from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base, - unsigned int ao_idx, - int curr, - spinlock_t * config_regs_lock, - spinlock_t * ao_shadows_lock, - me1600_ao_shadow_t * - ao_regs_shadows, - struct workqueue_struct - *me1600_wq); - -# endif //__KERNEL__ -#endif //_ME1600_AO_H_ diff --git a/drivers/staging/meilhaus/me1600_ao_reg.h b/drivers/staging/meilhaus/me1600_ao_reg.h deleted file mode 100644 index 31e7800e807..00000000000 --- a/drivers/staging/meilhaus/me1600_ao_reg.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file me1600_ao_reg.h - * - * @brief ME-1600 analog output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1600_AO_REG_H_ -#define _ME1600_AO_REG_H_ - -#ifdef __KERNEL__ - -#define ME1600_CHANNEL_0_REG 0x00 /**< Register to set a digital value on channel 0. */ -#define ME1600_CHANNEL_1_REG 0x02 /**< Register to set a digital value on channel 1. */ -#define ME1600_CHANNEL_2_REG 0x04 /**< Register to set a digital value on channel 2. */ -#define ME1600_CHANNEL_3_REG 0x06 /**< Register to set a digital value on channel 3. */ -#define ME1600_CHANNEL_4_REG 0x08 /**< Register to set a digital value on channel 4. */ -#define ME1600_CHANNEL_5_REG 0x0A /**< Register to set a digital value on channel 5. */ -#define ME1600_CHANNEL_6_REG 0x0C /**< Register to set a digital value on channel 6. */ -#define ME1600_CHANNEL_7_REG 0x0E /**< Register to set a digital value on channel 7. */ -#define ME1600_CHANNEL_8_REG 0x10 /**< Register to set a digital value on channel 8. */ -#define ME1600_CHANNEL_9_REG 0x12 /**< Register to set a digital value on channel 9. */ -#define ME1600_CHANNEL_10_REG 0x14 /**< Register to set a digital value on channel 10. */ -#define ME1600_CHANNEL_11_REG 0x16 /**< Register to set a digital value on channel 11. */ -#define ME1600_CHANNEL_12_REG 0x18 /**< Register to set a digital value on channel 12. */ -#define ME1600_CHANNEL_13_REG 0x1A /**< Register to set a digital value on channel 13. */ -#define ME1600_CHANNEL_14_REG 0x1C /**< Register to set a digital value on channel 14. */ -#define ME1600_CHANNEL_15_REG 0x1E /**< Register to set a digital value on channel 15. */ - -/* Every channel one bit: bipolar = 0, unipolar = 1 */ -#define ME1600_UNI_BI_REG 0x20 /**< Register to switch between unipolar and bipolar. */ - -/* Every channel one bit (only lower 8 Bits): 0..20mA = 0, 4..20mA = 1 */ -#define ME1600_020_420_REG 0x22 /**< Register to switch between the two current ranges. */ - -/* If a bit is set, the corresponding DAC (4 ports each) is - not set at the moment you write to an output of it. - Clearing the bit updates the port. */ -#define ME1600_SIM_OUTPUT_REG 0x24 /**< Register to update all channels of a subdevice simultaneously. */ - -/* Current on/off (only lower 8 bits): off = 0, on = 1 */ -#define ME1600_CURRENT_ON_REG 0x26 /**< Register to swicht between voltage and current output. */ - -#define ME1600_AO_MAX_DATA 0x0FFF /**< The maximum digital data accepted by an analog output channel. */ - -#endif -#endif diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c deleted file mode 100644 index c244e984049..00000000000 --- a/drivers/staging/meilhaus/me1600_device.c +++ /dev/null @@ -1,259 +0,0 @@ -/** - * @file me1600_device.c - * - * @brief ME-1600 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "mesubdevice.h" -#include "me1600_device.h" - -static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base); -static void me1600_destructor(struct me_device *device); - -/** - * @brief Global variable. - * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts). - */ -static struct workqueue_struct *me1600_workqueue; - -me_device_t *me1600_pci_constructor(struct pci_dev *pci_device) -{ - int err; - me1600_device_t *me1600_device; - me_subdevice_t *subdevice; - unsigned int chip_idx; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me1600_device = kmalloc(sizeof(me1600_device_t), GFP_KERNEL); - - if (!me1600_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me1600_device, 0, sizeof(me1600_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me1600_device, pci_device); - - if (err) { - kfree(me1600_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - // Initialize spin lock . - spin_lock_init(&me1600_device->config_regs_lock); - spin_lock_init(&me1600_device->ao_shadows_lock); - - // Get the number of analog output subdevices. - chip_idx = - me1600_versions_get_device_index(me1600_device->base.info.pci. - device_id); - - // Create shadow instance. - me1600_device->ao_regs_shadows.count = - me1600_versions[chip_idx].ao_chips; - me1600_device->ao_regs_shadows.registry = - kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(unsigned long), - GFP_KERNEL); - me1600_set_registry(me1600_device, - me1600_device->base.info.pci.reg_bases[2]); - me1600_device->ao_regs_shadows.shadow = - kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t), - GFP_KERNEL); - me1600_device->ao_regs_shadows.mirror = - kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t), - GFP_KERNEL); - - // Create subdevice instances. - for (i = 0; i < me1600_versions[chip_idx].ao_chips; i++) { - subdevice = - (me_subdevice_t *) me1600_ao_constructor(me1600_device-> - base.info.pci. - reg_bases[2], i, - ((me1600_versions - [chip_idx].curr > - i) ? 1 : 0), - &me1600_device-> - config_regs_lock, - &me1600_device-> - ao_shadows_lock, - &me1600_device-> - ao_regs_shadows, - me1600_workqueue); - - if (!subdevice) { - me_device_deinit((me_device_t *) me1600_device); - kfree(me1600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me1600_device->base.slist, - subdevice); - } - - // Overwrite base class methods. - me1600_device->base.me_device_destructor = me1600_destructor; - - return (me_device_t *) me1600_device; -} -EXPORT_SYMBOL(me1600_pci_constructor); - -static void me1600_destructor(struct me_device *device) -{ - me1600_device_t *me1600_device = (me1600_device_t *) device; - PDEBUG("executed.\n"); - - // Destroy shadow instance. - kfree(me1600_device->ao_regs_shadows.registry); - kfree(me1600_device->ao_regs_shadows.shadow); - kfree(me1600_device->ao_regs_shadows.mirror); - - me_device_deinit((me_device_t *) me1600_device); - kfree(me1600_device); -} - -static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base) -{ // Create shadow structure. - if (subdevice->ao_regs_shadows.count >= 1) { - subdevice->ao_regs_shadows.registry[0] = - (unsigned long)(reg_base + ME1600_CHANNEL_0_REG); - } - if (subdevice->ao_regs_shadows.count >= 2) { - subdevice->ao_regs_shadows.registry[1] = - (unsigned long)(reg_base + ME1600_CHANNEL_1_REG); - } - if (subdevice->ao_regs_shadows.count >= 3) { - subdevice->ao_regs_shadows.registry[2] = - (unsigned long)(reg_base + ME1600_CHANNEL_2_REG); - } - if (subdevice->ao_regs_shadows.count >= 4) { - subdevice->ao_regs_shadows.registry[3] = - (unsigned long)(reg_base + ME1600_CHANNEL_3_REG); - } - if (subdevice->ao_regs_shadows.count >= 5) { - subdevice->ao_regs_shadows.registry[4] = - (unsigned long)(reg_base + ME1600_CHANNEL_4_REG); - } - if (subdevice->ao_regs_shadows.count >= 6) { - subdevice->ao_regs_shadows.registry[5] = - (unsigned long)(reg_base + ME1600_CHANNEL_5_REG); - } - if (subdevice->ao_regs_shadows.count >= 7) { - subdevice->ao_regs_shadows.registry[6] = - (unsigned long)(reg_base + ME1600_CHANNEL_6_REG); - } - if (subdevice->ao_regs_shadows.count >= 8) { - subdevice->ao_regs_shadows.registry[7] = - (unsigned long)(reg_base + ME1600_CHANNEL_7_REG); - } - if (subdevice->ao_regs_shadows.count >= 9) { - subdevice->ao_regs_shadows.registry[8] = - (unsigned long)(reg_base + ME1600_CHANNEL_8_REG); - } - if (subdevice->ao_regs_shadows.count >= 10) { - subdevice->ao_regs_shadows.registry[9] = - (unsigned long)(reg_base + ME1600_CHANNEL_9_REG); - } - if (subdevice->ao_regs_shadows.count >= 11) { - subdevice->ao_regs_shadows.registry[10] = - (unsigned long)(reg_base + ME1600_CHANNEL_10_REG); - } - if (subdevice->ao_regs_shadows.count >= 12) { - subdevice->ao_regs_shadows.registry[11] = - (unsigned long)(reg_base + ME1600_CHANNEL_11_REG); - } - if (subdevice->ao_regs_shadows.count >= 13) { - subdevice->ao_regs_shadows.registry[12] = - (unsigned long)(reg_base + ME1600_CHANNEL_12_REG); - } - if (subdevice->ao_regs_shadows.count >= 14) { - subdevice->ao_regs_shadows.registry[13] = - (unsigned long)(reg_base + ME1600_CHANNEL_13_REG); - } - if (subdevice->ao_regs_shadows.count >= 15) { - subdevice->ao_regs_shadows.registry[14] = - (unsigned long)(reg_base + ME1600_CHANNEL_14_REG); - } - if (subdevice->ao_regs_shadows.count >= 16) { - subdevice->ao_regs_shadows.registry[15] = - (unsigned long)(reg_base + ME1600_CHANNEL_15_REG); - } - if (subdevice->ao_regs_shadows.count > 16) { - PERROR("More than 16 outputs! (%d)\n", - subdevice->ao_regs_shadows.count); - } -} - -// Init and exit of module. - -static int __init me1600_init(void) -{ - PDEBUG("executed\n."); - - me1600_workqueue = create_singlethread_workqueue("me1600"); - return 0; -} - -static void __exit me1600_exit(void) -{ - PDEBUG("executed\n."); - - flush_workqueue(me1600_workqueue); - destroy_workqueue(me1600_workqueue); -} - -module_init(me1600_init); -module_exit(me1600_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me1600_device.h b/drivers/staging/meilhaus/me1600_device.h deleted file mode 100644 index c73aca11ae8..00000000000 --- a/drivers/staging/meilhaus/me1600_device.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file me1600_device.h - * - * @brief ME-1600 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME1600_H -#define _ME1600_H - -#include -#include - -#include "medevice.h" -#include "me1600_ao.h" -#include "me1600_ao_reg.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure to store device capabilities. - */ -typedef struct me1600_version { - uint16_t device_id; /**< The PCI device id of the device. */ - unsigned int ao_chips; /**< The number of analog outputs on the device. */ - int curr; /**< Flag to identify amounts of current output. */ -} me1600_version_t; - -/** - * @brief Defines for each ME-1600 device version its capabilities. - */ -static me1600_version_t me1600_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME1600_4U, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME1600_8U, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME1600_12U, 12, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME1600_16U, 16, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I, 16, 8}, - {0} -}; - -/**< Returns the number of entries in #me1600_versions. */ -#define ME1600_DEVICE_VERSIONS (ARRAY_SIZE(me1600_versions) - 1) - -/** - * @brief Returns the index of the device entry in #me1600_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me1600_versions. - */ -static inline unsigned int me1600_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME1600_DEVICE_VERSIONS; i++) - if (me1600_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-1600 device class structure. - */ -typedef struct me1600_device { - me_device_t base; /**< The Meilhaus device base class. */ - spinlock_t config_regs_lock; /**< Protects the configuration registers. */ - - me1600_ao_shadow_t ao_regs_shadows; /**< Addresses and shadows of output's registers. */ - spinlock_t ao_shadows_lock; /**< Protects the shadow's struct. */ -} me1600_device_t; - -/** - * @brief The ME-1600 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-1600 device instance. \n - * NULL on error. - */ -me_device_t *me1600_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c deleted file mode 100644 index fd9daa942fb..00000000000 --- a/drivers/staging/meilhaus/me4600_ai.c +++ /dev/null @@ -1,3405 +0,0 @@ -/** - * @file me4600_ai.c - * - * @brief ME-4000 analog input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "medebug.h" -#include "meids.h" - -#include "me4600_reg.h" -#include "me4600_ai_reg.h" -#include "me4600_ai.h" - -/* - * Declarations (local) - */ - -static void me4600_ai_destructor(struct me_subdevice *subdevice); -static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags); - -static int me4600_ai_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags); - -static int me4600_ai_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags); - -static int me4600_ai_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags); -static int me4600_ai_io_stream_read(me_subdevice_t *subdevice, - struct file *filep, - int read_mode, - int *values, int *count, int flags); -static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags); -static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t * - instance, int *values, - const int count, - const int flags); - -static int me4600_ai_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags); -static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags); -static int me4600_ai_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags); - -static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range); -static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count); -static int me4600_ai_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata); -static int me4600_ai_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks); -static int me4600_ai_query_number_channels(me_subdevice_t *subdevice, - int *number); -static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype); -static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps); -static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count); - -static irqreturn_t me4600_ai_isr(int irq, void *dev_id); - -static int ai_mux_toggler(me4600_ai_subdevice_t *subdevice); - -/** Immidiate stop. -* Reset all IRQ's sources. (block laches) -* Preserve FIFO -*/ -static int ai_stop_immediately(me4600_ai_subdevice_t *instance); - -/** Immidiate stop. -* Reset all IRQ's sources. (block laches) -* Reset data FIFO -*/ -inline void ai_stop_isr(me4600_ai_subdevice_t *instance); - -/** Interrupt logics. -* Read datas -* Reset latches -*/ -void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status, - const uint32_t ctrl_status); -void ai_infinite_isr(me4600_ai_subdevice_t *instance, - const uint32_t irq_status, const uint32_t ctrl_status); - -/** Last chunck of datas. We must reschedule sample counter. -* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts. -* When threshold is wrongly set some IRQ are lost.(!!!) -*/ -inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance); - -/** Read datas from FIFO and copy them to buffer */ -static inline int ai_read_data(me4600_ai_subdevice_t *instance, - const int count); - -/** Copy rest of data from fifo to circular buffer.*/ -static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance); - -/** Set ISM to next state for infinite data aqusation mode*/ -inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance); - -/** Set ISM to next state for define amount of data aqusation mode*/ -inline void ai_limited_ISM(me4600_ai_subdevice_t *instance, - uint32_t irq_status); - -/** Set ISM to next stage for limited mode */ -inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance); - -static void me4600_ai_work_control_task(struct work_struct *work); - -/* Definitions - */ - -me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base, - unsigned int channels, - unsigned int ranges, - int isolated, - int sh, - int irq, - spinlock_t *ctrl_reg_lock, - struct workqueue_struct *me4600_wq) -{ - me4600_ai_subdevice_t *subdevice; - int err; - unsigned int i; - - PDEBUG("executed. idx=0\n"); - - // Allocate memory for subdevice instance. - subdevice = kmalloc(sizeof(me4600_ai_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_ai_subdevice_t)); - - // Initialize subdevice base class. - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - // Initialize circular buffer. - subdevice->circ_buf.mask = ME4600_AI_CIRC_BUF_COUNT - 1; - - subdevice->circ_buf.buf = - (void *)__get_free_pages(GFP_KERNEL, ME4600_AI_CIRC_BUF_SIZE_ORDER); - PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf, - ME4600_AI_CIRC_BUF_SIZE); - - if (!subdevice->circ_buf.buf) { - PERROR("Cannot get circular buffer.\n"); - me_subdevice_deinit((me_subdevice_t *) subdevice); - kfree(subdevice); - return NULL; - } - - memset(subdevice->circ_buf.buf, 0, ME4600_AI_CIRC_BUF_SIZE); - subdevice->circ_buf.head = 0; - subdevice->circ_buf.tail = 0; - subdevice->status = ai_status_none; - - // Initialize wait queue. - init_waitqueue_head(&subdevice->wait_queue); - - // Save the number of channels. - subdevice->channels = channels; - - /* Initialize the single config entries to reset values */ - for (i = 0; i < channels; i++) { - subdevice->single_config[i].status = ME_SINGLE_CHANNEL_NOT_CONFIGURED; //not configured - } - - // Save if isolated device. - subdevice->isolated = isolated; - - // Save if sample and hold is available. - subdevice->sh = sh; - - // Set stream config to not configured state. - subdevice->fifo_irq_threshold = 0; - subdevice->data_required = 0; - subdevice->chan_list_len = 0; - - // Initialize registers addresses. - subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AI_STATUS_REG; - subdevice->channel_list_reg = reg_base + ME4600_AI_CHANNEL_LIST_REG; - subdevice->data_reg = reg_base + ME4600_AI_DATA_REG; - subdevice->chan_timer_reg = reg_base + ME4600_AI_CHAN_TIMER_REG; - subdevice->chan_pre_timer_reg = reg_base + ME4600_AI_CHAN_PRE_TIMER_REG; - subdevice->scan_timer_low_reg = reg_base + ME4600_AI_SCAN_TIMER_LOW_REG; - subdevice->scan_timer_high_reg = - reg_base + ME4600_AI_SCAN_TIMER_HIGH_REG; - subdevice->scan_pre_timer_low_reg = - reg_base + ME4600_AI_SCAN_PRE_TIMER_LOW_REG; - subdevice->scan_pre_timer_high_reg = - reg_base + ME4600_AI_SCAN_PRE_TIMER_HIGH_REG; - subdevice->start_reg = reg_base + ME4600_AI_START_REG; - subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG; - subdevice->sample_counter_reg = reg_base + ME4600_AI_SAMPLE_COUNTER_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - // Initialize ranges. - subdevice->ranges_len = ranges; - subdevice->ranges[0].min = -10E6; - subdevice->ranges[0].max = 9999694; - - subdevice->ranges[1].min = 0; - subdevice->ranges[1].max = 9999847; - - subdevice->ranges[2].min = -25E5; - subdevice->ranges[2].max = 2499923; - - subdevice->ranges[3].min = 0; - subdevice->ranges[3].max = 2499961; - - // We have to switch the mux in order to get it work correctly. - ai_mux_toggler(subdevice); - - // Register interrupt service routine. - subdevice->irq = irq; - if (request_irq(subdevice->irq, me4600_ai_isr, - IRQF_DISABLED | IRQF_SHARED, - ME4600_NAME, subdevice)) { - PERROR("Cannot register interrupt service routine.\n"); - me_subdevice_deinit((me_subdevice_t *) subdevice); - free_pages((unsigned long)subdevice->circ_buf.buf, - ME4600_AI_CIRC_BUF_SIZE_ORDER); - subdevice->circ_buf.buf = NULL; - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - - // Override base class methods. - subdevice->base.me_subdevice_destructor = me4600_ai_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_ai_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_ai_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_ai_io_single_read; - subdevice->base.me_subdevice_io_stream_config = - me4600_ai_io_stream_config; - subdevice->base.me_subdevice_io_stream_new_values = - me4600_ai_io_stream_new_values; - subdevice->base.me_subdevice_io_stream_read = me4600_ai_io_stream_read; - subdevice->base.me_subdevice_io_stream_start = - me4600_ai_io_stream_start; - subdevice->base.me_subdevice_io_stream_status = - me4600_ai_io_stream_status; - subdevice->base.me_subdevice_io_stream_stop = me4600_ai_io_stream_stop; - subdevice->base.me_subdevice_query_number_channels = - me4600_ai_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_ai_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_ai_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me4600_ai_query_subdevice_caps_args; - subdevice->base.me_subdevice_query_range_by_min_max = - me4600_ai_query_range_by_min_max; - subdevice->base.me_subdevice_query_number_ranges = - me4600_ai_query_number_ranges; - subdevice->base.me_subdevice_query_range_info = - me4600_ai_query_range_info; - subdevice->base.me_subdevice_query_timer = me4600_ai_query_timer; - - // Prepare work queue. - subdevice->me4600_workqueue = me4600_wq; - -/* workqueue API changed in kernel 2.6.20 */ - INIT_DELAYED_WORK(&subdevice->ai_control_task, - me4600_ai_work_control_task); - - return subdevice; -} - -static void me4600_ai_destructor(struct me_subdevice *subdevice) -{ - me4600_ai_subdevice_t *instance; - - instance = (me4600_ai_subdevice_t *) subdevice; - - PDEBUG("executed. idx=0\n"); - - instance->ai_control_task_flag = 0; - // Reset subdevice to asure clean exit. - me4600_ai_io_reset_subdevice(subdevice, NULL, - ME_IO_RESET_SUBDEVICE_NO_FLAGS); - - // Remove any tasks from work queue. This is paranoic because it was done allready in reset(). - if (!cancel_delayed_work(&instance->ai_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue. - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(2); - } - - free_irq(instance->irq, instance); - free_pages((unsigned long)instance->circ_buf.buf, - ME4600_AI_CIRC_BUF_SIZE_ORDER); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - volatile uint32_t ctrl; - unsigned long status; - const int timeout = HZ / 10; //100ms - int i; - - PDEBUG("executed. idx=0\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - instance = (me4600_ai_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - instance->ai_control_task_flag = 0; - instance->status = ai_status_none; - - for (i = 0; i <= timeout; i++) { - spin_lock_irqsave(instance->ctrl_reg_lock, status); - ctrl = inl(instance->ctrl_reg); - //Stop DMA - ctrl &= ~ME4600_AI_CTRL_RPCI_FIFO; - // Stop all actions. No conditions! - ctrl &= ~ME4600_AI_CTRL_BIT_STOP; - ctrl |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP; - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(instance->ctrl_reg_lock, status); - - if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) - break; - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - if (i > timeout) { - PERROR("FSM is still busy.\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - - spin_lock_irqsave(instance->ctrl_reg_lock, status); - ctrl = inl(instance->ctrl_reg); - // Clear all features. Dissable interrupts. - ctrl &= ~(ME4600_AI_CTRL_BIT_STOP - | ME4600_AI_CTRL_BIT_LE_IRQ - | ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ); - ctrl |= (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP - | ME4600_AI_CTRL_BIT_LE_IRQ_RESET - | ME4600_AI_CTRL_BIT_HF_IRQ_RESET - | ME4600_AI_CTRL_BIT_SC_IRQ_RESET); - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(instance->ctrl_reg_lock, status); - - outl(ME4600_AI_MIN_CHAN_TICKS - 1, instance->chan_timer_reg); - PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llx\n", - instance->reg_base, - instance->chan_timer_reg - instance->reg_base, - ME4600_AI_MIN_CHAN_TICKS); - outl(ME4600_AI_MIN_ACQ_TICKS - 1, instance->chan_pre_timer_reg); - PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llx\n", - instance->reg_base, - instance->chan_pre_timer_reg - instance->reg_base, - ME4600_AI_MIN_ACQ_TICKS); - outl(0, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, 0); - outl(0, instance->scan_pre_timer_low_reg); - PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_pre_timer_high_reg); - PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_high_reg - instance->reg_base, 0); - outl(0xEFFFFFFF, instance->sample_counter_reg); - PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - 0xEFFFFFFF); - - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - - instance->fifo_irq_threshold = 0; - instance->data_required = 0; - instance->chan_list_len = 0; - - // Initialize the single config entries to reset values. - for (i = 0; i < instance->channels; i++) { - instance->single_config[i].status = - ME_SINGLE_CHANNEL_NOT_CONFIGURED; - } - instance->status = ai_status_none; - - //Signal reset if user is on wait. - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags; - int i; - - instance = (me4600_ai_subdevice_t *) subdevice; - - PDEBUG("executed. idx=0\n"); - - if (flags & ~ME_IO_SINGLE_CONFIG_CONTINUE) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - switch (trig_type) { - case ME_TRIG_TYPE_SW: - if (trig_edge != ME_TRIG_EDGE_NONE) { - PERROR - ("Invalid trigger edge. Software trigger has not edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - break; - - case ME_TRIG_TYPE_EXT_ANALOG: - if (instance->channels <= 16) //Only versions with 32 channels have analog trigger (4670 and 4680) - { - PERROR("Invalid trigger type specified.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - - case ME_TRIG_TYPE_EXT_DIGITAL: - if ((trig_edge != ME_TRIG_EDGE_ANY) - && (trig_edge != ME_TRIG_EDGE_RISING) - && (trig_edge != ME_TRIG_EDGE_FALLING)) { - PERROR("Invalid trigger edge specified.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - break; - - default: - PERROR("Invalid trigger type specified.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - - if (trig_chan != ME_TRIG_CHAN_DEFAULT) { - PERROR("Invalid trigger channel specified.\n"); - return ME_ERRNO_INVALID_TRIG_CHAN; - } - - if ((single_config < 0) || (single_config >= instance->ranges_len)) { - PERROR("Invalid single config specified.\n"); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - - if ((ref != ME_REF_AI_GROUND) && (ref != ME_REF_AI_DIFFERENTIAL)) { - PERROR("Invalid analog reference specified.\n"); - return ME_ERRNO_INVALID_REF; - } - - if ((single_config % 2) && (ref != ME_REF_AI_GROUND)) { - PERROR("Invalid analog reference specified.\n"); - return ME_ERRNO_INVALID_REF; - } - - if ((ref == ME_REF_AI_DIFFERENTIAL) - && ((instance->channels == 16) || (channel >= 16))) { - PERROR("Invalid analog reference specified.\n"); - return ME_ERRNO_INVALID_REF; - } - - if (channel < 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (channel >= instance->channels) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - //Prepare data entry. - // Common for all modes. - instance->single_config[channel].entry = - channel | ME4600_AI_LIST_LAST_ENTRY; - - if (ref == ME_REF_AI_DIFFERENTIAL) { // ME_REF_AI_DIFFERENTIAL - instance->single_config[channel].entry |= - ME4600_AI_LIST_INPUT_DIFFERENTIAL; - } -/* - // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000 - // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' <== Do nothing. Removed. - else - {// ME_REF_AI_GROUND - instance->single_config[channel].entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED; - } -*/ - switch (single_config) { - case 0: //-10V..10V -/* - // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000 - // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed. - instance->single_config[channel].entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10; -*/ break; - - case 1: //0V..10V - instance->single_config[channel].entry |= - ME4600_AI_LIST_RANGE_UNIPOLAR_10; - break; - - case 2: //-2.5V..2.5V - instance->single_config[channel].entry |= - ME4600_AI_LIST_RANGE_BIPOLAR_2_5; - break; - - case 3: //0V..2.5V - instance->single_config[channel].entry |= - ME4600_AI_LIST_RANGE_UNIPOLAR_2_5; - break; - } - - // Prepare control register. - // Common for all modes. - instance->single_config[channel].ctrl = - ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO; - - switch (trig_type) { - case ME_TRIG_TYPE_SW: - // Nothing to set. - break; - - case ME_TRIG_TYPE_EXT_ANALOG: - instance->single_config[channel].ctrl |= - ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG; - - case ME_TRIG_TYPE_EXT_DIGITAL: - instance->single_config[channel].ctrl |= - ME4600_AI_CTRL_BIT_EX_TRIG; - break; - } - - switch (trig_edge) { - case ME_TRIG_EDGE_RISING: - // Nothing to set. - break; - - case ME_TRIG_EDGE_ANY: - instance->single_config[channel].ctrl |= - ME4600_AI_CTRL_BIT_EX_TRIG_BOTH; - - case ME_TRIG_EDGE_FALLING: - instance->single_config[channel].ctrl |= - ME4600_AI_CTRL_BIT_EX_TRIG_FALLING; - break; - } - - // Enable this channel - instance->single_config[channel].status = ME_SINGLE_CHANNEL_CONFIGURED; - - // Copy this settings to other outputs. - if (flags == ME_IO_SINGLE_CONFIG_CONTINUE) { - for (i = channel + 1; i < instance->channels; i++) { - instance->single_config[i].ctrl = - instance->single_config[channel].ctrl; - instance->single_config[i].entry = - instance->single_config[channel].entry; - instance->single_config[i].status = - ME_SINGLE_CHANNEL_CONFIGURED; - } - } - - instance->status = ai_status_single_configured; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_ai_subdevice_t *instance; - volatile uint32_t tmp; - volatile uint32_t val; - unsigned long cpu_flags; - int err = ME_ERRNO_SUCCESS; - - unsigned long j; - unsigned long delay = 0; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (instance->status != ai_status_single_configured) { - PERROR("Subdevice not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - if ((channel > instance->channels) || (channel < 0)) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (instance->single_config[channel].status != - ME_SINGLE_CHANNEL_CONFIGURED) { - PERROR("Channel is not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) { - PERROR("Subdevice is busy.\n"); - return ME_ERRNO_SUBDEVICE_BUSY; - } - - ME_SUBDEVICE_ENTER; - - // Cancel control task - PDEBUG("Cancel control task.\n"); - instance->ai_control_task_flag = 0; - cancel_delayed_work(&instance->ai_control_task); - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - // Mark that StreamConfig is removed. - instance->chan_list_len = 0; - - spin_lock(instance->ctrl_reg_lock); - /// @note Imprtant: Preserve EXT IRQ settings. - tmp = inl(instance->ctrl_reg); - // Clear FIFOs and dissable interrupts - tmp &= - ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO); - - tmp &= - ~(ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ | - ME4600_AI_CTRL_BIT_LE_IRQ); - tmp |= - ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET | - ME4600_AI_CTRL_BIT_LE_IRQ_RESET; - - tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - outl(0, instance->scan_pre_timer_low_reg); - PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_pre_timer_high_reg); - PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_high_reg - instance->reg_base, 0); - outl(0, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, 0); - outl(65, instance->chan_timer_reg); - PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->chan_timer_reg - instance->reg_base, 65); - outl(65, instance->chan_pre_timer_reg); - PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->chan_pre_timer_reg - instance->reg_base, 65); - - //Reactive FIFOs. Enable work. - tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - outl(instance->single_config[channel].entry, - instance->channel_list_reg); - PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->channel_list_reg - instance->reg_base, - instance->single_config[channel].entry); - - // Preserve EXT IRQ settings. - tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET); - outl(instance->single_config[channel].ctrl | tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, - instance->single_config[channel].ctrl | tmp); - - spin_unlock(instance->ctrl_reg_lock); - - if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start - inl(instance->start_reg); - PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base, - instance->start_reg - instance->reg_base); - - delay = 2; - } - - j = jiffies; - - while (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) { - if (delay && ((jiffies - j) >= delay)) { - if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) { // Software start. - PERROR("Value not available after wait.\n"); - err = ME_ERRNO_INTERNAL; - } else { // External start. - PERROR("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - } - break; - } - // Wait - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - - if (signal_pending(current)) { - PERROR - ("Wait on external trigger interrupted by signal.\n"); - err = ME_ERRNO_SIGNAL; - break; - } - - if (instance->status != ai_status_single_configured) { - PERROR("Wait interrupted by reset.\n"); - err = ME_ERRNO_CANCELLED; - break; - } - } - - // Read value. - if (!err) { - val = inl(instance->data_reg) ^ 0x8000; - PDEBUG_REG("data_reg inl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->data_reg - instance->reg_base, val); - *value = val & ME4600_AI_MAX_DATA; - } else { - *value = 0xFFFFFFFF; - } - - // Restore settings. - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - // Clear FIFOs and dissable interrupts. - tmp &= - ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO); - tmp |= ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ; - tmp |= - ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET | - ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->ctrl_reg_lock); - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - int i; // internal multipurpose variable - unsigned long long data_required; - - volatile uint32_t entry; - volatile uint32_t ctrl = ME4600_AI_CTRL_BIT_IMMEDIATE_STOP; - volatile uint32_t tmp; // use when current copy of register's value needed - unsigned long cpu_flags; - - uint64_t acq_ticks; - uint64_t scan_ticks; - uint64_t conv_ticks; - unsigned int acq_start_ticks_low = trigger->iAcqStartTicksLow; - unsigned int acq_start_ticks_high = trigger->iAcqStartTicksHigh; - unsigned int scan_start_ticks_low = trigger->iScanStartTicksLow; - unsigned int scan_start_ticks_high = trigger->iScanStartTicksHigh; - unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow; - unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER - // Convert ticks to 64 bit long values - acq_ticks = - (uint64_t) acq_start_ticks_low + - ((uint64_t) acq_start_ticks_high << 32); - scan_ticks = - (uint64_t) scan_start_ticks_low + - ((uint64_t) scan_start_ticks_high << 32); - conv_ticks = - (uint64_t) conv_start_ticks_low + - ((uint64_t) conv_start_ticks_high << 32); - - // Check settings - begin - switch (trigger->iAcqStartTrigType) { - case ME_TRIG_TYPE_SW: - case ME_TRIG_TYPE_EXT_DIGITAL: - case ME_TRIG_TYPE_EXT_ANALOG: - break; - - default: - PERROR("Invalid acquisition start trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE; - goto ERROR; - break; - } - - if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) - && (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE)) { - PERROR("Invalid acquisition start trigger edge specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - goto ERROR; - } - - if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW) { - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_RISING: - case ME_TRIG_EDGE_FALLING: - case ME_TRIG_EDGE_ANY: - break; - - default: - PERROR - ("Invalid acquisition start trigger edge specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - goto ERROR; - break; - } - } - - if (trigger->iAcqStartTrigChan != ME_TRIG_CHAN_DEFAULT) { - PERROR - ("Invalid acquisition start trigger channel specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN; - goto ERROR; - } - - if ((acq_ticks < ME4600_AI_MIN_ACQ_TICKS) - || (acq_ticks > ME4600_AI_MAX_ACQ_TICKS)) { - PERROR - ("Invalid acquisition start trigger argument specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_ARG; - goto ERROR; - } - - switch (trigger->iScanStartTrigType) { - - case ME_TRIG_TYPE_TIMER: - if ((scan_ticks < ME4600_AI_MIN_SCAN_TICKS) - || (scan_ticks > ME4600_AI_MAX_SCAN_TICKS) - || (scan_ticks < count * conv_ticks) - ) { - PERROR("Invalid scan start argument specified.\n"); - err = ME_ERRNO_INVALID_SCAN_START_ARG; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL) { - PERROR - ("Invalid scan start trigger type specified (Acq is HW digital)\n"); - err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_EXT_ANALOG: - if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_ANALOG) { - PERROR - ("Invalid scan start trigger type specified (Acq is HW analog)\n"); - err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_FOLLOW: - break; - - default: - PERROR("Invalid scan start trigger type specified.\n"); - err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - goto ERROR; - break; - } - - switch (trigger->iConvStartTrigType) { - - case ME_TRIG_TYPE_TIMER: - if ((conv_ticks < ME4600_AI_MIN_CHAN_TICKS) - || (conv_ticks > ME4600_AI_MAX_CHAN_TICKS)) { - PERROR - ("Invalid conv start trigger argument specified.\n"); - err = ME_ERRNO_INVALID_CONV_START_ARG; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) - || (trigger->iAcqStartTrigType != - ME_TRIG_TYPE_EXT_DIGITAL)) { - PERROR("Invalid conv start trigger type specified.\n"); - err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_EXT_ANALOG: - if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) - || (trigger->iAcqStartTrigType != - ME_TRIG_TYPE_EXT_ANALOG)) { - PERROR("Invalid conv start trigger type specified.\n"); - err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - goto ERROR; - } - break; - - default: - PERROR("Invalid conv start trigger type specified.\n"); - err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - goto ERROR; - - break; - } -/** -* Aceptable settings: -* iScanStopTrigType : iAcqStopTrigType -* -* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_NONE -> infinite count with manual stop -* ME_TRIG_TYPE_NONE : ME_TRIG_TYPE_COUNT -> stop after getting iScanStopCount list of values (iScanStopCount * count) -* ME_TRIG_TYPE_COUNT : ME_TRIG_TYPE_FOLLOW -> stop after getting iAcqStopCount values (it can stops in midle of the list) -*/ - switch (trigger->iScanStopTrigType) { - - case ME_TRIG_TYPE_NONE: - break; - - case ME_TRIG_TYPE_COUNT: - if (trigger->iScanStopCount <= 0) { - PERROR("Invalid scan stop argument specified.\n"); - err = ME_ERRNO_INVALID_SCAN_STOP_ARG; - goto ERROR; - } - break; - - default: - PERROR("Invalid scan stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE; - goto ERROR; - break; - } - - switch (trigger->iAcqStopTrigType) { - - case ME_TRIG_TYPE_NONE: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) { - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_FOLLOW: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_COUNT) { - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - break; - - case ME_TRIG_TYPE_COUNT: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) { - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - - if (trigger->iAcqStopCount <= 0) { - PERROR - ("Invalid acquisition or scan stop argument specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_ARG; - goto ERROR; - } - break; - - default: - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - break; - } - - if ((count <= 0) || (count > ME4600_AI_LIST_COUNT)) { - PERROR("Invalid channel list count specified.\n"); - err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT; - goto ERROR; - } -///This is general limitation -// if (fifo_irq_threshold < 0 || fifo_irq_threshold >= ME4600_AI_CIRC_BUF_COUNT) -///This is limitation from Windows. I use it for compatibility. - if (fifo_irq_threshold < 0 - || fifo_irq_threshold >= ME4600_AI_FIFO_COUNT) { - PERROR("Invalid fifo irq threshold specified.\n"); - err = ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD; - goto ERROR; - } - - if ((config_list[0].iRef == ME_REF_AI_DIFFERENTIAL) - && (instance->channels == 16)) { - PERROR - ("Differential reference is not available on this subdevice.\n"); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - - if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) { - if (!instance->sh) { - PERROR - ("Sample and hold is not available for this board.\n"); - err = ME_ERRNO_INVALID_FLAGS; - goto ERROR; - } - if (config_list[0].iRef == ME_REF_AI_DIFFERENTIAL) { - PERROR - ("Sample and hold is not available in differential mode.\n"); - err = ME_ERRNO_INVALID_FLAGS; - goto ERROR; - } - } - - for (i = 0; i < count; i++) { - if ((config_list[i].iStreamConfig < 0) - || (config_list[i].iStreamConfig >= instance->ranges_len)) { - PERROR("Invalid stream config specified.\n"); - err = ME_ERRNO_INVALID_STREAM_CONFIG; - goto ERROR; - } - - if ((config_list[i].iRef != ME_REF_AI_GROUND) - && (config_list[i].iRef != ME_REF_AI_DIFFERENTIAL)) { - PERROR("Invalid references in the list. Ref=0x%x\n", - config_list[i].iRef); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - - if (config_list[i].iStreamConfig % 2) { // StreamConfig: 1 or 3 - if (config_list[i].iRef == ME_REF_AI_DIFFERENTIAL) { - PERROR - ("Only bipolar modes support differential measurement.\n"); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - } - - if (config_list[i].iRef != config_list[0].iRef) { - PERROR - ("Not all references in the configuration list are equal. Ref[0]=0x%x Ref[%d]=0x%x\n", - config_list[0].iRef, i, config_list[i].iRef); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - - if ((config_list[i].iRef == ME_REF_AI_DIFFERENTIAL) - && (config_list[i].iChannel >= 16)) { - PERROR("Channel not available in differential mode.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - goto ERROR; - } - - if ((config_list[i].iChannel < 0) - || (config_list[i].iChannel >= instance->channels)) { - PERROR("Invalid channel number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - goto ERROR; - } - } - - // Check settings - end - - //Cancel control task - PDEBUG("Cancel control task.\n"); - instance->ai_control_task_flag = 0; - cancel_delayed_work(&instance->ai_control_task); - - // Work around from Keith Hartley - begin - if (trigger->iScanStartTrigType == ME_TRIG_TYPE_TIMER) { - if (count == 1) { - // The hardware does not work properly with a non-zero scan time - // if there is only ONE channel in the channel list. In this case - // we must set the scan time to zero and use the channel time. - - conv_ticks = scan_ticks; - trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW; - } else if (scan_ticks == count * conv_ticks) { - // Another hardware problem. If the number of scan ticks is - // exactly equal to the number of channel ticks multiplied by - // the number of channels then the sampling rate is reduced - // by half. - trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW; - } - } - // Work around from Keith Hartley - end - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) { - PERROR("Subdevice is busy.\n"); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_SUBDEVICE_BUSY; - } - - instance->status = ai_status_none; - spin_lock(instance->ctrl_reg_lock); - // Stop all actions. Block all interrupts. Clear (disable) FIFOs. - ctrl = - ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET | - ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - - tmp = inl(instance->ctrl_reg); - // Preserve EXT IRQ and OFFSET settings. Clean other bits. - tmp &= - (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET | - ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET); - - // Send it to register. - outl(tmp | ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp | ctrl); - - // Enable channel fifo -> data fifo in stream_start(). - ctrl |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO; - outl(tmp | ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp | ctrl); - spin_unlock(instance->ctrl_reg_lock); - - // Write the channel list - for (i = 0; i < count; i++) { - entry = config_list[i].iChannel; - - switch (config_list[i].iStreamConfig) { - case 0: //BIPOLAR 10V -/* - // ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000 - // 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed. - entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10; -*/ - break; - case 1: //UNIPOLAR 10V - entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_10; - break; - case 2: //BIPOLAR 2.5V - entry |= ME4600_AI_LIST_RANGE_BIPOLAR_2_5; - break; - case 3: //UNIPOLAR 2.5V - entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_2_5; - break; - default: - PERROR_CRITICAL("UNCHECK ERROR in config_list!\n"); - PERROR_CRITICAL - ("WRONG range\nPosition:%d Range:0x%04X\n", i, - config_list[i].iStreamConfig); - goto VERIFY_ERROR; - break; - } - - switch (config_list[i].iRef) { - case ME_REF_AI_GROUND: //SINGLE ENDED -/* - // ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000 - // 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' ==> Do nothing. Removed. - entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED; -*/ break; - case ME_REF_AI_DIFFERENTIAL: //DIFFERENTIAL - entry |= ME4600_AI_LIST_INPUT_DIFFERENTIAL; - break; - default: - PERROR_CRITICAL("UNCHECK ERROR in config_list!\n"); - PERROR_CRITICAL - ("WRONG reference\nPosition:%d Reference:0x%04X\n", - i, config_list[i].iRef); - goto VERIFY_ERROR; - break; - } - - //Add last entry flag - if (i == (count - 1)) { - entry |= ME4600_AI_LIST_LAST_ENTRY; - } - - outl(entry, instance->channel_list_reg); - PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->channel_list_reg - instance->reg_base, - entry); - } - - // Set triggering registers - --acq_ticks; - outl(acq_ticks, instance->chan_pre_timer_reg); - PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->chan_pre_timer_reg - instance->reg_base, - acq_ticks); - outl(acq_ticks, instance->scan_pre_timer_low_reg); - PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->scan_pre_timer_low_reg - instance->reg_base, - acq_ticks & 0xFFFFFFFF); - outl((acq_ticks >> 32), instance->scan_pre_timer_high_reg); - PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->scan_pre_timer_high_reg - instance->reg_base, - (acq_ticks >> 32) & 0xFFFFFFFF); - - // Set triggers - switch (trigger->iAcqStartTrigType) { - // Internal - case ME_TRIG_TYPE_SW: - // Nothing to set. - break; - - // External - case ME_TRIG_TYPE_EXT_ANALOG: - ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG; - case ME_TRIG_TYPE_EXT_DIGITAL: - ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG; - - // External trigger needs edge's definition - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_RISING: - // Nothing to set. - break; - - case ME_TRIG_EDGE_FALLING: - ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_FALLING; - break; - - case ME_TRIG_EDGE_ANY: - ctrl |= - ME4600_AI_CTRL_BIT_EX_TRIG_FALLING | - ME4600_AI_CTRL_BIT_EX_TRIG_BOTH; - break; - - default: - PERROR_CRITICAL - ("UNCHECK TRIGGER EDGE in triggers structure!\n"); - PERROR_CRITICAL - ("WRONG acquisition start trigger:0x%04X.\n", - trigger->iAcqStartTrigEdge); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - goto VERIFY_ERROR; - break; - } - break; - - default: - PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n"); - PERROR_CRITICAL("WRONG acquisition start trigger:0x%04X.\n", - trigger->iAcqStartTrigType); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE; - goto VERIFY_ERROR; - break; - } - - switch (trigger->iScanStartTrigType) { - case ME_TRIG_TYPE_TIMER: - --scan_ticks; - outl(scan_ticks, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, - scan_ticks & 0xFFFFFFFF); - outl((scan_ticks >> 32), instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, - (scan_ticks >> 32) & 0xFFFFFFFF); - - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) { - ctrl |= ME4600_AI_CTRL_BIT_MODE_0; - } else { - ctrl |= ME4600_AI_CTRL_BIT_MODE_1; - } - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - case ME_TRIG_TYPE_EXT_ANALOG: - outl(0, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, - 0); - outl(0, instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, - 0); - ctrl |= ME4600_AI_CTRL_BIT_MODE_2; - break; - - case ME_TRIG_TYPE_FOLLOW: - outl(0, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, - 0); - outl(0, instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, - 0); - - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) { - ctrl |= ME4600_AI_CTRL_BIT_MODE_0; - } else { - ctrl |= ME4600_AI_CTRL_BIT_MODE_1; - } - break; - - default: - PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n"); - PERROR_CRITICAL("WRONG scan start trigger:0x%04X.\n", - trigger->iScanStartTrigType); - err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - goto VERIFY_ERROR; - break; - } - - switch (trigger->iConvStartTrigType) { - - case ME_TRIG_TYPE_TIMER: - --conv_ticks; - outl(conv_ticks, instance->chan_timer_reg); - PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llX\n", - instance->reg_base, - instance->chan_timer_reg - instance->reg_base, - conv_ticks); - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - case ME_TRIG_TYPE_EXT_ANALOG: - outl(0, instance->chan_timer_reg); - PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->chan_timer_reg - instance->reg_base, 0); - ctrl |= ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1; - break; - - default: - PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n"); - PERROR_CRITICAL("WRONG conv start trigger:0x%04X.\n", - trigger->iConvStartTrigType); - err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - goto VERIFY_ERROR; - - break; - } - - //Sample & Hold feature - if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) { - if (instance->sh) { - ctrl |= ME4600_AI_CTRL_BIT_SAMPLE_HOLD; - } else { - PERROR_CRITICAL("UNCHECK S&H feature!\n"); - err = ME_ERRNO_INVALID_FLAGS; - goto VERIFY_ERROR; - } - } - //Enable IRQs sources but leave latches blocked. - ctrl |= (ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_LE_IRQ); //The last IRQ source (ME4600_AI_CTRL_BIT_LE_IRQ) is unused! - - //Everything is good. Finalize - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - - //Preserve EXT IRQ and OFFSET settings. Clean other bits. - tmp &= - (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET | - ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET); - - // write the control word - outl(ctrl | tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl | tmp); - spin_unlock(instance->ctrl_reg_lock); - - //Set the global parameters end exit. - instance->chan_list_len = count; - instance->fifo_irq_threshold = fifo_irq_threshold; - - if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { - data_required = - (unsigned long long)trigger->iAcqStopCount * - (unsigned long long)count; - if (data_required > UINT_MAX) - data_required = UINT_MAX; - instance->data_required = (unsigned int)data_required; - } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) - instance->data_required = - (unsigned long long)trigger->iScanStopCount; - else - instance->data_required = 0; - - // Mark subdevice as configured to work in stream mode. - instance->status = ai_status_stream_configured; - - // Deinit single config. Set all entries to NOT_CONFIGURED. - for (i = 0; i < instance->channels; i++) { - instance->single_config[i].status = - ME_SINGLE_CHANNEL_NOT_CONFIGURED; - } - -VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend! - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); -ERROR: // Error in settings. - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long t; - unsigned long j; - int volatile head; - - PDEBUG("executed. idx=0\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } else { // Max time. - t = LONG_MAX; - } - - instance = (me4600_ai_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - j = jiffies; - - while (1) { - // Only runing device can generate break. - head = instance->circ_buf.head; - wait_event_interruptible_timeout(instance->wait_queue, - ((head != - instance->circ_buf.head) - || - ((instance->status <= - ai_status_stream_run_wait) - && (instance->status >= - ai_status_stream_end_wait))), - t); - - if (head != instance->circ_buf.head) { // New data in buffer. - break; - } else if (instance->status == ai_status_stream_end) { // End of work. - break; - } else if (instance->status == ai_status_stream_fifo_error) { - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - break; - } else if (instance->status == ai_status_stream_buffer_error) { - err = ME_ERRNO_RING_BUFFER_OVERFLOW; - break; - } else if (instance->status == ai_status_stream_error) { - err = ME_ERRNO_INTERNAL; - break; - } else if ((jiffies - j) >= t) { - PERROR("Wait on values timed out.\n"); - err = ME_ERRNO_TIMEOUT; - break; - } else if (signal_pending(current)) { - PERROR("Wait on values interrupted from signal.\n"); - err = ME_ERRNO_SIGNAL; - break; - } - // Correct timeout. - t -= jiffies - j; - } - - *count = me_circ_buf_values(&instance->circ_buf); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t * - instance, int *values, - const int count, - const int flags) -{ - int n; - int i; - uint32_t value; - - ///Checking how many datas can be copied. - n = me_circ_buf_values(&instance->circ_buf); - if (n <= 0) - return 0; - - if (n > count) - n = count; - - if (flags & ME_IO_STREAM_READ_FRAMES) { - if (n < instance->chan_list_len) //Not enough data! - return 0; - n -= n % instance->chan_list_len; - } - - for (i = 0; i < n; i++) { - value = *(instance->circ_buf.buf + instance->circ_buf.tail); - if (put_user(value, values + i)) { - PERROR("Cannot copy new values to user.\n"); - return -ME_ERRNO_INTERNAL; - } - instance->circ_buf.tail++; - instance->circ_buf.tail &= instance->circ_buf.mask; - } - return n; -} - -static int me4600_ai_io_stream_read(me_subdevice_t *subdevice, - struct file *filep, - int read_mode, - int *values, int *count, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - int ret; - - int c = *count; - int min = c; - - PDEBUG("executed. idx=0\n"); - - if (flags & ~ME_IO_STREAM_READ_FRAMES) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (!values || !count) { - PERROR("Request has invalid pointer.\n"); - return ME_ERRNO_INVALID_POINTER; - } - - if (c < 0) { - PERROR("Request has invalid value's counter.\n"); - return ME_ERRNO_INVALID_VALUE_COUNT; - } - - if ((read_mode != ME_READ_MODE_BLOCKING) - && (read_mode != ME_READ_MODE_NONBLOCKING)) { - PERROR("Invalid read mode specified.\n"); - return ME_ERRNO_INVALID_READ_MODE; - } - - if (c == 0) { //You get what you want! Nothing more or less. - return ME_ERRNO_SUCCESS; - } - - instance = (me4600_ai_subdevice_t *) subdevice; - ME_SUBDEVICE_ENTER; - - //Check if subdevice is configured. - if (instance->chan_list_len <= 0) { - PERROR("Subdevice wasn't configured.\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_PREVIOUS_CONFIG; - } - - if (flags & ME_IO_STREAM_READ_FRAMES) { - if (c < instance->chan_list_len) { //Not enough data requested. - PERROR - ("When using FRAME_READ mode minimal size is defined by channel list.\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INVALID_VALUE_COUNT; - } - } - - if (c > (ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len)) { // To return acceptable amount of data when user pass too big value. - min = ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len; - } - - if (flags & ME_IO_STREAM_READ_FRAMES) { - //Wait for whole list. - if (read_mode == ME_READ_MODE_BLOCKING) { - min = c - (c % instance->chan_list_len); - } - - if (read_mode == ME_READ_MODE_NONBLOCKING) { - min = instance->chan_list_len; - } - } - - if ((inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { //Working - //If blocking mode -> wait for data. - if ((me_circ_buf_values(&instance->circ_buf) < min) - && (read_mode == ME_READ_MODE_BLOCKING)) { - wait_event_interruptible(instance->wait_queue, - ((me_circ_buf_values - (&instance->circ_buf) >= min) - || !(inl(instance->status_reg) - & - ME4600_AI_STATUS_BIT_FSM))); - - if (signal_pending(current)) { - PERROR - ("Wait on values interrupted from signal.\n"); - err = ME_ERRNO_SIGNAL; - } - } - } - - ret = me4600_ai_io_stream_read_get_value(instance, values, c, flags); - if (ret < 0) { - err = -ret; - *count = 0; - } else if (ret == 0) { - *count = 0; - if (instance->status == ai_status_stream_fifo_error) { - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - instance->status = ai_status_stream_end; - } else if (instance->status == ai_status_stream_buffer_error) { - err = ME_ERRNO_RING_BUFFER_OVERFLOW; - instance->status = ai_status_stream_end; - } else if (instance->status == ai_status_stream_end) { - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - } else if (instance->status == ai_status_stream_error) { - err = ME_ERRNO_INTERNAL; - } else if (instance->status == ai_status_none) { - PDEBUG("Stream canceled.\n"); - err = ME_ERRNO_INTERNAL; - } - } else { - *count = ret; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -/** @brief Stop aqusation. Preserve FIFOs. -* -* @param instance The subdevice instance (pointer). -*/ - -static int ai_stop_immediately(me4600_ai_subdevice_t *instance) -{ - unsigned long cpu_flags = 0; - volatile uint32_t ctrl; - const int timeout = HZ / 10; //100ms - int i; - - for (i = 0; i <= timeout; i++) { - spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AI_CTRL_BIT_STOP; - ctrl |= - (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET | - ME4600_AI_CTRL_BIT_SC_IRQ_RESET); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - - if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) { // Exit. - break; - } - - PINFO("Wait for stop: %d\n", i + 1); - //Still working! - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - if (i > timeout) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - return ME_ERRNO_INTERNAL; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags = 0; - unsigned long ref; - unsigned long delay = 0; - - volatile uint32_t tmp; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((start_mode != ME_START_MODE_BLOCKING) - && (start_mode != ME_START_MODE_NONBLOCKING)) { - PERROR("Invalid start mode specified.\n"); - return ME_ERRNO_INVALID_START_MODE; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags); - - tmp = inl(instance->ctrl_reg); - - if ((tmp & ME4600_AI_STATUS_BIT_FSM)) { - PERROR("Conversion is already running.\n"); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - if (instance->chan_list_len == 0) { //Not configured! - PERROR("Subdevice is not configured to work in stream mode!\n"); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - } - - if (!(tmp & (ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1 | ME4600_AI_CTRL_BIT_MODE_2))) { //Mode 0 = single work => no stream config - PERROR("Subdevice is configured to work in single mode.\n"); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - } - //Reset stop bits. - tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - //Start datas' FIFO. - tmp |= ME4600_AI_CTRL_BIT_DATA_FIFO; - //Free stop bits. - tmp &= ~(ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - - //Cancel control task - PDEBUG("Cancel control task.\n"); - instance->ai_control_task_flag = 0; - cancel_delayed_work(&instance->ai_control_task); - - //Set the starting values. - instance->ISM.global_read = 0; - instance->ISM.read = 0; - //Clear circular buffer - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - - //Set everything. - ai_data_acquisition_logic(instance); - - //Set status to 'wait for start' - instance->status = ai_status_stream_run_wait; - - // Set control task's timeout - instance->timeout.delay = delay; - instance->timeout.start_time = jiffies; - - //Lets go! Start work - inl(instance->start_reg); - PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base, - instance->start_reg - instance->reg_base); - - // Schedule control task - instance->ai_control_task_flag = 1; - queue_delayed_work(instance->me4600_workqueue, - &instance->ai_control_task, 1); - - PDEVELOP("Delay:%ld\n", delay); - - if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start. - ref = jiffies; - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ai_status_stream_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if ((instance->status != ai_status_stream_run) - && (instance->status != ai_status_stream_end)) { - PDEBUG("Starting stream canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->status = ai_status_none; - ai_stop_isr(instance); - err = ME_ERRNO_SIGNAL; - } else if ((delay) && ((jiffies - ref) > delay)) { - if (instance->status != ai_status_stream_run) { - if (instance->status == ai_status_stream_end) { - PDEBUG("Timeout reached.\n"); - } else if ((jiffies - ref) > delay + 1) { - PERROR - ("Timeout reached. Not handled by control task!\n"); - ai_stop_isr(instance); - instance->status = - ai_status_stream_error; - } else { - PERROR - ("Timeout reached. Signal come but status is strange: %d\n", - instance->status); - ai_stop_isr(instance); - instance->status = - ai_status_stream_error; - } - - instance->ai_control_task_flag = 0; - cancel_delayed_work(&instance->ai_control_task); - err = ME_ERRNO_TIMEOUT; - } - } - } -#ifdef MEDEBUG_INFO - tmp = inl(instance->ctrl_reg); - PDEBUG_REG("ctrl_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - PINFO("STATUS_BIT_FSM=%s.\n", - (tmp & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off"); - PINFO("CTRL_BIT_HF_IRQ=%s.\n", - (tmp & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable"); - PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n", - (tmp & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : "work"); - PINFO("CTRL_BIT_SC_IRQ=%s.\n", - (tmp & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable"); - PINFO("CTRL_BIT_SC_RELOAD=%s.\n", - (tmp & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off"); - PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n", - (tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work"); -#endif - -ERROR: - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - switch (instance->status) { - case ai_status_single_configured: - case ai_status_stream_configured: - case ai_status_stream_end: - case ai_status_stream_fifo_error: - case ai_status_stream_buffer_error: - case ai_status_stream_error: - *status = ME_STATUS_IDLE; - break; - - case ai_status_stream_run_wait: - case ai_status_stream_run: - case ai_status_stream_end_wait: - *status = ME_STATUS_BUSY; - break; - - case ai_status_none: - default: - *status = - (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) ? - ME_STATUS_BUSY : ME_STATUS_IDLE; - break; - } - - if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) { - // Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - ((instance->status != - ai_status_stream_run_wait) - && (instance->status != - ai_status_stream_run) - && (instance->status != - ai_status_stream_end_wait)), - LONG_MAX); - - if (instance->status != ai_status_stream_end) { - PDEBUG("Wait for IDLE canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait for IDLE interrupted.\n"); - instance->status = ai_status_none; - ai_stop_isr(instance); - err = ME_ERRNO_SIGNAL; - } - - *status = ME_STATUS_IDLE; - } - - *values = me_circ_buf_values(&instance->circ_buf); - PDEBUG("me_circ_buf_values(&instance->circ_buf)=%d.\n", *values); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags) -{ -/** - @note Stop is implemented only in blocking mode. - @note Function return when state machine is stoped. -*/ - me4600_ai_subdevice_t *instance; - unsigned long cpu_flags; - uint32_t ctrl; - int ret; - - PDEBUG("executed. idx=0\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((stop_mode != ME_STOP_MODE_IMMEDIATE) - && (stop_mode != ME_STOP_MODE_LAST_VALUE)) { - PERROR("Invalid stop mode specified.\n"); - return ME_ERRNO_INVALID_STOP_MODE; - } - - instance = (me4600_ai_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - // Mark as stopping. => Software stop. - instance->status = ai_status_stream_end_wait; - - if (stop_mode == ME_STOP_MODE_IMMEDIATE) { - ret = ai_stop_immediately(instance); - - if (ret) { - PERROR("FSM is still busy.\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_SUBDEVICE_BUSY; - } - instance->ai_control_task_flag = 0; - - } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) { - // Set stop bit in registry. - spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME4600_AI_CTRL_BIT_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - - // Only runing process will interrupt this call. Events are signaled when status change. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ai_status_stream_end_wait), - LONG_MAX); - - if (instance->status != ai_status_stream_end) { - PDEBUG("Stopping stream canceled.\n"); - ret = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Stopping stream interrupted.\n"); - instance->status = ai_status_none; - ret = ME_ERRNO_SIGNAL; - } - // End of work. - ai_stop_immediately(instance); - - } - - ret = ai_read_data_pooling(instance); - if (ret > 0) { // Everything fine. More datas put to software buffer. - instance->status = ai_status_stream_end; - ret = ME_ERRNO_SUCCESS; - // Signal that we put last data to software buffer. - wake_up_interruptible_all(&instance->wait_queue); - } else if (ret == 0) { // Everything fine. No more datas in FIFO. - instance->status = ai_status_stream_end; - ret = ME_ERRNO_SUCCESS; - } else if (ret == -ME_ERRNO_RING_BUFFER_OVERFLOW) { // Stop is unsuccessful, buffer is overflow. - instance->status = ai_status_stream_buffer_error; - ret = ME_ERRNO_SUCCESS; - } else { // Stop is unsuccessful - instance->status = ai_status_stream_end; - ret = -ret; - } - - ME_SUBDEVICE_EXIT; - - return ret; -} - -static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - me4600_ai_subdevice_t *instance; - int i; - int r = -1; - int diff = 21E6; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if ((*max - *min) < 0) { - PERROR("Invalid minimum and maximum values specified.\n"); - return ME_ERRNO_INVALID_MIN_MAX; - } - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - for (i = 0; i < instance->ranges_len; i++) { - if ((instance->ranges[i].min <= *min) - && ((instance->ranges[i].max + 1000) >= *max)) { - if ((instance->ranges[i].max - - instance->ranges[i].min) - (*max - *min) < - diff) { - r = i; - diff = - (instance->ranges[i].max - - instance->ranges[i].min) - (*max - - *min); - } - } - } - - if (r < 0) { - PERROR("No matching range found.\n"); - return ME_ERRNO_NO_RANGE; - } else { - *min = instance->ranges[r].min; - *max = instance->ranges[r].max; - *maxdata = ME4600_AI_MAX_DATA; - *range = r; - } - } else { - PERROR("Invalid physical unit specified.\n"); - return ME_ERRNO_INVALID_UNIT; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count) -{ - me4600_ai_subdevice_t *instance; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - *count = instance->ranges_len; - } else { - *count = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - me4600_ai_subdevice_t *instance; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - if ((range < instance->ranges_len) && (range >= 0)) { - *unit = ME_UNIT_VOLT; - *min = instance->ranges[range].min; - *max = instance->ranges[range].max; - *maxdata = ME4600_AI_MAX_DATA; - } else { - PERROR("Invalid range number specified.\n"); - return ME_ERRNO_INVALID_RANGE; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks) -{ - me4600_ai_subdevice_t *instance; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - - switch (timer) { - - case ME_TIMER_ACQ_START: - *base_frequency = ME4600_AI_BASE_FREQUENCY; - *min_ticks = ME4600_AI_MIN_ACQ_TICKS; - *max_ticks = ME4600_AI_MAX_ACQ_TICKS; - break; - - case ME_TIMER_SCAN_START: - *base_frequency = ME4600_AI_BASE_FREQUENCY; - *min_ticks = ME4600_AI_MIN_SCAN_TICKS; - *max_ticks = ME4600_AI_MAX_SCAN_TICKS; - break; - - case ME_TIMER_CONV_START: - *base_frequency = ME4600_AI_BASE_FREQUENCY; - *min_ticks = ME4600_AI_MIN_CHAN_TICKS; - *max_ticks = ME4600_AI_MAX_CHAN_TICKS; - break; - - default: - PERROR("Invalid timer specified.(0x%04x)\n", timer); - - return ME_ERRNO_INVALID_TIMER; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - me4600_ai_subdevice_t *instance; - - PDEBUG("executed. idx=0\n"); - - instance = (me4600_ai_subdevice_t *) subdevice; - *number = instance->channels; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed. idx=0\n"); - - *type = ME_TYPE_AI; - *subtype = ME_SUBTYPE_STREAMING; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed. idx=0\n"); - - *caps = - ME_CAPS_AI_TRIG_SYNCHRONOUS | ME_CAPS_AI_FIFO | - ME_CAPS_AI_FIFO_THRESHOLD; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count) -{ - me4600_ai_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - instance = (me4600_ai_subdevice_t *) subdevice; - - PDEBUG("executed. idx=0\n"); - - if (count != 1) { - PERROR("Invalid capability argument count.\n"); - return ME_ERRNO_INVALID_CAP_ARG_COUNT; - } - - switch (cap) { - case ME_CAP_AI_FIFO_SIZE: - args[0] = ME4600_AI_FIFO_COUNT; - break; - - case ME_CAP_AI_BUFFER_SIZE: - args[0] = - (instance->circ_buf.buf) ? ME4600_AI_CIRC_BUF_COUNT : 0; - break; - - default: - PERROR("Invalid capability.\n"); - err = ME_ERRNO_INVALID_CAP; - args[0] = 0; - } - - return err; -} - -void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status, - const uint32_t ctrl_status) -{ - int to_read; - - if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work. HF need reseting. - if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { - if (ai_read_data(instance, instance->ISM.next) != instance->ISM.next) { //ERROR! - PERROR - ("Limited amounts aqusition with TH=0: Circular buffer full!\n"); - instance->status = - ai_status_stream_buffer_error; - } else { - instance->status = ai_status_stream_end; - } - //End of work. - ai_stop_isr(instance); - } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { - instance->ISM.global_read += ME4600_AI_FIFO_HALF; - - if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR! - PERROR - ("Limited amounts aqusition with TH = 0: Circular buffer full!\n"); - //End of work. - ai_stop_isr(instance); - instance->status = - ai_status_stream_buffer_error; - } else { - //Continue. - ai_limited_ISM(instance, irq_status); - } - } - //Signal user. - wake_up_interruptible_all(&instance->wait_queue); - } else //if(instance->fifo_irq_threshold) - { - if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { - instance->ISM.read = 0; - if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF) - && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA))) - { - to_read = - ME4600_AI_FIFO_HALF - - (ME4600_AI_FIFO_HALF % - instance->fifo_irq_threshold); - PDEBUG - ("Limited amounts aqusition with TH != 0: Not fast enough data aqusition! correction=%d\n", - to_read); - } else { - to_read = instance->ISM.next; - } - instance->ISM.global_read += to_read; - - ai_reschedule_SC(instance); - - if (ai_read_data(instance, to_read) != to_read) { //ERROR! - PERROR - ("Limited amounts aqusition with TH != 0: Circular buffer full!\n"); - //End of work. - ai_stop_isr(instance); - instance->status = - ai_status_stream_buffer_error; - } else { - //Continue. - ai_limited_ISM(instance, irq_status); - } - - //Signal user. - wake_up_interruptible_all(&instance->wait_queue); - } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { - instance->ISM.read += ME4600_AI_FIFO_HALF; - instance->ISM.global_read += ME4600_AI_FIFO_HALF; - - if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR! - PERROR - ("Limited amounts aqusition with TH != 0: Circular buffer full!\n"); - ai_stop_isr(instance); - - instance->status = - ai_status_stream_buffer_error; - //Signal user. - wake_up_interruptible_all(&instance-> - wait_queue); - } else { - //Countinue. - ai_limited_ISM(instance, irq_status); - } - } - - if (instance->ISM.global_read >= instance->data_required) { //End of work. Next paranoid pice of code: '>=' instead od '==' only to be sure. - ai_stop_isr(instance); - if (instance->status < ai_status_stream_end) { - instance->status = ai_status_stream_end; - } -#ifdef MEDEBUG_ERROR - if (instance->ISM.global_read > instance->data_required) { //This is security check case. This should never ever happend! - PERROR - ("Limited amounts aqusition: Read more data than necessary! data_required=%d < read=%d\n", - instance->data_required, - instance->ISM.global_read); - //Signal error (warning??). - instance->status = ai_status_stream_error; - } -#endif - } - } -} - -void ai_infinite_isr(me4600_ai_subdevice_t *instance, - const uint32_t irq_status, const uint32_t ctrl_status) -{ - int to_read; - - if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { //next chunck of data -> read fifo - //Set new state in ISM. - if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF) && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA))) { //There is more data than we ecpected. Propably we aren't fast enough. Read as many as possible. - if (instance->fifo_irq_threshold) { - to_read = - ME4600_AI_FIFO_HALF - - (ME4600_AI_FIFO_HALF % - instance->fifo_irq_threshold); - if (to_read > instance->fifo_irq_threshold) { - PDEBUG - ("Infinite aqusition: Not fast enough data aqusition! TH != 0: correction=%d\n", - to_read); - } - } else { //No threshold specified. - to_read = ME4600_AI_FIFO_HALF; - } - } else { - to_read = instance->ISM.next; - } - - instance->ISM.read += to_read; - - //Get data - if (ai_read_data(instance, to_read) != to_read) { //ERROR! - PERROR("Infinite aqusition: Circular buffer full!\n"); - ai_stop_isr(instance); - instance->status = ai_status_stream_buffer_error; - } else { - ai_infinite_ISM(instance); - instance->ISM.global_read += instance->ISM.read; - instance->ISM.read = 0; - } - - //Signal data to user - wake_up_interruptible_all(&instance->wait_queue); - } else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { //fifo is half full -> read fifo Large blocks only! - instance->ISM.read += ME4600_AI_FIFO_HALF; - - if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) { //ERROR! - PERROR("Infinite aqusition: Circular buffer full!\n"); - ai_stop_isr(instance); - instance->status = ai_status_stream_buffer_error; - - //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - } else { - ai_infinite_ISM(instance); - } - } -} - -static irqreturn_t me4600_ai_isr(int irq, void *dev_id) -{ /// @note This is time critical function! - uint32_t irq_status; - uint32_t ctrl_status; - me4600_ai_subdevice_t *instance = dev_id; - //int to_read; - - PDEBUG("executed. idx=0\n"); - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inl(instance->irq_status_reg); - if (! - (irq_status & - (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))) { -#ifdef MEDEBUG_INFO - if ((irq_status & (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC | ME4600_IRQ_STATUS_BIT_LE)) == ME4600_IRQ_STATUS_BIT_LE) { //This is security check case. LE is unused. This should never ever happend. - PINFO - ("%ld Shared interrupt. %s(): irq_status_reg=LE_IRQ\n", - jiffies, __func__); - } else { - PINFO - ("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n", - jiffies, __func__, irq_status); - } -#endif - return IRQ_NONE; - } - - if (!instance->circ_buf.buf) { //Security check. - PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n"); - ai_stop_isr(instance); - return IRQ_HANDLED; - } - //Get the status register. - ctrl_status = inl(instance->status_reg); - -#ifdef MEDEBUG_INFO - if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) - PINFO("HF interrupt active\n"); - if (irq_status & ME4600_IRQ_STATUS_BIT_SC) - PINFO("SC interrupt active\n"); - if (irq_status & ME4600_IRQ_STATUS_BIT_LE) - PINFO("LE interrupt active\n"); -#endif - - //This is safety check! - if ((irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) - && (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)) { - PDEBUG("HF interrupt active but FIFO under half\n"); - //Reset HF interrupt latch. - spin_lock(instance->ctrl_reg_lock); - outl(ctrl_status | ME4600_AI_CTRL_BIT_HF_IRQ_RESET, - instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl_status); - outl(ctrl_status, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl_status); - spin_unlock(instance->ctrl_reg_lock); - return IRQ_HANDLED; - } -#ifdef MEDEBUG_INFO - PINFO("STATUS_BIT_FSM=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off"); - - PINFO("STATUS_BIT_EF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" : - "empty"); - PINFO("STATUS_BIT_HF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" : - " > HF"); - PINFO("STATUS_BIT_FF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" : - "full"); - - PINFO("STATUS_BIT_EF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" : - "empty"); - PINFO("STATUS_BIT_HF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF"); - PINFO("STATUS_BIT_FF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" : - "full"); - - PINFO("CTRL_BIT_HF_IRQ=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable"); - PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : - "work"); - PINFO("CTRL_BIT_SC_IRQ=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable"); - PINFO("CTRL_BIT_SC_RELOAD=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off"); - PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : - "work"); -#endif - - //Look for overflow error. - if (!(ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA)) { - //FIFO is full. Read datas and reset all settings. - PERROR("FIFO overflow.\n"); - ai_read_data(instance, ME4600_AI_FIFO_COUNT); - ai_stop_isr(instance); - - instance->status = ai_status_stream_fifo_error; - //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; - } - - if (!instance->data_required) { //This is infinite aqusition. -#ifdef MEDEBUG_ERROR - if ((irq_status & - (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC)) - == - (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC)) { - ///In infinite mode only one interrupt source should be reported! - PERROR - ("Error in ISM! Infinite aqusition: HF and SC interrupts active! threshold=%d next=%d ctrl=0x%04X irq_status_reg=0x%04X", - instance->fifo_irq_threshold, instance->ISM.next, - ctrl_status, irq_status); - } -#endif - - ai_infinite_isr(instance, irq_status, ctrl_status); - -#ifdef MEDEBUG_INFO - ctrl_status = inl(instance->ctrl_reg); -#endif - } else { - - ai_limited_isr(instance, irq_status, ctrl_status); - ctrl_status = inl(instance->status_reg); - if (!(ctrl_status & (ME4600_AI_STATUS_BIT_HF_DATA | ME4600_AI_CTRL_BIT_HF_IRQ_RESET))) { //HF active, but we have more than half already => HF will never come - PDEBUG - ("MISSED HF. data_required=%d ISM.read=%d ISM.global=%d ISM.next=%d\n", - instance->data_required, instance->ISM.read, - instance->ISM.global_read, instance->ISM.next); - ai_limited_isr(instance, ME4600_IRQ_STATUS_BIT_AI_HF, - ctrl_status); - } - } - -#ifdef MEDEBUG_INFO - PINFO("STATUS_BIT_FSM=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off"); - - PINFO("STATUS_BIT_EF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" : - "empty"); - PINFO("STATUS_BIT_HF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" : - " > HF"); - PINFO("STATUS_BIT_FF_CHANNEL=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" : - "full"); - - PINFO("STATUS_BIT_EF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" : - "empty"); - PINFO("STATUS_BIT_HF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF"); - PINFO("STATUS_BIT_FF_DATA=%s.\n", - (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" : - "full"); - - PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : - "work"); - PINFO("CTRL_BIT_SC_IRQ=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable"); - PINFO("CTRL_BIT_SC_RELOAD=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off"); - PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n", - (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : - "work"); - PINFO("%ld END\n", jiffies); -#endif - - return IRQ_HANDLED; -} - -/** @brief Stop aqusation of data. Reset interrupts' laches. Clear data's FIFO. -* -* @param instance The subdevice instance (pointer). -*/ -inline void ai_stop_isr(me4600_ai_subdevice_t *instance) -{ /// @note This is soft time critical function! - register uint32_t tmp; - - spin_lock(instance->ctrl_reg_lock); - //Stop all. Reset interrupt laches. Reset data FIFO. - tmp = inl(instance->ctrl_reg); - tmp |= - (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_HF_IRQ_RESET - | ME4600_AI_CTRL_BIT_LE_IRQ_RESET | - ME4600_AI_CTRL_BIT_SC_IRQ_RESET); - tmp &= ~ME4600_AI_CTRL_BIT_DATA_FIFO; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->ctrl_reg_lock); -} - -/** @brief Copy data from fifo to circular buffer. -* -* @param instance The subdevice instance (pointer). -* @param count The number of requested data. -* -* @return On success: Number of copied values. -* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW. -*/ -static inline int ai_read_data(me4600_ai_subdevice_t *instance, - const int count) -{ /// @note This is time critical function! - int c = count; - int empty_space; - int copied = 0; - int i, j; - - empty_space = me_circ_buf_space_to_end(&instance->circ_buf); - if (empty_space <= 0) { - PDEBUG("Circular buffer full.\n"); - return -ME_ERRNO_RING_BUFFER_OVERFLOW; - } - - if (empty_space < c) { //Copy first part. Max to end of buffer. - PDEBUG - ("Try to copy %d values from FIFO to circular buffer (pass 1).\n", - empty_space); - for (i = 0; i < empty_space; i++) { - *(instance->circ_buf.buf + instance->circ_buf.head) = - (inw(instance->data_reg) ^ 0x8000); - instance->circ_buf.head++; - } - instance->circ_buf.head &= instance->circ_buf.mask; - c -= empty_space; - copied = empty_space; - - empty_space = me_circ_buf_space_to_end(&instance->circ_buf); - } - - if (empty_space > 0) { - j = (empty_space < c) ? empty_space : c; - PDEBUG - ("Try to copy %d values from FIFO to circular buffer (pass 2).\n", - c); - for (i = 0; i < j; i++) { - *(instance->circ_buf.buf + instance->circ_buf.head) = - (inw(instance->data_reg) ^ 0x8000); - instance->circ_buf.head++; - } - instance->circ_buf.head &= instance->circ_buf.mask; - copied += j; - } - return copied; -} - -inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance) -{ /// @note This is time critical function! - register volatile uint32_t ctrl_set, ctrl_reset, tmp; - - if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { // Only sample counter with reloadnig is working. Reset it. - PINFO - ("Only sample counter with reloadnig is working. Reset it.\n"); - ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - ctrl_reset = ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - } else if (instance->fifo_irq_threshold == instance->ISM.read) { //This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning. - PINFO - ("This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning.\n"); - ctrl_set = - ME4600_AI_CTRL_BIT_SC_IRQ_RESET | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - ctrl_reset = - ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET); - } else if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) { //This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF. - PINFO - ("This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.\n"); - ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - } else { //This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF! - PINFO - ("This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!\n"); - ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - ctrl_reset = 0xFFFFFFFF; - } - - //Reset interrupt latch. - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - PINFO("ctrl=0x%x ctrl_set=0x%x ctrl_reset=0x%x\n", tmp, ctrl_set, - ctrl_reset); - tmp |= ctrl_set; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - if (ctrl_reset != 0xFFFFFFFF) { - outl(tmp & ctrl_reset, instance->ctrl_reg); - PDEBUG_REG("ctrl_reset outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp & ctrl_reset); - } - spin_unlock(instance->ctrl_reg_lock); - -} - -inline void ai_limited_ISM(me4600_ai_subdevice_t *instance, - uint32_t irq_status) -{ /// @note This is time critical function! - register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp; - - if (!instance->fifo_irq_threshold) { //No threshold provided. SC ends work. - PINFO("No threshold provided. SC ends work.\n"); - ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - if (instance->data_required > (ME4600_AI_FIFO_COUNT - 1 + instance->ISM.global_read)) { //HF need reseting. - ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - } - } else //if(instance->fifo_irq_threshold) - { - if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) { - PINFO("Threshold provided. Clear HF latch.\n"); - ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - - if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) { //This is not the last one. HF need reseting. - PINFO - ("The next interrupt is HF. HF need be activating.\n"); - ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - } - } - - if (irq_status & ME4600_IRQ_STATUS_BIT_SC) { - PINFO("Threshold provided. Restart SC.\n"); - ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - ctrl_reset &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - - if (instance->fifo_irq_threshold >= ME4600_AI_FIFO_MAX_SC) { //This is not the last one. HF need to be activating. - PINFO - ("The next interrupt is HF. HF need to be activating.\n"); - ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - } - } - } - - //Reset interrupt latch. - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp |= ctrl_set; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - if (ctrl_reset != 0xFFFFFFFF) { - outl(tmp & ctrl_reset, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp & ctrl_reset); - } - spin_unlock(instance->ctrl_reg_lock); - -} - -/** @brief Last chunck of datas. We must reschedule sample counter. -* @note Last chunck. -* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts. -* @warning When threshold is wrongly set some IRQ are lost.(!!!) -*/ -inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance) -{ - register uint32_t rest; - - if (instance->data_required <= instance->ISM.global_read) - return; - - rest = instance->data_required - instance->ISM.global_read; - if (rest < instance->fifo_irq_threshold) { //End of work soon .... - PDEBUG("Rescheduling SC from %d to %d.\n", - instance->fifo_irq_threshold, rest); - /// @note Write new value to SC <== DANGER! This is not safe solution! We can miss some inputs. - outl(rest, instance->sample_counter_reg); - PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - rest); - instance->fifo_irq_threshold = rest; - - if (rest < ME4600_AI_FIFO_MAX_SC) { - instance->ISM.next = rest; - } else { - instance->ISM.next = rest % ME4600_AI_FIFO_HALF; - if (instance->ISM.next + ME4600_AI_FIFO_HALF < - ME4600_AI_FIFO_MAX_SC) { - instance->ISM.next += ME4600_AI_FIFO_HALF; - } - } - } -} - -/** Start the ISM. All must be reseted before enter to this function. */ -inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance) -{ - register uint32_t tmp; - - if (!instance->data_required) { //This is infinite aqusition. - if (!instance->fifo_irq_threshold) { //No threshold provided. Set SC to 0.5*FIFO. Clear the SC's latch. - //Set the sample counter - outl(ME4600_AI_FIFO_HALF, instance->sample_counter_reg); - PDEBUG_REG - ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - ME4600_AI_FIFO_HALF); - } else { //Threshold provided. Set SC to treshold. Clear the SC's latch. - //Set the sample counter - outl(instance->fifo_irq_threshold, - instance->sample_counter_reg); - PDEBUG_REG - ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - instance->fifo_irq_threshold); - } - - if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //Enable only sample counter's interrupt. Set reload bit. Clear the SC's latch. - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD; - tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp); - spin_unlock(instance->ctrl_reg_lock); - if (!instance->fifo_irq_threshold) { //No threshold provided. Set ISM.next to 0.5*FIFO. - instance->ISM.next = ME4600_AI_FIFO_HALF; - } else { //Threshold provided. Set ISM.next to treshold. - instance->ISM.next = - instance->fifo_irq_threshold; - } - } else { //Enable sample counter's and HF's interrupts. - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD; - tmp &= - ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp); - spin_unlock(instance->ctrl_reg_lock); - - instance->ISM.next = - instance->fifo_irq_threshold % ME4600_AI_FIFO_HALF; - if (instance->ISM.next + ME4600_AI_FIFO_HALF < - ME4600_AI_FIFO_MAX_SC) { - instance->ISM.next += ME4600_AI_FIFO_HALF; - } - } - } else { //This aqusition is limited to set number of data. - if (instance->fifo_irq_threshold >= instance->data_required) { //Stupid situation. - instance->fifo_irq_threshold = 0; - PDEBUG - ("Stupid situation: data_required(%d) < threshold(%d).\n", - instance->fifo_irq_threshold, - instance->data_required); - } - - if (!instance->fifo_irq_threshold) { //No threshold provided. Easy case: HF=read and SC=end. - //Set the sample counter to data_required. - outl(instance->data_required, - instance->sample_counter_reg); - PDEBUG_REG - ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - instance->data_required); - - //Reset the latches of sample counter and HF (if SC>FIFO). - //No SC reload! - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp &= - ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET | - ME4600_AI_CTRL_BIT_SC_RELOAD); - if (instance->data_required > - (ME4600_AI_FIFO_COUNT - 1)) { - tmp &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET; - instance->ISM.next = - instance->data_required % - ME4600_AI_FIFO_HALF; - instance->ISM.next += ME4600_AI_FIFO_HALF; - - } else { - instance->ISM.next = instance->data_required; - } - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp); - spin_unlock(instance->ctrl_reg_lock); - - } else { //The most general case. We have concret numbe of required data and threshold. SC=TH - //Set the sample counter to threshold. - outl(instance->fifo_irq_threshold, - instance->sample_counter_reg); - PDEBUG_REG - ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->sample_counter_reg - instance->reg_base, - instance->fifo_irq_threshold); - - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - //In this moment we are sure that SC will come more than once. - tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD; - - if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) { //The threshold is so small that we do need HF. - tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET; - instance->ISM.next = - instance->fifo_irq_threshold; - } else { //The threshold is large. The HF must be use. - tmp &= - ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET); - instance->ISM.next = - instance->fifo_irq_threshold % - ME4600_AI_FIFO_HALF; - if (instance->ISM.next + ME4600_AI_FIFO_HALF < - ME4600_AI_FIFO_MAX_SC) { - instance->ISM.next += - ME4600_AI_FIFO_HALF; - } - } - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - tmp); - spin_unlock(instance->ctrl_reg_lock); - } - } -} - -static int ai_mux_toggler(me4600_ai_subdevice_t *instance) -{ - uint32_t tmp; - - PDEBUG("executed. idx=0\n"); - - outl(0, instance->scan_pre_timer_low_reg); - PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_pre_timer_high_reg); - PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_pre_timer_high_reg - instance->reg_base, 0); - outl(0, instance->scan_timer_low_reg); - PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_low_reg - instance->reg_base, 0); - outl(0, instance->scan_timer_high_reg); - PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->scan_timer_high_reg - instance->reg_base, 0); - outl(65, instance->chan_timer_reg); - PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->chan_timer_reg - instance->reg_base, 65); - outl(65, instance->chan_pre_timer_reg); - PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->chan_pre_timer_reg - instance->reg_base, 65); - - // Turn on internal reference. - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AI_CTRL_BIT_FULLSCALE; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - // Clear data and channel fifo. - tmp &= - ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - // Write channel entry. - outl(ME4600_AI_LIST_INPUT_DIFFERENTIAL | - ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31, - instance->channel_list_reg); - PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->channel_list_reg - instance->reg_base, - ME4600_AI_LIST_INPUT_DIFFERENTIAL | - ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31); - - // Start conversion. - inl(instance->start_reg); - PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base, - instance->start_reg - instance->reg_base); - udelay(10); - - // Clear data and channel fifo. - tmp &= - ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO; - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - // Write channel entry. - // ME4600_AI_LIST_INPUT_SINGLE_ENDED | ME4600_AI_LIST_RANGE_BIPOLAR_10 <= 0x0000 - outl(ME4600_AI_LIST_INPUT_SINGLE_ENDED | - ME4600_AI_LIST_RANGE_BIPOLAR_10, instance->channel_list_reg); - PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->channel_list_reg - instance->reg_base, - ME4600_AI_LIST_INPUT_SINGLE_ENDED | - ME4600_AI_LIST_RANGE_BIPOLAR_10); - - // Start conversion. - inl(instance->start_reg); - PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base, - instance->start_reg - instance->reg_base); - udelay(10); - - // Clear control register. - tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - - return ME_ERRNO_SUCCESS; -} - -/** @brief Copy rest of data from fifo to circular buffer. -* @note Helper for STOP command. After FSM is stopped. -* @note This is slow function that copy all remainig data from FIFO to buffer. -* -* @param instance The subdevice instance (pointer). -* -* @return On success: Number of copied values. -* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW. -*/ -static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance) -{ /// @note This is time critical function! - int empty_space; - int copied = 0; - int status = ME_ERRNO_SUCCESS; - - PDEBUG("Space left in circular buffer = %d.\n", - me_circ_buf_space(&instance->circ_buf)); - - while ((empty_space = me_circ_buf_space(&instance->circ_buf))) { - if (!(status = inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) { //No more data. status = ME_ERRNO_SUCCESS = 0 - break; - } - *(instance->circ_buf.buf + instance->circ_buf.head) = - (inw(instance->data_reg) ^ 0x8000); - instance->circ_buf.head++; - instance->circ_buf.head &= instance->circ_buf.mask; - } - -#ifdef MEDEBUG_ERROR - if (!status) - PDEBUG - ("Copied all remaining datas (%d) from FIFO to circular buffer.\n", - copied); - else { - PDEBUG("No more empty space in buffer.\n"); - PDEBUG("Copied %d datas from FIFO to circular buffer.\n", - copied); - PDEBUG("FIFO still not empty.\n"); - } -#endif - return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW; -} - -static void me4600_ai_work_control_task(struct work_struct *work) -{ - me4600_ai_subdevice_t *instance; - uint32_t status; - uint32_t ctrl; - unsigned long cpu_flags = 0; - int reschedule = 0; - int signaling = 0; - - instance = - container_of((void *)work, me4600_ai_subdevice_t, ai_control_task); - PINFO("<%s: %ld> executed.\n", __func__, jiffies); - - status = inl(instance->status_reg); - PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->status_reg - instance->reg_base, status); - - switch (instance->status) { // Checking actual mode. - // Not configured for work. - case ai_status_none: - break; - - //This are stable modes. No need to do anything. (?) - case ai_status_single_configured: - case ai_status_stream_configured: - case ai_status_stream_fifo_error: - case ai_status_stream_buffer_error: - case ai_status_stream_error: - PERROR("Shouldn't be running!.\n"); - break; - - // Stream modes - case ai_status_stream_run_wait: - if (status & ME4600_AI_STATUS_BIT_FSM) { // ISM started.. - instance->status = ai_status_stream_run; - // Signal the end of wait for start. - signaling = 1; - // Wait now for stop. - reschedule = 1; - break; - - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - // Stop all actions. No conditions! Block interrupts. Reset FIFO => Too late! - ai_stop_isr(instance); - - instance->status = ai_status_stream_end; - - // Signal the end. - signaling = 1; - } - } - break; - - case ai_status_stream_run: - // Wait for stop ISM. - reschedule = 1; - break; - - case ai_status_stream_end_wait: - if (!(status & ME4600_AI_STATUS_BIT_FSM)) { // ISM stoped. Overwrite ISR. - instance->status = ai_status_stream_end; - // Signal the end of wait for stop. - signaling = 1; - } else { - // Wait for stop ISM. - reschedule = 1; - } - break; - - case ai_status_stream_end: - //End work. - if (status & ME4600_AI_STATUS_BIT_FSM) { // Still working? Stop it! - PERROR - ("Status is 'ai_status_stream_end' but hardware is still working!\n"); - spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AI_CTRL_BIT_HF_IRQ_RESET | - ME4600_AI_CTRL_BIT_SC_IRQ_RESET); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(instance->ctrl_reg_lock, - cpu_flags); - } - break; - - default: - PERROR_CRITICAL("Status is in wrong state (%d)!\n", - instance->status); - instance->status = ai_status_stream_error; - // Signal the end. - signaling = 1; - break; - - } - - if (signaling) { //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - } - - if (instance->ai_control_task_flag && reschedule) { // Reschedule task - queue_delayed_work(instance->me4600_workqueue, - &instance->ai_control_task, 1); - } else { - PINFO("<%s> Ending control task.\n", __func__); - } - -} diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h deleted file mode 100644 index 7055e44f32e..00000000000 --- a/drivers/staging/meilhaus/me4600_ai.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @file me4600_ai.h - * - * @brief Meilhaus ME-4000 analog input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_AI_H_ -#define _ME4600_AI_H_ - -#include "mesubdevice.h" -#include "meioctl.h" -#include "mecirc_buf.h" - -#ifdef __KERNEL__ - -#define ME4600_AI_MAX_DATA 0xFFFF - -#ifdef ME_SYNAPSE -# define ME4600_AI_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse -#else -# define ME4600_AI_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB -#endif -#define ME4600_AI_CIRC_BUF_SIZE PAGE_SIZE< - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "meids.h" -#include "me4600_reg.h" -#include "me4600_ao_reg.h" -#include "me4600_ao.h" - -/* Defines - */ - -static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range); - -static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count); - -static int me4600_ao_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata); - -static int me4600_ao_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks); - -static int me4600_ao_query_number_channels(me_subdevice_t *subdevice, - int *number); - -static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype); - -static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps); - -static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count); - -#ifndef BOSCH -/// @note NORMAL BUILD -/// @author Krzysztof Gantzke (k.gantzke@meilhaus.de) -/* Includes - */ - -# include - -/* Defines - */ - -/** Remove subdevice. -*/ -static void me4600_ao_destructor(struct me_subdevice *subdevice); - -/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. -*/ -static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags); - -/** Set output as single -*/ -static int me4600_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags); - -/** Pass to user actual value of output. -*/ -static int me4600_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags); - -/** Write to output requed value. -*/ -static int me4600_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags); - -/** Set output as streamed device. -*/ -static int me4600_ao_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags); - -/** Wait for / Check empty space in buffer. -*/ -static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags); - -/** Start streaming. -*/ -static int me4600_ao_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags); - -/** Check actual state. / Wait for end. -*/ -static int me4600_ao_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags); - -/** Stop streaming. -*/ -static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags); - -/** Write datas to buffor. -*/ -static int me4600_ao_io_stream_write(me_subdevice_t *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags); - -/** Interrupt handler. Copy from buffer to FIFO. -*/ -static irqreturn_t me4600_ao_isr(int irq, void *dev_id); -/** Copy data from circular buffer to fifo (fast) in wraparound mode. -*/ -inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from circular buffer to fifo (fast). -*/ -inline int ao_write_data(me4600_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from circular buffer to fifo (slow). -*/ -inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from user space to circular buffer. -*/ -inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count, - int *user_values); - -/** Stop presentation. Preserve FIFOs. -*/ -inline int ao_stop_immediately(me4600_ao_subdevice_t *instance); - -/** Task for asynchronical state verifying. -*/ -static void me4600_ao_work_control_task(struct work_struct *work); -/* Functions - */ - -static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t tmp; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - instance->status = ao_status_none; - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->timeout.delay = 0; - instance->timeout.start_time = jiffies; - - //Stop state machine. - err = ao_stop_immediately(instance); - - //Remove from synchronous start. - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= - ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - outl(tmp, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, tmp); - *instance->preload_flags &= - ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - spin_unlock(instance->preload_reg_lock); - - //Set single mode, dissable FIFO, dissable external trigger, set output to analog, block interrupt. - outl(ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_RESET_IRQ, - instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ); - - //Set output to 0V - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - instance->preloaded_count = 0; - instance->data_count = 0; - instance->single_value = 0x8000; - instance->single_value_in_fifo = 0x8000; - - //Set status to signal that device is unconfigured. - instance->status = ao_status_none; - - //Signal reset if user is on wait. - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t ctrl; - uint32_t sync; - unsigned long cpu_flags; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - // Checking parameters - if (flags) { - PERROR - ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - switch (trig_type) { - case ME_TRIG_TYPE_SW: - if (trig_edge != ME_TRIG_EDGE_NONE) { - PERROR - ("Invalid trigger edge. Software trigger has not edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - switch (trig_edge) { - case ME_TRIG_EDGE_ANY: - case ME_TRIG_EDGE_RISING: - case ME_TRIG_EDGE_FALLING: - break; - - default: - PERROR("Invalid trigger edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - break; - - default: - PERROR - ("Invalid trigger type. Trigger must be software or digital.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - - if ((trig_chan != ME_TRIG_CHAN_DEFAULT) - && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) { - PERROR("Invalid trigger channel specified.\n"); - return ME_ERRNO_INVALID_TRIG_CHAN; - } - - if (ref != ME_REF_AO_GROUND) { - PERROR - ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n"); - return ME_ERRNO_INVALID_REF; - } - - if (single_config != 0) { - PERROR - ("Invalid single config specified. Only one range for anlog outputs is available.\n"); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - - if (channel != 0) { - PERROR - ("Invalid channel number specified. Analog output have only one channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - //Subdevice running in stream mode! - if ((instance->status >= ao_status_stream_run_wait) - && (instance->status < ao_status_stream_end)) { - PERROR("Subdevice is busy.\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } -/// @note For single all calls (config and write) are erasing previous state! - - instance->status = ao_status_none; - - // Correct single mirrors - instance->single_value_in_fifo = instance->single_value; - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - // Set control register. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Set stop bit. Stop streaming mode. - ctrl = inl(instance->ctrl_reg); - //Reset all bits. - ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP; - - if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) { - PINFO("External digital trigger.\n"); - - if (trig_edge == ME_TRIG_EDGE_ANY) { -// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - instance->ctrl_trg = - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - } else if (trig_edge == ME_TRIG_EDGE_FALLING) { -// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - } else if (trig_edge == ME_TRIG_EDGE_RISING) { - instance->ctrl_trg = 0x0; - } - } else if (trig_type == ME_TRIG_TYPE_SW) { - PDEBUG("Software trigger\n"); - instance->ctrl_trg = 0x0; - } - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - // Set preload/synchronization register. - spin_lock(instance->preload_reg_lock); - if (trig_type == ME_TRIG_TYPE_SW) { - *instance->preload_flags &= - ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx); - } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) - { - *instance->preload_flags |= - ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx; - } - - if (trig_chan == ME_TRIG_CHAN_DEFAULT) { - *instance->preload_flags &= - ~(ME4600_AO_SYNC_HOLD << instance->ao_idx); - } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) - { - *instance->preload_flags |= - ME4600_AO_SYNC_HOLD << instance->ao_idx; - } - - //Reset hardware register - sync = inl(instance->preload_reg); - PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync); - sync &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx); - sync |= ME4600_AO_SYNC_HOLD << instance->ao_idx; - - //Output configured in default (safe) mode. - outl(sync, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync); - spin_unlock(instance->preload_reg_lock); - - instance->status = ao_status_single_configured; - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - unsigned long j; - unsigned long delay = 0; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & ~ME_IO_SINGLE_NONBLOCKING) { - PERROR("Invalid flag specified. %d\n", flags); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if ((instance->status >= ao_status_stream_configured) - && (instance->status <= ao_status_stream_end)) { - PERROR("Subdevice not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - ME_SUBDEVICE_ENTER; - if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger. - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - j = jiffies; - - //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_single_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if (instance->status == ao_status_none) { - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - - PDEBUG("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - } - - *value = - (!err) ? instance->single_value_in_fifo : instance-> - single_value; - } else { //Non-blocking mode - //Read value - *value = instance->single_value; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags; - unsigned long j; - unsigned long delay = 0x0; - - //Registry handling variables. - uint32_t sync_mask; - uint32_t mode; - uint32_t tmp; - uint32_t ctrl; - uint32_t status; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & - ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS | - ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (value & ~ME4600_AO_MAX_DATA) { - PERROR("Invalid value provided.\n"); - return ME_ERRNO_VALUE_OUT_OF_RANGE; - } - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if ((instance->status == ao_status_none) - || (instance->status > ao_status_single_end)) { - PERROR("Subdevice not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - ME_SUBDEVICE_ENTER; - -/// @note For single all calls (config and write) are erasing previous state! - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - // Correct single mirrors - instance->single_value_in_fifo = instance->single_value; - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - instance->single_value_in_fifo = value; - - ctrl = inl(instance->ctrl_reg); - - if (!instance->fifo) { //No FIFO - //Set the single mode. - ctrl &= ~ME4600_AO_CTRL_MODE_MASK; - - //Write value - PDEBUG("Write value\n"); - outl(value, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, value); - } else { // mix-mode - //Set speed - outl(ME4600_AO_MIN_CHAN_TICKS - 1, instance->timer_reg); - PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->timer_reg - instance->reg_base, - (int)ME4600_AO_MIN_CHAN_TICKS); - instance->hardware_stop_delay = HZ / 10; //100ms - - status = inl(instance->status_reg); - - //Set the continous mode. - ctrl &= ~ME4600_AO_CTRL_MODE_MASK; - ctrl |= ME4600_AO_MODE_CONTINUOUS; - - //Prepare FIFO - if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. - PINFO("Enableing FIFO.\n"); - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= - ME4600_AO_CTRL_BIT_ENABLE_FIFO | - ME4600_AO_CTRL_BIT_RESET_IRQ; - } else { //Check if FIFO is empty - if (status & ME4600_AO_STATUS_BIT_EF) { //FIFO not empty - PINFO("Reseting FIFO.\n"); - ctrl &= - ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO | - ME4600_AO_CTRL_BIT_ENABLE_IRQ); - ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - - instance->reg_base, ctrl); - - ctrl |= - ME4600_AO_CTRL_BIT_ENABLE_FIFO | - ME4600_AO_CTRL_BIT_RESET_IRQ; - } else { //FIFO empty, only interrupt needs to be disabled! - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ; - } - } - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Write output - 1 value to FIFO - if (instance->ao_idx & 0x1) { - outl(value <<= 16, instance->fifo_reg); - PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->fifo_reg - instance->reg_base, - value <<= 16); - } else { - outl(value, instance->fifo_reg); - PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->fifo_reg - instance->reg_base, - value); - } - } - - mode = *instance->preload_flags >> instance->ao_idx; - mode &= (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG); - - PINFO("Triggering mode: 0x%x\n", mode); - - spin_lock(instance->preload_reg_lock); - sync_mask = inl(instance->preload_reg); - PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync_mask); - switch (mode) { - case 0: //Individual software - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output. - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) { //Now we can set correct mode. This is exception. It is set to synchronous and triggered later. - sync_mask &= - ~(ME4600_AO_SYNC_EXT_TRIG << instance-> - ao_idx); - sync_mask |= - ME4600_AO_SYNC_HOLD << instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } else { // FIFO - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode. - sync_mask &= - ~((ME4600_AO_SYNC_EXT_TRIG | - ME4600_AO_SYNC_HOLD) << instance-> - ao_idx); - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } - instance->single_value = value; - break; - - case ME4600_AO_SYNC_EXT_TRIG: //Individual hardware - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if (!instance->fifo) { // No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output. - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) { //Now we can set correct mode - sync_mask &= - ~(ME4600_AO_SYNC_EXT_TRIG << instance-> - ao_idx); - sync_mask |= - ME4600_AO_SYNC_HOLD << instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } else { // FIFO - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode. - sync_mask &= - ~((ME4600_AO_SYNC_EXT_TRIG | - ME4600_AO_SYNC_HOLD) << instance-> - ao_idx); - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } - break; - - case ME4600_AO_SYNC_HOLD: //Synchronous software - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - -// if((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) { //Now we can set correct mode - sync_mask |= - ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx; -// sync_mask &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx); - sync_mask |= ME4600_AO_SYNC_HOLD << instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - break; - - case (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG): //Synchronous hardware - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) { //Now we can set correct mode - sync_mask |= - (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << - instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - break; - } -// spin_unlock(instance->preload_reg_lock); // Moved down. - - //Activate ISM (remove 'stop' bits) - ctrl &= - ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH); - ctrl |= instance->ctrl_trg; - ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - -/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS! - - if (!instance->fifo) { //No FIFO - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs. - tmp = ~(*instance->preload_flags | 0xFFFF0000); - PINFO - ("Fired all software synchronous outputs. mask:0x%08x\n", - tmp); - tmp |= sync_mask & 0xFFFF0000; - // Add this channel to list - tmp &= ~(ME4600_AO_SYNC_HOLD << instance->ao_idx); - - //Fire - PINFO("Software trigger.\n"); - outl(tmp, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - tmp); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } else if (!mode) { // Add this channel to list - outl(sync_mask & - ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask & ~(ME4600_AO_SYNC_HOLD << - instance->ao_idx)); - - //Fire - PINFO("Software trigger.\n"); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - - } else { // mix-mode - begin - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs - //Add channel to start list - outl(sync_mask | - (ME4600_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask | (ME4600_AO_SYNC_HOLD << - instance->ao_idx)); - - //Fire - PINFO - ("Fired all software synchronous outputs by software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - 0x8000); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } else if (!mode) { //Trigger outputs -/* //Remove channel from start list //<== Unnecessary. Removed. - outl(sync_mask & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, tmp); -*/ - //Fire - PINFO("Software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - 0x8000); - -/* //Restore save settings //<== Unnecessary. Removed. - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask); -*/ - } - } - spin_unlock(instance->preload_reg_lock); - - j = jiffies; - instance->status = ao_status_single_run_wait; - - instance->timeout.delay = delay; - instance->timeout.start_time = j; - instance->ao_control_task_flag = 1; - queue_delayed_work(instance->me4600_workqueue, - &instance->ao_control_task, 1); - - if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_single_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if (((!delay) || ((jiffies - j) <= delay)) - && (instance->status != ao_status_single_end)) { - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - ao_stop_immediately(instance); - instance->status = ao_status_none; - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - if (instance->status == ao_status_single_end) { - PDEBUG("Timeout reached.\n"); - } else { - if ((jiffies - j) > delay) { - PERROR - ("Timeout reached. Not handled by control task!\n"); - } else { - PERROR - ("Timeout reached. Signal come but status is strange: %d\n", - instance->status); - } - - ao_stop_immediately(instance); - } - - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->status = ao_status_single_end; - err = ME_ERRNO_TIMEOUT; - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t ctrl; - unsigned long cpu_flags; - uint64_t conv_ticks; - unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow; - unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - conv_ticks = - (uint64_t) conv_start_ticks_low + - ((uint64_t) conv_start_ticks_high << 32); - - if (flags & - ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY | ME_IO_STREAM_CONFIG_WRAPAROUND - | ME_IO_STREAM_CONFIG_BIT_PATTERN)) { - PERROR("Invalid flags.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { - if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) { - PERROR - ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE) - || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) { - PERROR - ("Hardware wraparound mode must be in infinite mode.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - } - - if (count != 1) { - PERROR("Only 1 entry in config list acceptable.\n"); - return ME_ERRNO_INVALID_CONFIG_LIST_COUNT; - } - - if (config_list[0].iChannel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (config_list[0].iStreamConfig != 0) { - PERROR("Only one range available.\n"); - return ME_ERRNO_INVALID_STREAM_CONFIG; - } - - if (config_list[0].iRef != ME_REF_AO_GROUND) { - PERROR("Output is referenced to ground.\n"); - return ME_ERRNO_INVALID_REF; - } - - if ((trigger->iAcqStartTicksLow != 0) - || (trigger->iAcqStartTicksHigh != 0)) { - PERROR - ("Invalid acquisition start trigger argument specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_ARG; - } - - if (config_list[0].iFlags) { - PERROR("Invalid config list flag.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - switch (trigger->iAcqStartTrigType) { - case ME_TRIG_TYPE_SW: - if (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE) { - PERROR - ("Invalid acquisition start trigger edge specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - } - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_ANY: - case ME_TRIG_EDGE_RISING: - case ME_TRIG_EDGE_FALLING: - break; - - default: - PERROR - ("Invalid acquisition start trigger edge specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - } - break; - - default: - PERROR("Invalid acquisition start trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE; - } - - if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) { - PERROR("Invalid scan start trigger type specified.\n"); - return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - } - - if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) { - PERROR("Invalid conv start trigger type specified.\n"); - return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - } - - if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS) - || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) { - PERROR("Invalid conv start trigger argument specified.\n"); - return ME_ERRNO_INVALID_CONV_START_ARG; - } - - if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) { - PERROR("Invalid acq start trigger argument specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_ARG; - } - - if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) { - PERROR("Invalid scan start trigger argument specified.\n"); - return ME_ERRNO_INVALID_SCAN_START_ARG; - } - - switch (trigger->iScanStopTrigType) { - case ME_TRIG_TYPE_NONE: - if (trigger->iScanStopCount != 0) { - PERROR("Invalid scan stop count specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_ARG; - } - break; - - case ME_TRIG_TYPE_COUNT: - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iScanStopCount <= 0) { - PERROR("Invalid scan stop count specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_ARG; - } - } else { - PERROR("The continous mode has not 'scan' contects.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - break; - - default: - PERROR("Invalid scan stop trigger type specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE; - } - - switch (trigger->iAcqStopTrigType) { - case ME_TRIG_TYPE_NONE: - if (trigger->iAcqStopCount != 0) { - PERROR("Invalid acq stop count specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_ARG; - } - break; - - case ME_TRIG_TYPE_COUNT: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) { - PERROR("Invalid acq stop trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iAcqStopCount <= 0) { - PERROR - ("The continous mode has not 'scan' contects.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_ARG; - } - } - break; - - default: - PERROR("Invalid acq stop trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - - switch (trigger->iAcqStartTrigChan) { - case ME_TRIG_CHAN_DEFAULT: - case ME_TRIG_CHAN_SYNCHRONOUS: - break; - - default: - PERROR("Invalid acq start trigger channel specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN; - } - - ME_SUBDEVICE_ENTER; - - if ((flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) && !instance->bitpattern) { - PERROR("This subdevice not support output redirection.\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INVALID_FLAGS; - } - //Stop device - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - //Check if state machine is stopped. - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - //Reset control register. Block all actions. Disable IRQ. Disable FIFO. - ctrl = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //This is paranoic, but to be sure. - instance->preloaded_count = 0; - instance->data_count = 0; - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - - /* Set mode. */ - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound - if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound - PINFO("Hardware wraparound.\n"); - ctrl |= ME4600_AO_MODE_WRAPAROUND; - instance->mode = ME4600_AO_HW_WRAP_MODE; - } else { //Software wraparound - PINFO("Software wraparound.\n"); - ctrl |= ME4600_AO_MODE_CONTINUOUS; - instance->mode = ME4600_AO_SW_WRAP_MODE; - } - } else { //Continous - PINFO("Continous.\n"); - ctrl |= ME4600_AO_MODE_CONTINUOUS; - instance->mode = ME4600_AO_CONTINOUS; - } - - //Set the trigger edge. - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger. - PINFO("External digital trigger.\n"); - instance->start_mode = ME4600_AO_EXT_TRIG; -/* - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; -*/ - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_RISING: - PINFO("Set the trigger edge: rising.\n"); - instance->ctrl_trg = 0x0; - break; - - case ME_TRIG_EDGE_FALLING: - PINFO("Set the trigger edge: falling.\n"); -// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - break; - - case ME_TRIG_EDGE_ANY: - PINFO("Set the trigger edge: both edges.\n"); -// ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - instance->ctrl_trg = - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - break; - } - } else { - PINFO("Internal software trigger.\n"); - instance->start_mode = 0; - } - - //Set the stop mode and value. - if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data - instance->stop_mode = ME4600_AO_ACQ_STOP_MODE; - instance->stop_count = trigger->iAcqStopCount; - } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans' - instance->stop_mode = ME4600_AO_SCAN_STOP_MODE; - instance->stop_count = trigger->iScanStopCount; - } else { //Infinite - instance->stop_mode = ME4600_AO_INF_STOP_MODE; - instance->stop_count = 0; - } - - PINFO("Stop count: %d.\n", instance->stop_count); - - if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start - instance->start_mode |= ME4600_AO_SYNC_HOLD; - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered - PINFO("Synchronous start. Externaly trigger active.\n"); - instance->start_mode |= ME4600_AO_SYNC_EXT_TRIG; - } -#ifdef MEDEBUG_INFO - else { - PINFO - ("Synchronous start. Externaly trigger dissabled.\n"); - } -#endif - - } - //Set speed - outl(conv_ticks - 2, instance->timer_reg); - PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base, - instance->timer_reg - instance->reg_base, conv_ticks - 2); - instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME4600_AO_BASE_FREQUENCY; //<== MUST be with cast! - - //Conect outputs to analog or digital port. - if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) { - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO; - } - // Write the control word - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Set status. - instance->status = ao_status_stream_configured; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - long j; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (!instance->circ_buf.buf) { - PERROR("Circular buffer not exists.\n"); - return ME_ERRNO_INTERNAL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - ME_SUBDEVICE_ENTER; - - if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full. - *count = me_circ_buf_space(&instance->circ_buf); - } else { //The buffer is full. - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } else { //Max time. - t = LONG_MAX; - } - - *count = 0; - - j = jiffies; - - //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled. - wait_event_interruptible_timeout(instance->wait_queue, - ((me_circ_buf_space - (&instance->circ_buf)) - || !(inl(instance->status_reg) - & - ME4600_AO_STATUS_BIT_FSM)), - t); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PERROR("AO subdevice is not running.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - } else if (signal_pending(current)) { - PERROR("Wait on values interrupted from signal.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } else if ((jiffies - j) >= t) { - PERROR("Wait on values timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } else { //Uff... all is good. Inform user about empty space. - *count = me_circ_buf_space(&instance->circ_buf); - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags = 0; - uint32_t status; - uint32_t ctrl; - uint32_t synch; - int count = 0; - int circ_buffer_count; - - unsigned long ref; - unsigned long delay = 0; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - PERROR("Invalid flags.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if ((start_mode != ME_START_MODE_BLOCKING) - && (start_mode != ME_START_MODE_NONBLOCKING)) { - PERROR("Invalid start mode specified.\n"); - return ME_ERRNO_INVALID_START_MODE; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - switch (instance->status) { //Checking actual mode. - case ao_status_stream_configured: - case ao_status_stream_end: - //Correct modes! - break; - - //The device is in wrong mode. - case ao_status_none: - case ao_status_single_configured: - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - PERROR - ("Subdevice must be preinitialize correctly for streaming.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - PDEBUG("Before restart broke stream 'STOP' must be caled.\n"); - return ME_STATUS_ERROR; - - case ao_status_stream_run_wait: - case ao_status_stream_run: - case ao_status_stream_end_wait: - PDEBUG("Stream is already working.\n"); - return ME_ERRNO_SUBDEVICE_BUSY; - - default: - instance->status = ao_status_stream_error; - PERROR_CRITICAL("Status is in wrong state!\n"); - return ME_ERRNO_INTERNAL; - - } - - ME_SUBDEVICE_ENTER; - - if (instance->mode == ME4600_AO_CONTINOUS) { //Continous - instance->circ_buf.tail += instance->preloaded_count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } - circ_buffer_count = me_circ_buf_values(&instance->circ_buf); - - if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer - ME_SUBDEVICE_EXIT; - PERROR("No values in buffer!\n"); - return ME_ERRNO_LACK_OF_RESOURCES; - } - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - //Set values for single_read() - instance->single_value = ME4600_AO_MAX_DATA + 1; - instance->single_value_in_fifo = ME4600_AO_MAX_DATA + 1; - - //Setting stop points - if (instance->stop_mode == ME4600_AO_SCAN_STOP_MODE) { - instance->stop_data_count = - instance->stop_count * circ_buffer_count; - } else { - instance->stop_data_count = instance->stop_count; - } - - if ((instance->stop_data_count != 0) - && (instance->stop_data_count < circ_buffer_count)) { - PERROR("More data in buffer than previously set limit!\n"); - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - //Check FIFO - if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD - PINFO("Enableing FIFO.\n"); - ctrl |= - ME4600_AO_CTRL_BIT_ENABLE_FIFO | - ME4600_AO_CTRL_BIT_RESET_IRQ; - - instance->preloaded_count = 0; - instance->data_count = 0; - } else { //Block IRQ - ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl | ME4600_AO_CTRL_BIT_RESET_IRQ); - - //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it. - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_EF)) { //FIFO empty - if (instance->stop_data_count == 0) { - count = ME4600_AO_FIFO_COUNT; - } else { - count = - (ME4600_AO_FIFO_COUNT < - instance-> - stop_data_count) ? ME4600_AO_FIFO_COUNT : - instance->stop_data_count; - } - - //Copy data - count = - ao_write_data(instance, count, instance->preloaded_count); - - if (count < 0) { //This should never happend! - PERROR_CRITICAL("COPY FINISH WITH ERROR!\n"); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - //Set pre-load features. - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - synch &= - ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - synch |= - (instance->start_mode & ~ME4600_AO_EXT_TRIG) << instance->ao_idx; - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); - - //Default count is '0' - if (instance->mode == ME4600_AO_CONTINOUS) { //Continous - instance->preloaded_count = 0; - instance->circ_buf.tail += count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } else { //Wraparound - instance->preloaded_count += count; - instance->data_count += count; - - //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode. - if ((instance->stop_mode == ME4600_AO_INF_STOP_MODE) - && (circ_buffer_count <= ME4600_AO_FIFO_COUNT)) { //Change to hardware wraparound - PDEBUG - ("Changeing mode from software wraparound to hardware wraparound.\n"); - //Copy all data - count = - ao_write_data(instance, circ_buffer_count, - instance->preloaded_count); - ctrl &= ~ME4600_AO_CTRL_MODE_MASK; - ctrl |= ME4600_AO_MODE_WRAPAROUND; - } - - if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator. - instance->preloaded_count = 0; - } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend! - PERROR_CRITICAL - ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n"); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - - //Set status to 'wait for start' - instance->status = ao_status_stream_run_wait; - - status = inl(instance->status_reg); - //Start state machine and interrupts - ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - if (instance->start_mode == ME4600_AO_EXT_TRIG) { // External trigger. - PINFO("External trigger.\n"); - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - } - if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half! - if ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS) { //Enable IRQ only when hardware_continous is set and FIFO is more than half - ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - } - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - //Trigger output - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - //Add channel to start list - outl(synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx)); - - //Fire - PINFO - ("Fired all software synchronous outputs by software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - - //Restore save settings - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); - } else if (!instance->start_mode) { //Trigger outputs -/* - //Remove channel from start list. // <== Unnecessary. Removed. - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - outl(synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx)); -*/ - //Fire - PINFO("Software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - -/* - //Restore save settings. // <== Unnecessary. Removed. - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); -*/ - } - // Set control task's timeout - ref = jiffies; - instance->timeout.delay = delay; - instance->timeout.start_time = ref; - - if (status & ME4600_AO_STATUS_BIT_HF) { //Less than half but not empty! - PINFO("Less than half.\n"); - if (instance->stop_data_count != 0) { - count = ME4600_AO_FIFO_COUNT / 2; - } else { - count = - ((ME4600_AO_FIFO_COUNT / 2) < - instance->stop_data_count) ? ME4600_AO_FIFO_COUNT / - 2 : instance->stop_data_count; - } - - //Copy data - count = - ao_write_data(instance, count, instance->preloaded_count); - - if (count < 0) { //This should never happend! - PERROR_CRITICAL("COPY FINISH WITH ERROR!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - - if (instance->mode == ME4600_AO_CONTINOUS) { //Continous - instance->circ_buf.tail += count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } else { //Wraparound - instance->data_count += count; - instance->preloaded_count += count; - - if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator. - instance->preloaded_count = 0; - } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend! - PERROR_CRITICAL - ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_HF)) { //More than half! - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - } - //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt. - if ((instance->stop_mode != ME4600_AO_INF_STOP_MODE) - && (instance->mode == ME4600_AO_SW_WRAP_MODE) - && (circ_buffer_count <= (ME4600_AO_FIFO_COUNT / 2))) { //Put more data to FIFO - PINFO("Limited wraparound with less than HALF FIFO datas.\n"); - if (instance->preloaded_count) { //This should never happend! - PERROR_CRITICAL - ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - - while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet. - //Copy to buffer - if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend! - PERROR_CRITICAL - ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - instance->data_count += circ_buffer_count; - - if (!((status = inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy. - spin_lock_irqsave(&instance->subdevice_lock, - cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - break; - } - } - } - // Schedule control task. - instance->ao_control_task_flag = 1; - queue_delayed_work(instance->me4600_workqueue, - &instance->ao_control_task, 1); - - if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start. - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_stream_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if ((instance->status != ao_status_stream_run) - && (instance->status != ao_status_stream_end)) { - PDEBUG("Starting stream canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } else if ((delay) && ((jiffies - ref) >= delay)) { - if (instance->status != ao_status_stream_run) { - if (instance->status == ao_status_stream_end) { - PDEBUG("Timeout reached.\n"); - } else { - if ((jiffies - ref) > delay) { - PERROR - ("Timeout reached. Not handled by control task!\n"); - } else { - PERROR - ("Timeout reached. Signal come but status is strange: %d\n", - instance->status); - } - ao_stop_immediately(instance); - } - - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->status = ao_status_stream_end; - err = ME_ERRNO_TIMEOUT; - } - } - } - - ME_SUBDEVICE_EXIT; - return err; -} - -static int me4600_ao_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) { - PERROR("Invalid wait argument specified.\n"); - *status = ME_STATUS_INVALID; - return ME_ERRNO_INVALID_WAIT; - } - - ME_SUBDEVICE_ENTER; - - switch (instance->status) { - case ao_status_single_configured: - case ao_status_single_end: - case ao_status_stream_configured: - case ao_status_stream_end: - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - *status = ME_STATUS_IDLE; - break; - - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - case ao_status_stream_run_wait: - case ao_status_stream_run: - case ao_status_stream_end_wait: - *status = ME_STATUS_BUSY; - break; - - case ao_status_none: - default: - *status = - (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ? - ME_STATUS_BUSY : ME_STATUS_IDLE; - break; - } - - if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) { - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - ((instance->status != - ao_status_single_run_wait) - && (instance->status != - ao_status_single_run) - && (instance->status != - ao_status_single_end_wait) - && (instance->status != - ao_status_stream_run_wait) - && (instance->status != - ao_status_stream_run) - && (instance->status != - ao_status_stream_end_wait)), - LONG_MAX); - - if (instance->status != ao_status_stream_end) { - PDEBUG("Wait for IDLE canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait for IDLE interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - - *status = ME_STATUS_IDLE; - } - - *values = me_circ_buf_space(&instance->circ_buf); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags) -{ // Stop work and empty buffer and FIFO - int err = ME_ERRNO_SUCCESS; - me4600_ao_subdevice_t *instance; - unsigned long cpu_flags; - volatile uint32_t ctrl; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((stop_mode != ME_STOP_MODE_IMMEDIATE) - && (stop_mode != ME_STOP_MODE_LAST_VALUE)) { - PERROR("Invalid stop mode specified.\n"); - return ME_ERRNO_INVALID_STOP_MODE; - } - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (instance->status < ao_status_stream_configured) { - //There is nothing to stop! - PERROR("Subdevice not in streaming mode. %d\n", - instance->status); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - ME_SUBDEVICE_ENTER; - - //Mark as stopping. => Software stop. - instance->status = ao_status_stream_end_wait; - - if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now! - err = ao_stop_immediately(instance); - } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) { - ctrl = inl(instance->ctrl_reg) & ME4600_AO_CTRL_MODE_MASK; - if (ctrl == ME4600_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - //Only runing process will interrupt this call. Events are signaled when status change. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_stream_end_wait), - LONG_MAX); - - if (instance->status != ao_status_stream_end) { - PDEBUG("Stopping stream canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Stopping stream interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - if (!flags) { //Reset FIFO - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - if (!flags) { //Reset software buffer - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - instance->preloaded_count = 0; - instance->data_count = 0; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_write(me_subdevice_t *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me4600_ao_subdevice_t *instance; - unsigned long cpu_flags = 0; - uint32_t reg_copy; - - int copied_from_user = 0; - int left_to_copy_from_user = *count; - - int copied_values; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - //Checking arguments - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (*count <= 0) { - PERROR("Invalid count of values specified.\n"); - return ME_ERRNO_INVALID_VALUE_COUNT; - } - - if (values == NULL) { - PERROR("Invalid address of values specified.\n"); - return ME_ERRNO_INVALID_POINTER; - } - - if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode. - PERROR - ("Subdevice must be preinitialize correctly for streaming.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } -/// @note If no 'pre-load' is used. stream_start() will move data to FIFO. - switch (write_mode) { - case ME_WRITE_MODE_PRELOAD: - - //Device must be stopped. - if ((instance->status != ao_status_stream_configured) - && (instance->status != ao_status_stream_end)) { - PERROR - ("Subdevice mustn't be runing when 'pre-load' mode is used.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - break; - case ME_WRITE_MODE_NONBLOCKING: - case ME_WRITE_MODE_BLOCKING: - /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up! - /// @note Some other thread must empty buffer by starting engine. - break; - - default: - PERROR("Invalid write mode specified.\n"); - return ME_ERRNO_INVALID_WRITE_MODE; - } - - if (instance->mode & ME4600_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped. - if ((instance->status != ao_status_stream_configured) - && (instance->status != ao_status_stream_end)) { - PERROR - ("Subdevice mustn't be runing when 'pre-load' mode is used.\n"); - return ME_ERRNO_INVALID_WRITE_MODE; - } - } - - if ((instance->mode == ME4600_AO_HW_WRAP_MODE) && (write_mode != ME_WRITE_MODE_PRELOAD)) { // hardware wrap_around mode. - //This is transparent for user. - PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n"); - write_mode = ME_WRITE_MODE_PRELOAD; - } - - ME_SUBDEVICE_ENTER; - - if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - //Check FIFO - if (!(reg_copy & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it. - reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_FIFO; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - instance->preloaded_count = 0; - } - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } - - while (1) { - //Copy to buffer. This step is common for all modes. - copied_from_user = - ao_get_data_from_user(instance, left_to_copy_from_user, - values + (*count - - left_to_copy_from_user)); - left_to_copy_from_user -= copied_from_user; - - reg_copy = inl(instance->status_reg); - if ((instance->status == ao_status_stream_run) && !(reg_copy & ME4600_AO_STATUS_BIT_FSM)) { //BROKEN PIPE! The state machine is stoped but logical status show that should be working. - PERROR("Broken pipe in write.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - break; - } - - if ((instance->status == ao_status_stream_run) && (instance->mode == ME4600_AO_CONTINOUS) && (reg_copy & ME4600_AO_STATUS_BIT_HF)) { //Continous mode runing and data are below half! - - // Block interrupts. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - //reg_copy &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - reg_copy |= ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - //Fast copy - copied_values = - ao_write_data(instance, ME4600_AO_FIFO_COUNT / 2, - 0); - if (copied_values > 0) { - instance->circ_buf.tail += copied_values; - instance->circ_buf.tail &= - instance->circ_buf.mask; - continue; - } - // Activate interrupts. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - //reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - reg_copy &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (copied_values == 0) { //This was checked and never should happend! - PERROR_CRITICAL("COPING FINISH WITH 0!\n"); - } - - if (copied_values < 0) { //This was checked and never should happend! - PERROR_CRITICAL - ("COPING FINISH WITH AN ERROR!\n"); - instance->status = ao_status_stream_fifo_error; - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - break; - } - } - - if (!left_to_copy_from_user) { //All datas were copied. - break; - } else { //Not all datas were copied. - if (instance->mode & ME4600_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size! - PERROR - ("Too much data for wraparound mode! Exceeded size of %ld.\n", - ME4600_AO_CIRC_BUF_COUNT - 1); - err = ME_ERRNO_RING_BUFFER_OVERFLOW; - break; - } - - if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls - break; - } - - wait_event_interruptible(instance->wait_queue, - me_circ_buf_space(&instance-> - circ_buf)); - - if (signal_pending(current)) { - PERROR("Writing interrupted by signal.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - break; - } - - if (instance->status == ao_status_none) { //Reset - PERROR("Writing interrupted by reset.\n"); - err = ME_ERRNO_CANCELLED; - break; - } - } - } - - if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload - copied_values = - ao_write_data_pooling(instance, ME4600_AO_FIFO_COUNT, - instance->preloaded_count); - instance->preloaded_count += copied_values; - instance->data_count += copied_values; - - if ((instance->mode == ME4600_AO_HW_WRAP_MODE) - && (me_circ_buf_values(&instance->circ_buf) > - ME4600_AO_FIFO_COUNT)) { - PERROR - ("Too much data for hardware wraparound mode! Exceeded size of %d.\n", - ME4600_AO_FIFO_COUNT); - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } - } - - *count = *count - left_to_copy_from_user; - ME_SUBDEVICE_EXIT; - - return err; -} -static irqreturn_t me4600_ao_isr(int irq, void *dev_id) -{ - me4600_ao_subdevice_t *instance = dev_id; - uint32_t irq_status; - uint32_t ctrl; - uint32_t status; - int count = 0; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inl(instance->irq_status_reg); - if (!(irq_status & (ME4600_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) { - PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n", - jiffies, __func__, instance->ao_idx, irq_status); - return IRQ_NONE; - } - - if (!instance->circ_buf.buf) { - instance->status = ao_status_stream_error; - PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n"); - //Block interrupts. Stop machine. - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= - ME4600_AO_CTRL_BIT_RESET_IRQ | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Inform user - wake_up_interruptible_all(&instance->wait_queue); - return IRQ_HANDLED; - } - - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE? - PDEBUG("Interrupt come but ISM is not working!\n"); - //Block interrupts. Stop machine. - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= - ME4600_AO_CTRL_BIT_RESET_IRQ | ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - return IRQ_HANDLED; - } - //General procedure. Process more datas. - -#ifdef MEDEBUG_DEBUG - if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty! - PDEBUG("Circular buffer empty!\n"); - } -#endif - - //Check FIFO - if (status & ME4600_AO_STATUS_BIT_HF) { //OK less than half - - //Block interrupts - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - do { - //Calculate how many should be copied. - count = - (instance->stop_data_count) ? instance-> - stop_data_count - - instance->data_count : ME4600_AO_FIFO_COUNT / 2; - if (ME4600_AO_FIFO_COUNT / 2 < count) { - count = ME4600_AO_FIFO_COUNT / 2; - } - //Copy data - if (instance->mode == ME4600_AO_CONTINOUS) { //Continous - count = ao_write_data(instance, count, 0); - if (count > 0) { - instance->circ_buf.tail += count; - instance->circ_buf.tail &= - instance->circ_buf.mask; - instance->data_count += count; - - if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied. - break; - } - } - } else if ((instance->mode == ME4600_AO_SW_WRAP_MODE) && ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS)) { //Wraparound (software) - if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer. - count = - ao_write_data(instance, count, 0); - } else { //Copy in wraparound mode. - count = - ao_write_data_wraparound(instance, - count, - instance-> - preloaded_count); - } - - if (count > 0) { - instance->data_count += count; - instance->preloaded_count += count; - instance->preloaded_count %= - me_circ_buf_values(&instance-> - circ_buf); - - if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied. - break; - } - } - } - - if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work. - break; - } - } //Repeat if still is under half fifo - while ((status = - inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF); - - //Unblock interrupts - ctrl = inl(instance->ctrl_reg); - if (count >= 0) { //Copy was successful. - if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts. - PDEBUG("Finishing work. Interrupt disabled.\n"); - instance->status = ao_status_stream_end_wait; - } else if (count > 0) { //Normal work. Enable interrupt. - PDEBUG("Normal work. Enable interrupt.\n"); - ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - } else { //Normal work but there are no more data in buffer. Interrupt active but blocked. stream_write() will unblock it. - PDEBUG - ("No data in software buffer. Interrupt blocked.\n"); - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - } - } else { //Error during copy. - instance->status = ao_status_stream_fifo_error; - } - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - } else { //?? more than half - PDEBUG - ("Interrupt come but FIFO more than half full! Reset interrupt.\n"); - //Reset pending interrupt - ctrl = inl(instance->ctrl_reg); - ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - } - - PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n", - me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail, - instance->circ_buf.head); - PINFO("ISR: Stop count: %d.\n", instance->stop_count); - PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count); - PINFO("ISR: Data count: %d.\n", instance->data_count); - - //Inform user - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -static void me4600_ao_destructor(struct me_subdevice *subdevice) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - instance->ao_control_task_flag = 0; - - // Reset subdevice to asure clean exit. - me4600_ao_io_reset_subdevice(subdevice, NULL, - ME_IO_RESET_SUBDEVICE_NO_FLAGS); - - // Remove any tasks from work queue. This is paranoic because it was done allready in reset(). - if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue. - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(2); - } - - if (instance->fifo) { - if (instance->irq) { - free_irq(instance->irq, instance); - instance->irq = 0; - } - - if (instance->circ_buf.buf) { - free_pages((unsigned long)instance->circ_buf.buf, - ME4600_AO_CIRC_BUF_SIZE_ORDER); - } - instance->circ_buf.buf = NULL; - } - - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base, - spinlock_t *preload_reg_lock, - uint32_t *preload_flags, - int ao_idx, - int fifo, - int irq, - struct workqueue_struct *me4600_wq) -{ - me4600_ao_subdevice_t *subdevice; - int err; - - PDEBUG("executed. idx=%d\n", ao_idx); - - // Allocate memory for subdevice instance. - subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_ao_subdevice_t)); - - // Initialize subdevice base class. - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->preload_reg_lock = preload_reg_lock; - subdevice->preload_flags = preload_flags; - - // Store analog output index. - subdevice->ao_idx = ao_idx; - - // Store if analog output has fifo. - subdevice->fifo = (ao_idx < fifo) ? 1 : 0; - - if (subdevice->fifo) { // Allocate and initialize circular buffer. - subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1; - - subdevice->circ_buf.buf = - (void *)__get_free_pages(GFP_KERNEL, - ME4600_AO_CIRC_BUF_SIZE_ORDER); - PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf, - ME4600_AO_CIRC_BUF_SIZE); - - if (!subdevice->circ_buf.buf) { - PERROR - ("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - - memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE); - } else { // No FIFO. - subdevice->circ_buf.mask = 0; - subdevice->circ_buf.buf = NULL; - } - - subdevice->circ_buf.head = 0; - subdevice->circ_buf.tail = 0; - - subdevice->status = ao_status_none; - subdevice->ao_control_task_flag = 0; - subdevice->timeout.delay = 0; - subdevice->timeout.start_time = jiffies; - - // Initialize wait queue. - init_waitqueue_head(&subdevice->wait_queue); - - // Initialize single value to 0V. - subdevice->single_value = 0x8000; - subdevice->single_value_in_fifo = 0x8000; - - // Register interrupt service routine. - if (subdevice->fifo) { - subdevice->irq = irq; - if (request_irq(subdevice->irq, me4600_ao_isr, - IRQF_DISABLED | IRQF_SHARED, - ME4600_NAME, subdevice)) { - PERROR("Cannot get interrupt line.\n"); - PDEBUG("free circ_buf = %p size=%d", - subdevice->circ_buf.buf, - PAGE_SHIFT << ME4600_AO_CIRC_BUF_SIZE_ORDER); - free_pages((unsigned long)subdevice->circ_buf.buf, - ME4600_AO_CIRC_BUF_SIZE_ORDER); - me_subdevice_deinit((me_subdevice_t *) subdevice); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - } else { - subdevice->irq = 0; - } - - // Initialize registers. - subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG; - subdevice->preload_reg = reg_base + ME4600_AO_SYNC_REG; - if (ao_idx == 0) { - subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bitpattern = 0; - } else if (ao_idx == 1) { - subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bitpattern = 0; - } else if (ao_idx == 2) { - subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bitpattern = 0; - } else if (ao_idx == 3) { - subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bitpattern = 1; - } else { - PERROR_CRITICAL("WRONG SUBDEVICE idx=%d!", ao_idx); - me_subdevice_deinit((me_subdevice_t *) subdevice); - if (subdevice->fifo) { - free_pages((unsigned long)subdevice->circ_buf.buf, - ME4600_AO_CIRC_BUF_SIZE_ORDER); - } - subdevice->circ_buf.buf = NULL; - kfree(subdevice); - return NULL; - } - - // Override base class methods. - subdevice->base.me_subdevice_destructor = me4600_ao_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_ao_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_ao_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me4600_ao_io_single_write; - subdevice->base.me_subdevice_io_stream_config = - me4600_ao_io_stream_config; - subdevice->base.me_subdevice_io_stream_new_values = - me4600_ao_io_stream_new_values; - subdevice->base.me_subdevice_io_stream_write = - me4600_ao_io_stream_write; - subdevice->base.me_subdevice_io_stream_start = - me4600_ao_io_stream_start; - subdevice->base.me_subdevice_io_stream_status = - me4600_ao_io_stream_status; - subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop; - subdevice->base.me_subdevice_query_number_channels = - me4600_ao_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_ao_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_ao_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me4600_ao_query_subdevice_caps_args; - subdevice->base.me_subdevice_query_range_by_min_max = - me4600_ao_query_range_by_min_max; - subdevice->base.me_subdevice_query_number_ranges = - me4600_ao_query_number_ranges; - subdevice->base.me_subdevice_query_range_info = - me4600_ao_query_range_info; - subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer; - - // Prepare work queue - subdevice->me4600_workqueue = me4600_wq; - -/* workqueue API changed in kernel 2.6.20 */ - INIT_DELAYED_WORK(&subdevice->ao_control_task, - me4600_ao_work_control_task); - - if (subdevice->fifo) { // Set speed for single operations. - outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg); - subdevice->hardware_stop_delay = HZ / 10; //100ms - } - - return subdevice; -} - -/** @brief Stop presentation. Preserve FIFOs. -* -* @param instance The subdevice instance (pointer). -*/ -inline int ao_stop_immediately(me4600_ao_subdevice_t *instance) -{ - unsigned long cpu_flags; - uint32_t ctrl; - int timeout; - int i; - - timeout = - (instance->hardware_stop_delay > - (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10; - for (i = 0; i <= timeout; i++) { - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched! - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { // Exit. - break; - } - //Still working! - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - if (i > timeout) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - return ME_ERRNO_INTERNAL; - } - return ME_ERRNO_SUCCESS; -} - -/** @brief Copy data from circular buffer to fifo (fast) in wraparound. -* @note This is time critical function. Checking is done at begining and end only. -* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied data. -* @return On error/success: 0. No datas were copied => no data in buffer. -* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW. -*/ -inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is time critical function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int i = 1; - - if (count <= 0) { //Wrong count! - return 0; - } - - while (i < local_count) { - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - if (pos == instance->circ_buf.head) { - pos = instance->circ_buf.tail; - } - i++; - } - - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied! - PERROR("FIFO was full before all datas were copied! idx=%d\n", - instance->ao_idx); - return -ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } else { //Add last value - value = *(instance->circ_buf.buf + pos); - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - } - - PINFO("WRAPAROUND LOADED %d values. idx=%d\n", local_count, - instance->ao_idx); - return local_count; -} - -/** @brief Copy data from software buffer to fifo (fast). -* @note This is time critical function. Checking is done at begining and end only. -* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied data. -* @return On error/success: 0. No datas were copied => no data in buffer. -* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW. -*/ -inline int ao_write_data(me4600_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is time critical function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int max_count; - int i = 1; - - if (count <= 0) { //Wrong count! - return 0; - } - - max_count = me_circ_buf_values(&instance->circ_buf) - start_pos; - if (max_count <= 0) { //No data to copy! - return 0; - } - - if (max_count < count) { - local_count = max_count; - } - - while (i < local_count) { - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - i++; - } - - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied! - PERROR("FIFO was full before all datas were copied! idx=%d\n", - instance->ao_idx); - return -ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } else { //Add last value - value = *(instance->circ_buf.buf + pos); - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - } - - PINFO("FAST LOADED %d values. idx=%d\n", local_count, instance->ao_idx); - return local_count; -} - -/** @brief Copy data from software buffer to fifo (slow). -* @note This is slow function that copy all data from buffer to FIFO with full control. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied values. -* @return On error/success: 0. FIFO was full at begining. -* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW. -*/ -inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is slow function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int i; - int max_count; - - if (count <= 0) { //Wrong count! - PERROR("SLOW LOADED: Wrong count! idx=%d\n", instance->ao_idx); - return 0; - } - - max_count = me_circ_buf_values(&instance->circ_buf) - start_pos; - if (max_count <= 0) { //No data to copy! - PERROR("SLOW LOADED: No data to copy! idx=%d\n", - instance->ao_idx); - return 0; - } - - if (max_count < count) { - local_count = max_count; - } - - for (i = 0; i < local_count; i++) { - status = inl(instance->status_reg); - if (!(status & ME4600_AO_STATUS_BIT_FF)) { //FIFO is full! - return i; - } - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - } - - PINFO("SLOW LOADED %d values. idx=%d\n", local_count, instance->ao_idx); - return local_count; -} - -/** @brief Copy data from user space to circular buffer. -* @param instance The subdevice instance (pointer). -* @param count Number of datas in user space. -* @param user_values Buffer's pointer. -* -* @return On success: Number of copied values. -* @return On error: -ME_ERRNO_INTERNAL. -*/ -inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count, - int *user_values) -{ - int i, err; - int empty_space; - int copied; - int value; - - empty_space = me_circ_buf_space(&instance->circ_buf); - //We have only this space free. - copied = (count < empty_space) ? count : empty_space; - for (i = 0; i < copied; i++) { //Copy from user to buffer - if ((err = get_user(value, (int *)(user_values + i)))) { - PERROR - ("BUFFER LOADED: get_user(0x%p) return an error: %d. idx=%d\n", - user_values + i, err, instance->ao_idx); - return -ME_ERRNO_INTERNAL; - } - /// @note The analog output in me4600 series has size of 16 bits. - *(instance->circ_buf.buf + instance->circ_buf.head) = - (uint16_t) value; - instance->circ_buf.head++; - instance->circ_buf.head &= instance->circ_buf.mask; - } - - PINFO("BUFFER LOADED %d values. idx=%d\n", copied, instance->ao_idx); - return copied; -} - -/** @brief Checking actual hardware and logical state. -* @param instance The subdevice instance (pointer). -*/ -static void me4600_ao_work_control_task(struct work_struct *work) -{ - me4600_ao_subdevice_t *instance; - unsigned long cpu_flags = 0; - uint32_t status; - uint32_t ctrl; - uint32_t synch; - int reschedule = 0; - int signaling = 0; - - instance = - container_of((void *)work, me4600_ao_subdevice_t, ao_control_task); - PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies, - instance->ao_idx); - - status = inl(instance->status_reg); - PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->status_reg - instance->reg_base, status); - - switch (instance->status) { // Checking actual mode. - - // Not configured for work. - case ao_status_none: - break; - - //This are stable modes. No need to do anything. (?) - case ao_status_single_configured: - case ao_status_stream_configured: - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - PERROR("Shouldn't be running!.\n"); - break; - - case ao_status_stream_end: - if (!instance->fifo) { - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - case ao_status_single_end: - if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop. - - // Wait for stop. - reschedule = 1; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched! - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP - | ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG); - ctrl &= - ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - break; - - // Single modes - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - - if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. - if (((instance->fifo) - && (!(status & ME4600_AO_STATUS_BIT_EF))) - || (!(instance->fifo))) { // Single is in end state. - PDEBUG("Single call has been complited.\n"); - - // Set correct value for single_read(); - instance->single_value = - instance->single_value_in_fifo; - - // Set status as 'ao_status_single_end' - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - // Wait for stop ISM. - reschedule = 1; - - break; - } - } - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched! - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG); - /// Fix for timeout error. - ctrl &= - ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH); - if (instance->fifo) { //Disabling FIFO - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - spin_lock(instance->preload_reg_lock); - //Remove from synchronous start. Block triggering from this output. - synch = inl(instance->preload_reg); - synch &= - ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << - instance->ao_idx); - if (!(instance->fifo)) { // No FIFO - set to single safe mode - synch |= - ME4600_AO_SYNC_HOLD << instance->ao_idx; - } - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch); - spin_unlock(instance->preload_reg_lock); - - if (!(instance->fifo)) { // No FIFO - // Restore old settings. - PDEBUG("Write old value back to register.\n"); - outl(instance->single_value, - instance->single_reg); - PDEBUG_REG - ("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - instance->single_value); - } - // Set correct value for single_read(); - instance->single_value_in_fifo = instance->single_value; - - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - } - // Wait for stop. - reschedule = 1; - break; - - // Stream modes - case ao_status_stream_run_wait: - if (!instance->fifo) { - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (status & ME4600_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish. - instance->status = ao_status_stream_run; - - // Signal end of this step - signaling = 1; - } else { // State machine is not working. - if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already! - instance->status = ao_status_stream_end; - - // Signal the end. - signaling = 1; - // Wait for stop. - reschedule = 1; - break; - } - } - - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched! - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | - ME4600_AO_CTRL_BIT_RESET_IRQ; - ctrl &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - spin_lock(instance->preload_reg_lock); - //Remove from synchronous start. Block triggering from this output. - synch = inl(instance->preload_reg); - synch &= - ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << - instance->ao_idx); - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch); - spin_unlock(instance->preload_reg_lock); - - instance->status = ao_status_stream_end; - - // Signal the end. - signaling = 1; - } - // Wait for stop. - reschedule = 1; - break; - - case ao_status_stream_run: - if (!instance->fifo) { - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error. - // BROKEN PIPE! - if (!(status & ME4600_AO_STATUS_BIT_EF)) { // FIFO is empty. - if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty. - if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown. - PDEBUG - ("ISM stoped. No data in FIFO. Buffer is not empty.\n"); - instance->status = - ao_status_stream_end; - } else { - PERROR - ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n"); - instance->status = - ao_status_stream_buffer_error; - } - } else { // Software buffer is empty. - PDEBUG - ("ISM stoped. No data in FIFO. Buffer is empty.\n"); - instance->status = ao_status_stream_end; - } - } else { // There are still datas in FIFO. - if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty. - PERROR - ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n"); - } else { // Software buffer is empty. - PERROR - ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n"); - } - instance->status = ao_status_stream_fifo_error; - - } - - // Signal the failure. - signaling = 1; - break; - } - // Wait for stop. - reschedule = 1; - break; - - case ao_status_stream_end_wait: - if (!instance->fifo) { - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (!(status & ME4600_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish. - instance->status = ao_status_stream_end; - signaling = 1; - } - // State machine is working. - reschedule = 1; - break; - - default: - PERROR_CRITICAL("Status is in wrong state (%d)!\n", - instance->status); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - - } - - if (signaling) { //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - } - - if (instance->ao_control_task_flag && reschedule) { // Reschedule task - queue_delayed_work(instance->me4600_workqueue, - &instance->ao_control_task, 1); - } else { - PINFO("<%s> Ending control task.\n", __func__); - } - -} -#else -/// @note SPECIAL BUILD FOR BOSCH -/// @author Guenter Gebhardt -static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t tmp; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status); - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= ~(0x10001 << instance->ao_idx); - outl(tmp, instance->preload_reg); - *instance->preload_flags &= ~(0x1 << instance->ao_idx); - spin_unlock(instance->preload_reg_lock); - - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - - while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ; - - outl(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP, - instance->ctrl_reg); - - outl(0x8000, instance->single_reg); - - instance->single_value = 0x8000; - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - if (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) { - PERROR("Subdevice is busy.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - if (channel == 0) { - if (single_config == 0) { - if (ref == ME_REF_AO_GROUND) { - if (trig_chan == ME_TRIG_CHAN_DEFAULT) { - if (trig_type == ME_TRIG_TYPE_SW) { - tmp = inl(instance->ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - - spin_lock(instance-> - preload_reg_lock); - tmp = - inl(instance->preload_reg); - tmp &= - ~(0x10001 << instance-> - ao_idx); - outl(tmp, - instance->preload_reg); - *instance->preload_flags &= - ~(0x1 << instance->ao_idx); - spin_unlock(instance-> - preload_reg_lock); - } else if (trig_type == - ME_TRIG_TYPE_EXT_DIGITAL) { - if (trig_edge == - ME_TRIG_EDGE_RISING) { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - outl(tmp, - instance-> - ctrl_reg); - } else if (trig_edge == - ME_TRIG_EDGE_FALLING) - { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - outl(tmp, - instance-> - ctrl_reg); - } else if (trig_edge == - ME_TRIG_EDGE_ANY) { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - outl(tmp, - instance-> - ctrl_reg); - } else { - PERROR - ("Invalid trigger edge.\n"); - err = - ME_ERRNO_INVALID_TRIG_EDGE; - goto ERROR; - } - - spin_lock(instance-> - preload_reg_lock); - - tmp = - inl(instance->preload_reg); - tmp &= - ~(0x10001 << instance-> - ao_idx); - tmp |= 0x1 << instance->ao_idx; - outl(tmp, - instance->preload_reg); - *instance->preload_flags &= - ~(0x1 << instance->ao_idx); - spin_unlock(instance-> - preload_reg_lock); - } else { - PERROR - ("Invalid trigger type.\n"); - err = - ME_ERRNO_INVALID_TRIG_TYPE; - goto ERROR; - } - } else if (trig_chan == - ME_TRIG_CHAN_SYNCHRONOUS) { - if (trig_type == ME_TRIG_TYPE_SW) { - tmp = inl(instance->ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - - spin_lock(instance-> - preload_reg_lock); - tmp = - inl(instance->preload_reg); - tmp &= - ~(0x10001 << instance-> - ao_idx); - tmp |= 0x1 << instance->ao_idx; - outl(tmp, - instance->preload_reg); - *instance->preload_flags |= - 0x1 << instance->ao_idx; - spin_unlock(instance-> - preload_reg_lock); - } else if (trig_type == - ME_TRIG_TYPE_EXT_DIGITAL) { - if (trig_edge == - ME_TRIG_EDGE_RISING) { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - } else if (trig_edge == - ME_TRIG_EDGE_FALLING) - { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - outl(tmp, - instance-> - ctrl_reg); - } else if (trig_edge == - ME_TRIG_EDGE_ANY) { - tmp = - inl(instance-> - ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, - instance-> - ctrl_reg); - tmp = - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE - | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - outl(tmp, - instance-> - ctrl_reg); - } else { - PERROR - ("Invalid trigger edge.\n"); - err = - ME_ERRNO_INVALID_TRIG_EDGE; - goto ERROR; - } - - spin_lock(instance-> - preload_reg_lock); - - tmp = - inl(instance->preload_reg); - tmp |= - 0x10001 << instance->ao_idx; - outl(tmp, - instance->preload_reg); - *instance->preload_flags &= - ~(0x1 << instance->ao_idx); - spin_unlock(instance-> - preload_reg_lock); - } else { - PERROR - ("Invalid trigger type.\n"); - err = - ME_ERRNO_INVALID_TRIG_TYPE; - goto ERROR; - } - } else { - PERROR - ("Invalid trigger channel specified.\n"); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - } else { - PERROR("Invalid analog reference specified.\n"); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - } else { - PERROR("Invalid single config specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - goto ERROR; - } - } else { - PERROR("Invalid channel number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - goto ERROR; - } - -ERROR: - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - tmp = inl(instance->ctrl_reg); - - if (tmp & 0x3) { - PERROR("Not in single mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } else { - *value = instance->single_value; - } - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long mask = 0; - unsigned long tmp; - unsigned long cpu_flags; - int i; - wait_queue_head_t queue; - unsigned long j; - unsigned long delay = 0; - - PDEBUG("executed.\n"); - - init_waitqueue_head(&queue); - - instance = (me4600_ao_subdevice_t *) subdevice; - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - tmp = inl(instance->ctrl_reg); - - if (tmp & 0x3) { - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - PERROR("Not in single mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - } - - if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { - outl(value, instance->single_reg); - instance->single_value = value; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - j = jiffies; - - while (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - - if (signal_pending(current)) { - PERROR - ("Wait on external trigger interrupted by signal.\n"); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (delay && ((jiffies - j) > delay)) { - PERROR("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) - == (0x10001 << instance->ao_idx)) { - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { - tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - outl(tmp, instance->ctrl_reg); - outl(value, instance->single_reg); - instance->single_value = value; - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - j = jiffies; - - while (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, - 1); - - if (signal_pending(current)) { - PERROR - ("Wait on external trigger interrupted by signal.\n"); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (delay && ((jiffies - j) > delay)) { - PERROR("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } - } else { - outl(value, instance->single_reg); - instance->single_value = value; - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) - == (0x1 << instance->ao_idx)) { - outl(value, instance->single_reg); - instance->single_value = value; - - PDEBUG("Synchronous SW, flags = 0x%X.\n", flags); - - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { - PDEBUG("Trigger synchronous SW.\n"); - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - - for (i = 0; i < ME4600_AO_MAX_SUBDEVICES; i++) { - if ((*instance->preload_flags & (0x1 << i))) { - if ((tmp & (0x10001 << i)) == - (0x1 << i)) { - mask |= 0x1 << i; - } - } - } - - tmp &= ~(mask); - - outl(tmp, instance->preload_reg); - spin_unlock(instance->preload_reg_lock); - } - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } else { - outl(value, instance->single_reg); - instance->single_value = value; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } - -ERROR: - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long ctrl; - unsigned long tmp; - unsigned long cpu_flags; - uint64_t conv_ticks; - unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow; - unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - conv_ticks = - (uint64_t) conv_start_ticks_low + - ((uint64_t) conv_start_ticks_high << 32); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - if ((inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_FSM) { - PERROR("Subdevice is busy.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - ctrl = inl(instance->ctrl_reg); - ctrl |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(ctrl, instance->ctrl_reg); - ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(ctrl, instance->ctrl_reg); - - if (count != 1) { - PERROR("Invalid stream configuration list count specified.\n"); - err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT; - goto ERROR; - } - - if (config_list[0].iChannel != 0) { - PERROR("Invalid channel number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - goto ERROR; - } - - if (config_list[0].iStreamConfig != 0) { - PERROR("Invalid stream config specified.\n"); - err = ME_ERRNO_INVALID_STREAM_CONFIG; - goto ERROR; - } - - if (config_list[0].iRef != ME_REF_AO_GROUND) { - PERROR("Invalid analog reference.\n"); - err = ME_ERRNO_INVALID_REF; - goto ERROR; - } - - if ((trigger->iAcqStartTicksLow != 0) - || (trigger->iAcqStartTicksHigh != 0)) { - PERROR - ("Invalid acquisition start trigger argument specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_ARG; - goto ERROR; - } - - switch (trigger->iAcqStartTrigType) { - - case ME_TRIG_TYPE_SW: - break; - - case ME_TRIG_TYPE_EXT_DIGITAL: - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - - switch (trigger->iAcqStartTrigEdge) { - - case ME_TRIG_EDGE_RISING: - break; - - case ME_TRIG_EDGE_FALLING: - ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE; - - break; - - case ME_TRIG_EDGE_ANY: - ctrl |= - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | - ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - - break; - - default: - PERROR - ("Invalid acquisition start trigger edge specified.\n"); - - err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - - goto ERROR; - - break; - } - - break; - - default: - PERROR("Invalid acquisition start trigger type specified.\n"); - - err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE; - - goto ERROR; - - break; - } - - switch (trigger->iScanStartTrigType) { - - case ME_TRIG_TYPE_FOLLOW: - break; - - default: - PERROR("Invalid scan start trigger type specified.\n"); - - err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - - goto ERROR; - - break; - } - - switch (trigger->iConvStartTrigType) { - - case ME_TRIG_TYPE_TIMER: - if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS) - || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) { - PERROR - ("Invalid conv start trigger argument specified.\n"); - err = ME_ERRNO_INVALID_CONV_START_ARG; - goto ERROR; - } - - break; - - default: - PERROR("Invalid conv start trigger type specified.\n"); - - err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - - goto ERROR; - - break; - } - - /* Preset to hardware wraparound mode */ - instance->flags &= ~(ME4600_AO_FLAGS_SW_WRAP_MODE_MASK); - - switch (trigger->iScanStopTrigType) { - - case ME_TRIG_TYPE_NONE: - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - /* Set flags to indicate usage of software mode. */ - instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_INF; - instance->wrap_count = 0; - instance->wrap_remaining = 0; - } - - break; - - case ME_TRIG_TYPE_COUNT: - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iScanStopCount <= 0) { - PERROR("Invalid scan stop count specified.\n"); - err = ME_ERRNO_INVALID_SCAN_STOP_ARG; - goto ERROR; - } - - /* Set flags to indicate usage of software mode. */ - instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN; - instance->wrap_count = trigger->iScanStopCount; - instance->wrap_remaining = trigger->iScanStopCount; - } else { - PERROR("Invalid scan stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - - break; - - default: - PERROR("Invalid scan stop trigger type specified.\n"); - - err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE; - - goto ERROR; - - break; - } - - switch (trigger->iAcqStopTrigType) { - - case ME_TRIG_TYPE_NONE: - break; - - case ME_TRIG_TYPE_COUNT: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) { - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iAcqStopCount <= 0) { - PERROR("Invalid acq stop count specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_ARG; - goto ERROR; - } - - /* Set flags to indicate usage of software mode. */ - instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN; - instance->wrap_count = trigger->iAcqStopCount; - instance->wrap_remaining = trigger->iAcqStopCount; - } else { - PERROR("Invalid acp stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - } - - break; - - default: - PERROR("Invalid acq stop trigger type specified.\n"); - err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - goto ERROR; - break; - } - - switch (trigger->iAcqStartTrigChan) { - - case ME_TRIG_CHAN_DEFAULT: - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= ~(0x10001 << instance->ao_idx); - outl(tmp, instance->preload_reg); - spin_unlock(instance->preload_reg_lock); - - break; - - case ME_TRIG_CHAN_SYNCHRONOUS: - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) { - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= ~(0x10001 << instance->ao_idx); - outl(tmp, instance->preload_reg); - tmp |= 0x1 << instance->ao_idx; - outl(tmp, instance->preload_reg); - spin_unlock(instance->preload_reg_lock); - } else { - ctrl &= ~(ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG); - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= ~(0x10001 << instance->ao_idx); - outl(tmp, instance->preload_reg); - tmp |= 0x10000 << instance->ao_idx; - outl(tmp, instance->preload_reg); - spin_unlock(instance->preload_reg_lock); - } - - break; - - default: - PERROR("Invalid acq start trigger channel specified.\n"); - err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN; - goto ERROR; - - break; - } - - outl(conv_ticks - 2, instance->timer_reg); - - if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) { - if (instance->ao_idx == 3) { - ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO; - } else { - err = ME_ERRNO_INVALID_FLAGS; - goto ERROR; - } - } else { - if (instance->ao_idx == 3) { - ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_DO; - } - } - - /* Set hardware mode. */ - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - ctrl |= ME4600_AO_CTRL_BIT_MODE_0; - } else { - ctrl |= ME4600_AO_CTRL_BIT_MODE_1; - } - - PDEBUG("Preload word = 0x%X.\n", inl(instance->preload_reg)); - - PDEBUG("Ctrl word = 0x%lX.\n", ctrl); - outl(ctrl, instance->ctrl_reg); // Write the control word - -ERROR: - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - long j; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - *count = 0; - - ME_SUBDEVICE_ENTER; - - if (t) { - j = jiffies; - wait_event_interruptible_timeout(instance->wait_queue, - ((me_circ_buf_space - (&instance->circ_buf)) - || !(inl(instance->status_reg) - & - ME4600_AO_STATUS_BIT_FSM)), - t); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PERROR("AO subdevice is not running.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - } else if (signal_pending(current)) { - PERROR("Wait on values interrupted from signal.\n"); - err = ME_ERRNO_SIGNAL; - } else if ((jiffies - j) >= t) { - PERROR("Wait on values timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } else { - *count = me_circ_buf_space(&instance->circ_buf); - } - } else { - wait_event_interruptible(instance->wait_queue, - ((me_circ_buf_space - (&instance->circ_buf)) - || !(inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM))); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PERROR("AO subdevice is not running.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - } else if (signal_pending(current)) { - PERROR("Wait on values interrupted from signal.\n"); - err = ME_ERRNO_SIGNAL; - } else { - *count = me_circ_buf_space(&instance->circ_buf); - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static void stop_immediately(me4600_ao_subdevice_t *instance) -{ - unsigned long cpu_flags; - uint32_t tmp; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - - while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ; - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); -} - -static int me4600_ao_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags = 0; - unsigned long ref; - unsigned long tmp; - unsigned long delay = 0; - wait_queue_head_t queue; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - init_waitqueue_head(&queue); - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - ME_SUBDEVICE_ENTER - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - tmp = inl(instance->ctrl_reg); - - switch (tmp & (ME4600_AO_CTRL_MASK_MODE)) { - - case 0: // Single mode - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - PERROR("Subdevice is configured in single mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - - case 1: // Wraparound mode - if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Normal wraparound with external trigger - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (start_mode == ME_START_MODE_BLOCKING) { - init_waitqueue_head(&queue); - - if (delay) { - ref = jiffies; - - while (! - (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending(current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (((jiffies - ref) >= delay)) { - PERROR - ("Timeout reached.\n"); - stop_immediately - (instance); - err = ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } else { - while (! - (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending(current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - } - } - } else if (start_mode == ME_START_MODE_NONBLOCKING) { - } else { - PERROR("Invalid start mode specified.\n"); - err = ME_ERRNO_INVALID_START_MODE; - goto ERROR; - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG; - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - - if (start_mode == ME_START_MODE_BLOCKING) { - init_waitqueue_head(&queue); - - if (delay) { - ref = jiffies; - - while (! - (inl - (instance-> - status_reg) & - ME4600_AO_STATUS_BIT_FSM)) - { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending - (current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (((jiffies - ref) >= - delay)) { - PERROR - ("Timeout reached.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } else { - while (! - (inl - (instance-> - status_reg) & - ME4600_AO_STATUS_BIT_FSM)) - { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending - (current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_SIGNAL; - goto ERROR; - } - } - } - } else if (start_mode == - ME_START_MODE_NONBLOCKING) { - } else { - PERROR - ("Invalid start mode specified.\n"); - err = ME_ERRNO_INVALID_START_MODE; - goto ERROR; - } - } else { - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - - outl(tmp, instance->ctrl_reg); - - if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - outl(0x8000, instance->single_reg); - instance->single_value = 0x8000; - } - - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } else { // Software start - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ | - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - - outl(tmp, instance->ctrl_reg); - - outl(0x8000, instance->single_reg); - instance->single_value = 0x8000; - - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - - break; - - case 2: // Continuous mode - if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) { // Externally triggered - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - instance->wrap_remaining = instance->wrap_count; - instance->circ_buf.tail = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (start_mode == ME_START_MODE_BLOCKING) { - init_waitqueue_head(&queue); - - if (delay) { - ref = jiffies; - - while (! - (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending(current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (((jiffies - ref) >= delay)) { - PERROR - ("Timeout reached.\n"); - stop_immediately - (instance); - err = ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } else { - while (! - (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending(current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - } - } - } else if (start_mode == ME_START_MODE_NONBLOCKING) { - /* Do nothing */ - } else { - PERROR("Invalid start mode specified.\n"); - stop_immediately(instance); - err = ME_ERRNO_INVALID_START_MODE; - goto ERROR; - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) { // Synchronous with external trigger - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - tmp |= - ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG | - ME4600_AO_CTRL_BIT_ENABLE_IRQ; - tmp &= - ~(ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, instance->ctrl_reg); - instance->wrap_remaining = instance->wrap_count; - instance->circ_buf.tail = 0; - - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - - if (start_mode == ME_START_MODE_BLOCKING) { - init_waitqueue_head(&queue); - - if (delay) { - ref = jiffies; - - while (! - (inl - (instance-> - status_reg) & - ME4600_AO_STATUS_BIT_FSM)) - { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending - (current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_SIGNAL; - goto ERROR; - } - - if (((jiffies - ref) >= - delay)) { - PERROR - ("Timeout reached.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_TIMEOUT; - goto ERROR; - } - } - } else { - while (! - (inl - (instance-> - status_reg) & - ME4600_AO_STATUS_BIT_FSM)) - { - interruptible_sleep_on_timeout - (&queue, 1); - - if (signal_pending - (current)) { - PERROR - ("Wait on start of state machine interrupted.\n"); - stop_immediately - (instance); - err = - ME_ERRNO_SIGNAL; - goto ERROR; - } - } - } - } else if (start_mode == - ME_START_MODE_NONBLOCKING) { - } else { - PERROR - ("Invalid start mode specified.\n"); - stop_immediately(instance); - err = ME_ERRNO_INVALID_START_MODE; - goto ERROR; - } - } else { - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - tmp &= - ~(ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - outl(tmp, instance->ctrl_reg); - instance->wrap_remaining = instance->wrap_count; - instance->circ_buf.tail = 0; - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - } - } else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) { // Synchronous wraparound with sw trigger - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - instance->wrap_remaining = instance->wrap_count; - instance->circ_buf.tail = 0; - PDEBUG("CTRL Reg = 0x%X.\n", inl(instance->ctrl_reg)); - outl(tmp, instance->ctrl_reg); - - if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - outl(0x8000, instance->single_reg); - instance->single_value = 0x8000; - } - - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } else { // Software start - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR("Conversion is already running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp &= - ~(ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP); - - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - outl(0x8000, instance->single_reg); - instance->single_value = 0x8000; - instance->wrap_remaining = instance->wrap_count; - instance->circ_buf.tail = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - - break; - - default: - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - PERROR("Invalid mode configured.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - -ERROR: - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - wait_queue_head_t queue; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - init_waitqueue_head(&queue); - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - ME_SUBDEVICE_ENTER; - - if (wait == ME_WAIT_NONE) { - *status = - (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ? - ME_STATUS_BUSY : ME_STATUS_IDLE; - *values = me_circ_buf_space(&instance->circ_buf); - } else if (wait == ME_WAIT_IDLE) { - while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) { - interruptible_sleep_on_timeout(&queue, 1); - - if (instance->flags & ME4600_AO_FLAGS_BROKEN_PIPE) { - PERROR("Output stream was interrupted.\n"); - *status = ME_STATUS_ERROR; - err = ME_ERRNO_SUCCESS; - goto ERROR; - } - - if (signal_pending(current)) { - PERROR - ("Wait on state machine interrupted by signal.\n"); - *status = ME_STATUS_INVALID; - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - } - - *status = ME_STATUS_IDLE; - - *values = me_circ_buf_space(&instance->circ_buf); - } else { - PERROR("Invalid wait argument specified.\n"); - *status = ME_STATUS_INVALID; - err = ME_ERRNO_INVALID_WAIT; - goto ERROR; - } - -ERROR: - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me4600_ao_subdevice_t *instance; - unsigned long cpu_flags; - unsigned long tmp; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - ME_SUBDEVICE_ENTER; - - if (stop_mode == ME_STOP_MODE_IMMEDIATE) { - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - tmp = inl(instance->ctrl_reg); - tmp |= - ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - - while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ; - - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) { - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_STOP; - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } else { - PERROR("Invalid stop mode specified.\n"); - err = ME_ERRNO_INVALID_STOP_MODE; - goto ERROR; - } - -ERROR: - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ao_io_stream_write(me_subdevice_t *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me4600_ao_subdevice_t *instance; - unsigned long tmp; - int i; - int value; - int cnt = *count; - int c; - int k; - int ret = 0; - unsigned long cpu_flags = 0; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - if (!instance->fifo) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - ME_SUBDEVICE_ENTER; - - if (*count <= 0) { - PERROR("Invalid count of values specified.\n"); - err = ME_ERRNO_INVALID_VALUE_COUNT; - goto ERROR; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - tmp = inl(instance->ctrl_reg); - - switch (tmp & 0x3) { - - case 1: // Wraparound mode - if (instance->bosch_fw) { // Bosch firmware - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (cnt != 7) { - PERROR - ("Invalid count of values specified. 7 expected.\n"); - err = ME_ERRNO_INVALID_VALUE_COUNT; - goto ERROR; - } - - for (i = 0; i < 7; i++) { - if (get_user(value, values)) { - PERROR - ("Can't copy value from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - if (i == 0) { - /* Maximum voltage */ - value <<= 16; - value |= - inl(instance->reg_base + - 0xD4) & 0xFFFF; - outl(value, instance->reg_base + 0xD4); - } else if (i == 1) { - /* Minimum voltage */ - value &= 0xFFFF; - value |= - inl(instance->reg_base + - 0xD4) & 0xFFFF0000; - outl(value, instance->reg_base + 0xD4); - } else if (i == 2) { - /* Delta up */ - value <<= 16; - value |= - inl(instance->reg_base + - 0xD8) & 0xFFFF; - outl(value, instance->reg_base + 0xD8); - } else if (i == 3) { - /* Delta down */ - value &= 0xFFFF; - value |= - inl(instance->reg_base + - 0xD8) & 0xFFFF0000; - outl(value, instance->reg_base + 0xD8); - } else if (i == 4) { - /* Start value */ - outl(value, instance->reg_base + 0xDC); - } else if (i == 5) { - /* Invert */ - if (value) { - value = inl(instance->ctrl_reg); - value |= 0x100; - outl(value, instance->ctrl_reg); - } else { - value = inl(instance->ctrl_reg); - value &= ~0x100; - outl(value, instance->ctrl_reg); - } - } else if (i == 6) { - /* Timer for positive ramp */ - outl(value, instance->reg_base + 0xE0); - } - - values++; - } - } else { // Normal firmware - PDEBUG("Write for wraparound mode.\n"); - - if (inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR - ("There is already a conversion running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO; - outl(tmp, instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO; - - if ((*count > ME4600_AO_FIFO_COUNT) || - ((instance-> - flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) == - ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) { - tmp &= - ~(ME4600_AO_CTRL_BIT_MODE_0 | - ME4600_AO_CTRL_BIT_MODE_1); - tmp |= ME4600_AO_CTRL_BIT_MODE_1; - } - - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if ((*count <= ME4600_AO_FIFO_COUNT) && - ((instance-> - flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) == - ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) { - for (i = 0; i < *count; i++) { - if (get_user(value, values + i)) { - PERROR - ("Cannot copy value from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - if (instance->ao_idx & 0x1) - value <<= 16; - - outl(value, instance->fifo_reg); - } - } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) && - ((instance-> - flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) - == ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) { - for (i = 0; i < *count; i++) { - if (get_user(value, values + i)) { - PERROR - ("Cannot copy value from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - instance->circ_buf.buf[i] = value; /* Used to hold the values. */ - } - - instance->circ_buf.tail = 0; /* Used as the current read position. */ - instance->circ_buf.head = *count; /* Used as the buffer size. */ - - /* Preload the FIFO. */ - - for (i = 0; i < ME4600_AO_FIFO_COUNT; - i++, instance->circ_buf.tail++) { - if (instance->circ_buf.tail >= - instance->circ_buf.head) - instance->circ_buf.tail = 0; - - if (instance->ao_idx & 0x1) - outl(instance->circ_buf. - buf[instance->circ_buf. - tail] << 16, - instance->fifo_reg); - else - outl(instance->circ_buf. - buf[instance->circ_buf. - tail], - instance->fifo_reg); - } - } else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) && - ((instance-> - flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) - == ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) { - unsigned int preload_count; - - for (i = 0; i < *count; i++) { - if (get_user(value, values + i)) { - PERROR - ("Cannot copy value from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - instance->circ_buf.buf[i] = value; /* Used to hold the values. */ - } - - instance->circ_buf.tail = 0; /* Used as the current read position. */ - instance->circ_buf.head = *count; /* Used as the buffer size. */ - - /* Try to preload the whole FIFO. */ - preload_count = ME4600_AO_FIFO_COUNT; - - if (preload_count > instance->wrap_count) - preload_count = instance->wrap_count; - - /* Preload the FIFO. */ - for (i = 0; i < preload_count; - i++, instance->circ_buf.tail++) { - if (instance->circ_buf.tail >= - instance->circ_buf.head) - instance->circ_buf.tail = 0; - - if (instance->ao_idx & 0x1) - outl(instance->circ_buf. - buf[instance->circ_buf. - tail] << 16, - instance->fifo_reg); - else - outl(instance->circ_buf. - buf[instance->circ_buf. - tail], - instance->fifo_reg); - } - - instance->wrap_remaining = - instance->wrap_count - preload_count; - } else { - PERROR("To many values written.\n"); - err = ME_ERRNO_INVALID_VALUE_COUNT; - goto ERROR; - } - } - - break; - - case 2: // Continuous mode - /* Check if in SW wrapround mode */ - if (instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) { - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - PERROR("Subdevice is configured SW wrapround mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - } - - switch (write_mode) { - - case ME_WRITE_MODE_BLOCKING: - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - PDEBUG("Write for blocking continuous mode.\n"); - - while (cnt > 0) { - wait_event_interruptible(instance->wait_queue, - (c = - me_circ_buf_space_to_end - (&instance-> - circ_buf))); - - if (instance-> - flags & ME4600_AO_FLAGS_BROKEN_PIPE) { - PERROR - ("Broken pipe in blocking write.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - goto ERROR; - } else if (signal_pending(current)) { - PERROR - ("Wait for free buffer interrupted from signal.\n"); - err = ME_ERRNO_SIGNAL; - goto ERROR; - } - - PDEBUG("Space to end = %d.\n", c); - - /* Only able to write size of free buffer or size of count */ - - if (cnt < c) - c = cnt; - k = sizeof(int) * c; - k -= copy_from_user(instance->circ_buf.buf + - instance->circ_buf.head, - values, k); - c = k / sizeof(int); - - PDEBUG("Copy %d values from user space.\n", c); - - if (!c) { - PERROR - ("Cannot copy values from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - instance->circ_buf.head = - (instance->circ_buf.head + - c) & (instance->circ_buf.mask); - - values += c; - cnt -= c; - ret += c; - - /* Values are now available so enable interrupts */ - spin_lock_irqsave(&instance->subdevice_lock, - cpu_flags); - - if (me_circ_buf_space(&instance->circ_buf)) { - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - } - - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - } - - *count = ret; - - break; - - case ME_WRITE_MODE_NONBLOCKING: - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - PDEBUG("Write for non blocking continuous mode.\n"); - - while (cnt > 0) { - if (instance-> - flags & ME4600_AO_FLAGS_BROKEN_PIPE) { - PERROR - ("ME4600:Broken pipe in nonblocking write.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - goto ERROR; - } - - c = me_circ_buf_space_to_end(&instance-> - circ_buf); - - if (!c) { - PDEBUG - ("Returning from nonblocking write.\n"); - break; - } - - PDEBUG("Space to end = %d.\n", c); - - /* Only able to write size of free buffer or size of count */ - - if (cnt < c) - c = cnt; - k = sizeof(int) * c; - k -= copy_from_user(instance->circ_buf.buf + - instance->circ_buf.head, - values, k); - c = k / sizeof(int); - - PDEBUG("Copy %d values from user space.\n", c); - - if (!c) { - PERROR - ("Cannot copy values from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - instance->circ_buf.head = - (instance->circ_buf.head + - c) & (instance->circ_buf.mask); - - values += c; - cnt -= c; - ret += c; - - /* Values are now available so enable interrupts */ - spin_lock_irqsave(&instance->subdevice_lock, - cpu_flags); - - if (me_circ_buf_space(&instance->circ_buf)) { - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - } - - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - } - - *count = ret; - - break; - - case ME_WRITE_MODE_PRELOAD: - PDEBUG("Write for preload continuous mode.\n"); - - if ((inl(instance->status_reg) & - ME4600_AO_STATUS_BIT_FSM)) { - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - PERROR - ("Can't Preload DAC FIFO while conversion is running.\n"); - err = ME_ERRNO_SUBDEVICE_BUSY; - goto ERROR; - } - - tmp = inl(instance->ctrl_reg); - - tmp |= - ME4600_AO_CTRL_BIT_STOP | - ME4600_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(tmp, instance->ctrl_reg); - tmp &= - ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO | - ME4600_AO_CTRL_BIT_ENABLE_IRQ); - outl(tmp, instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO; - outl(tmp, instance->ctrl_reg); - - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - instance->flags &= ~ME4600_AO_FLAGS_BROKEN_PIPE; - - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - c = ME4600_AO_FIFO_COUNT; - - if (cnt < c) - c = cnt; - - for (i = 0; i < c; i++) { - if (get_user(value, values)) { - PERROR - ("Can't copy value from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - if (instance->ao_idx & 0x1) - value <<= 16; - - outl(value, instance->fifo_reg); - - values++; - } - - cnt -= c; - - ret += c; - - PDEBUG("Wrote %d values to fifo.\n", c); - - while (1) { - c = me_circ_buf_space_to_end(&instance-> - circ_buf); - - if (c == 0) - break; - - if (cnt < c) - c = cnt; - - if (c <= 0) - break; - - k = sizeof(int) * c; - - k -= copy_from_user(instance->circ_buf.buf + - instance->circ_buf.head, - values, k); - - c = k / sizeof(int); - - PDEBUG("Wrote %d values to circular buffer.\n", - c); - - if (!c) { - PERROR - ("Can't copy values from user space.\n"); - err = ME_ERRNO_INTERNAL; - goto ERROR; - } - - instance->circ_buf.head = - (instance->circ_buf.head + - c) & (instance->circ_buf.mask); - - values += c; - cnt -= c; - ret += c; - } - - *count = ret; - - break; - - default: - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - PERROR("Invalid write mode specified.\n"); - - err = ME_ERRNO_INVALID_WRITE_MODE; - - goto ERROR; - } - - break; - - default: // Single mode of invalid - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - PERROR("Subdevice is configured in single mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - goto ERROR; - } - -ERROR: - - ME_SUBDEVICE_EXIT; - - return err; -} - -static irqreturn_t me4600_ao_isr(int irq, void *dev_id) -{ - unsigned long tmp; - int value; - me4600_ao_subdevice_t *instance = dev_id; - int i; - int c = 0; - int c1 = 0; - - if (irq != instance->irq) { - PDEBUG("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - if (!((0x1 << (instance->ao_idx + 3)) & inl(instance->irq_status_reg))) { - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - tmp = inl(instance->status_reg); - - if (!(tmp & ME4600_AO_STATUS_BIT_EF) && - (tmp & ME4600_AO_STATUS_BIT_HF) && - (tmp & ME4600_AO_STATUS_BIT_HF)) { - c = ME4600_AO_FIFO_COUNT; - PDEBUG("Fifo empty.\n"); - } else if ((tmp & ME4600_AO_STATUS_BIT_EF) && - (tmp & ME4600_AO_STATUS_BIT_HF) && - (tmp & ME4600_AO_STATUS_BIT_HF)) { - c = ME4600_AO_FIFO_COUNT / 2; - PDEBUG("Fifo under half full.\n"); - } else { - c = 0; - PDEBUG("Fifo full.\n"); - } - - PDEBUG("Try to write 0x%04X values.\n", c); - - if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) == - ME4600_AO_FLAGS_SW_WRAP_MODE_INF) { - while (c) { - c1 = c; - - if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */ - c1 = (instance->circ_buf.head - - instance->circ_buf.tail); - - /* Write the values to the FIFO */ - for (i = 0; i < c1; i++, instance->circ_buf.tail++, c--) { - if (instance->ao_idx & 0x1) - outl(instance->circ_buf. - buf[instance->circ_buf.tail] << 16, - instance->fifo_reg); - else - outl(instance->circ_buf. - buf[instance->circ_buf.tail], - instance->fifo_reg); - } - - if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */ - instance->circ_buf.tail = 0; - } - - spin_lock(&instance->subdevice_lock); - - tmp = inl(instance->ctrl_reg); - tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(tmp, instance->ctrl_reg); - tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(tmp, instance->ctrl_reg); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PERROR("Broken pipe.\n"); - instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE; - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - } - - spin_unlock(&instance->subdevice_lock); - } else if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) == - ME4600_AO_FLAGS_SW_WRAP_MODE_FIN) { - while (c && instance->wrap_remaining) { - c1 = c; - - if (c1 > (instance->circ_buf.head - instance->circ_buf.tail)) /* Only up to the end of the buffer */ - c1 = (instance->circ_buf.head - - instance->circ_buf.tail); - - if (c1 > instance->wrap_remaining) /* Only up to count of user defined number of values */ - c1 = instance->wrap_remaining; - - /* Write the values to the FIFO */ - for (i = 0; i < c1; - i++, instance->circ_buf.tail++, c--, - instance->wrap_remaining--) { - if (instance->ao_idx & 0x1) - outl(instance->circ_buf. - buf[instance->circ_buf.tail] << 16, - instance->fifo_reg); - else - outl(instance->circ_buf. - buf[instance->circ_buf.tail], - instance->fifo_reg); - } - - if (instance->circ_buf.tail >= instance->circ_buf.head) /* Start from beginning */ - instance->circ_buf.tail = 0; - } - - spin_lock(&instance->subdevice_lock); - - tmp = inl(instance->ctrl_reg); - - if (!instance->wrap_remaining) { - PDEBUG("Finite SW wraparound done.\n"); - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - } - - tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ; - - outl(tmp, instance->ctrl_reg); - tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(tmp, instance->ctrl_reg); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PERROR("Broken pipe.\n"); - instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE; - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - } - - spin_unlock(&instance->subdevice_lock); - - } else { /* Regular continuous mode */ - - while (1) { - c1 = me_circ_buf_values_to_end(&instance->circ_buf); - PDEBUG("Values to end = %d.\n", c1); - - if (c1 > c) - c1 = c; - - if (c1 <= 0) { - PDEBUG("Work done or buffer empty.\n"); - break; - } - - if (instance->ao_idx & 0x1) { - for (i = 0; i < c1; i++) { - value = - *(instance->circ_buf.buf + - instance->circ_buf.tail + - i) << 16; - outl(value, instance->fifo_reg); - } - } else - outsl(instance->fifo_reg, - instance->circ_buf.buf + - instance->circ_buf.tail, c1); - - instance->circ_buf.tail = - (instance->circ_buf.tail + - c1) & (instance->circ_buf.mask); - - PDEBUG("%d values wrote to port 0x%04X.\n", c1, - instance->fifo_reg); - - c -= c1; - } - - spin_lock(&instance->subdevice_lock); - - tmp = inl(instance->ctrl_reg); - - if (!me_circ_buf_values(&instance->circ_buf)) { - PDEBUG - ("Disable Interrupt because no values left in buffer.\n"); - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - } - - tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ; - - outl(tmp, instance->ctrl_reg); - tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ; - outl(tmp, instance->ctrl_reg); - - if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) { - PDEBUG("Broken pipe in me4600_ao_isr.\n"); - instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE; - tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ; - outl(tmp, instance->ctrl_reg); - } - - spin_unlock(&instance->subdevice_lock); - - wake_up_interruptible(&instance->wait_queue); - } - - return IRQ_HANDLED; -} - -static void me4600_ao_destructor(struct me_subdevice *subdevice) -{ - me4600_ao_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me4600_ao_subdevice_t *) subdevice; - - free_irq(instance->irq, instance); - kfree(instance->circ_buf.buf); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base, - spinlock_t *preload_reg_lock, - uint32_t *preload_flags, - int ao_idx, int fifo, int irq) -{ - me4600_ao_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_ao_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->preload_reg_lock = preload_reg_lock; - subdevice->preload_flags = preload_flags; - - /* Allocate and initialize circular buffer */ - subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1; - subdevice->circ_buf.buf = kmalloc(ME4600_AO_CIRC_BUF_SIZE, GFP_KERNEL); - - if (!subdevice->circ_buf.buf) { - PERROR("Cannot initialize subdevice base class instance.\n"); - me_subdevice_deinit((me_subdevice_t *) subdevice); - kfree(subdevice); - return NULL; - } - - memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE); - - subdevice->circ_buf.head = 0; - subdevice->circ_buf.tail = 0; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Initialize single value to 0V */ - subdevice->single_value = 0x8000; - - /* Store analog output index */ - subdevice->ao_idx = ao_idx; - - /* Store if analog output has fifo */ - subdevice->fifo = fifo; - - /* Initialize registers */ - - if (ao_idx == 0) { - subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG; - subdevice->reg_base = reg_base; - - if (inl(subdevice->reg_base + ME4600_AO_BOSCH_REG) == 0x20000) { - PINFO("Bosch firmware in use for channel 0.\n"); - subdevice->bosch_fw = 1; - } else { - subdevice->bosch_fw = 0; - } - } else if (ao_idx == 1) { - subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bosch_fw = 0; - } else if (ao_idx == 2) { - subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bosch_fw = 0; - } else { - subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG; - subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG; - subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG; - subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG; - subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG; - subdevice->reg_base = reg_base; - subdevice->bosch_fw = 0; - } - - subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG; - subdevice->preload_reg = reg_base + ME4600_AO_LOADSETREG_XX; - - /* Register interrupt service routine */ - subdevice->irq = irq; - - if (request_irq - (subdevice->irq, me4600_ao_isr, IRQF_DISABLED | IRQF_SHARED, - ME4600_NAME, subdevice)) { - PERROR("Cannot get interrupt line.\n"); - me_subdevice_deinit((me_subdevice_t *) subdevice); - kfree(subdevice->circ_buf.buf); - kfree(subdevice); - return NULL; - } - - /* Override base class methods. */ - subdevice->base.me_subdevice_destructor = me4600_ao_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_ao_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_ao_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me4600_ao_io_single_write; - subdevice->base.me_subdevice_io_stream_config = - me4600_ao_io_stream_config; - subdevice->base.me_subdevice_io_stream_new_values = - me4600_ao_io_stream_new_values; - subdevice->base.me_subdevice_io_stream_write = - me4600_ao_io_stream_write; - subdevice->base.me_subdevice_io_stream_start = - me4600_ao_io_stream_start; - subdevice->base.me_subdevice_io_stream_status = - me4600_ao_io_stream_status; - subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop; - subdevice->base.me_subdevice_query_number_channels = - me4600_ao_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_ao_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_ao_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me4600_ao_query_subdevice_caps_args; - subdevice->base.me_subdevice_query_range_by_min_max = - me4600_ao_query_range_by_min_max; - subdevice->base.me_subdevice_query_number_ranges = - me4600_ao_query_number_ranges; - subdevice->base.me_subdevice_query_range_info = - me4600_ao_query_range_info; - subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer; - - return subdevice; -} - -#endif // BOSCH - -/* Common functions -*/ - -static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((*max - *min) < 0) { - PERROR("Invalid minimum and maximum values specified.\n"); - return ME_ERRNO_INVALID_MIN_MAX; - } - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - if ((*max <= (ME4600_AO_MAX_RANGE + 1000)) - && (*min >= ME4600_AO_MIN_RANGE)) { - *min = ME4600_AO_MIN_RANGE; - *max = ME4600_AO_MAX_RANGE; - *maxdata = ME4600_AO_MAX_DATA; - *range = 0; - } else { - PERROR("No matching range available.\n"); - return ME_ERRNO_NO_RANGE; - } - } else { - PERROR("Invalid physical unit specified.\n"); - return ME_ERRNO_INVALID_UNIT; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - *count = 1; - } else { - *count = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (range == 0) { - *unit = ME_UNIT_VOLT; - *min = ME4600_AO_MIN_RANGE; - *max = ME4600_AO_MAX_RANGE; - *maxdata = ME4600_AO_MAX_DATA; - } else { - PERROR("Invalid range number specified.\n"); - return ME_ERRNO_INVALID_RANGE; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((timer != ME_TIMER_ACQ_START) && (timer != ME_TIMER_CONV_START)) { - PERROR("Invalid timer specified.\n"); - return ME_ERRNO_INVALID_TIMER; - } - - if (instance->fifo) { //Streaming device. - *base_frequency = ME4600_AO_BASE_FREQUENCY; - if (timer == ME_TIMER_ACQ_START) { - *min_ticks = ME4600_AO_MIN_ACQ_TICKS; - *max_ticks = ME4600_AO_MAX_ACQ_TICKS; - } else if (timer == ME_TIMER_CONV_START) { - *min_ticks = ME4600_AO_MIN_CHAN_TICKS; - *max_ticks = ME4600_AO_MAX_CHAN_TICKS; - } - } else { //Not streaming device! - *base_frequency = 0; - *min_ticks = 0; - *max_ticks = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - me4600_ao_subdevice_t *instance; - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *number = 1; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - me4600_ao_subdevice_t *instance; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *type = ME_TYPE_AO; - *subtype = (instance->fifo) ? ME_SUBTYPE_STREAMING : ME_SUBTYPE_SINGLE; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - me4600_ao_subdevice_t *instance; - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *caps = - ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO : - ME_CAPS_NONE); - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count) -{ - me4600_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - instance = (me4600_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (count != 1) { - PERROR("Invalid capability argument count.\n"); - return ME_ERRNO_INVALID_CAP_ARG_COUNT; - } - - switch (cap) { - case ME_CAP_AI_FIFO_SIZE: - args[0] = (instance->fifo) ? ME4600_AO_FIFO_COUNT : 0; - break; - - case ME_CAP_AI_BUFFER_SIZE: - args[0] = - (instance->circ_buf.buf) ? ME4600_AO_CIRC_BUF_COUNT : 0; - break; - - default: - PERROR("Invalid capability.\n"); - err = ME_ERRNO_INVALID_CAP; - args[0] = 0; - } - - return err; -} diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h deleted file mode 100644 index 7579435adc6..00000000000 --- a/drivers/staging/meilhaus/me4600_ao.h +++ /dev/null @@ -1,259 +0,0 @@ -/** - * @file me4600_ao.h - * - * @brief Meilhaus ME-4000 analog output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_AO_H_ -# define _ME4600_AO_H_ - -# include -# include "mesubdevice.h" -# include "mecirc_buf.h" -# include "meioctl.h" - -# ifdef __KERNEL__ - -# ifdef BOSCH -# undef ME_SYNAPSE -# ifndef _CBUFF_32b_t -# define _CBUFF_32b_t -# endif //_CBUFF_32b_t -# endif //BOSCH - -# define ME4600_AO_MAX_SUBDEVICES 4 -# define ME4600_AO_FIFO_COUNT 4096 - -# define ME4600_AO_BASE_FREQUENCY 33000000LL - -# define ME4600_AO_MIN_ACQ_TICKS 0LL -# define ME4600_AO_MAX_ACQ_TICKS 0LL - -# define ME4600_AO_MIN_CHAN_TICKS 66LL -# define ME4600_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL - -# define ME4600_AO_MIN_RANGE -10000000 -# define ME4600_AO_MAX_RANGE 9999694 - -# define ME4600_AO_MAX_DATA 0xFFFF - -# ifdef ME_SYNAPSE -# define ME4600_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse -# else -# define ME4600_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB -# endif -# define ME4600_AO_CIRC_BUF_SIZE PAGE_SIZE< Now problems are reported in status. - -typedef enum ME4600_AO_STATUS { - ao_status_none = 0, - ao_status_single_configured, - ao_status_single_run_wait, - ao_status_single_run, - ao_status_single_end_wait, - ao_status_single_end, - ao_status_stream_configured, - ao_status_stream_run_wait, - ao_status_stream_run, - ao_status_stream_end_wait, - ao_status_stream_end, - ao_status_stream_fifo_error, - ao_status_stream_buffer_error, - ao_status_stream_error, - ao_status_last -} ME4600_AO_STATUS; - -typedef struct me4600_ao_timeout { - unsigned long start_time; - unsigned long delay; -} me4600_ao_timeout_t; - - /** - * @brief The ME-4600 analog output subdevice class. - */ -typedef struct me4600_ao_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - unsigned int ao_idx; /**< The index of this analog output on this device. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */ - - uint32_t *preload_flags; - - /* Hardware feautres */ - unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */ - int fifo; /**< If set this device has a FIFO. */ - int bitpattern; /**< If set this device use bitpattern. */ - - int single_value; /**< Mirror of the output value in single mode. */ - int single_value_in_fifo; /**< Mirror of the value written in single mode. */ - uint32_t ctrl_trg; /**< Mirror of the trigger settings. */ - - volatile int mode; /**< Flags used for storing SW wraparound setup*/ - int stop_mode; /**< The user defined stop condition flag. */ - unsigned int start_mode; - unsigned int stop_count; /**< The user defined dates presentation end count. */ - unsigned int stop_data_count; /**< The stop presentation count. */ - unsigned int data_count; /**< The real presentation count. */ - unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */ - int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */ - - volatile enum ME4600_AO_STATUS status; /**< The current stream status flag. */ - me4600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */ - - /* Registers *//**< All registers are 32 bits long. */ - unsigned long ctrl_reg; - unsigned long status_reg; - unsigned long fifo_reg; - unsigned long single_reg; - unsigned long timer_reg; - unsigned long irq_status_reg; - unsigned long preload_reg; - unsigned long reg_base; - - /* Software buffer */ - me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. 32 bit long */ - wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */ - - struct workqueue_struct *me4600_workqueue; - struct delayed_work ao_control_task; - - volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */ - -} me4600_ao_subdevice_t; - - /** - * @brief The constructor to generate a ME-4600 analog output subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access. - * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access. - * @param ao_idx Subdevice number. - * @param fifo Flag set if subdevice has hardware FIFO. - * @param irq IRQ number. - * @param me4600_wq Queue for asynchronous task (1 queue for all subdevice on 1 board). - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base, - spinlock_t * preload_reg_lock, - uint32_t * preload_flags, - int ao_idx, - int fifo, - int irq, - struct workqueue_struct - *me4600_wq); - -# endif //BOSCH -# endif //__KERNEL__ -#endif // ~_ME4600_AO_H_ diff --git a/drivers/staging/meilhaus/me4600_ao_reg.h b/drivers/staging/meilhaus/me4600_ao_reg.h deleted file mode 100644 index f83d82ecd4b..00000000000 --- a/drivers/staging/meilhaus/me4600_ao_reg.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file me4600_ao_reg.h - * - * @brief ME-4000 analog output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_AO_REG_H_ -#define _ME4600_AO_REG_H_ - -#ifdef __KERNEL__ - -#define ME4600_AO_00_CTRL_REG 0x00 // R/W -#define ME4600_AO_00_STATUS_REG 0x04 // R/_ -#define ME4600_AO_00_FIFO_REG 0x08 // _/W -#define ME4600_AO_00_SINGLE_REG 0x0C // R/W -#define ME4600_AO_00_TIMER_REG 0x10 // _/W - -#define ME4600_AO_01_CTRL_REG 0x18 // R/W -#define ME4600_AO_01_STATUS_REG 0x1C // R/_ -#define ME4600_AO_01_FIFO_REG 0x20 // _/W -#define ME4600_AO_01_SINGLE_REG 0x24 // R/W -#define ME4600_AO_01_TIMER_REG 0x28 // _/W - -#define ME4600_AO_02_CTRL_REG 0x30 // R/W -#define ME4600_AO_02_STATUS_REG 0x34 // R/_ -#define ME4600_AO_02_FIFO_REG 0x38 // _/W -#define ME4600_AO_02_SINGLE_REG 0x3C // R/W -#define ME4600_AO_02_TIMER_REG 0x40 // _/W - -#define ME4600_AO_03_CTRL_REG 0x48 // R/W -#define ME4600_AO_03_STATUS_REG 0x4C // R/_ -#define ME4600_AO_03_FIFO_REG 0x50 // _/W -#define ME4600_AO_03_SINGLE_REG 0x54 // R/W -#define ME4600_AO_03_TIMER_REG 0x58 // _/W - -#define ME4600_AO_DEMUX_ADJUST_REG 0xBC // -/W -#define ME4600_AO_DEMUX_ADJUST_VALUE 0x4C - -#ifdef BOSCH -# define ME4600_AO_BOSCH_REG 0xC4 - -# define ME4600_AO_LOADSETREG_XX 0xB4 // R/W - -# define ME4600_AO_CTRL_BIT_MODE_0 0x001 -# define ME4600_AO_CTRL_BIT_MODE_1 0x002 -# define ME4600_AO_CTRL_MASK_MODE 0x003 - -#else //~BOSCH - -#define ME4600_AO_SYNC_REG 0xB4 // R/W ///ME4600_AO_SYNC_REG <==> ME4600_AO_PRELOAD_REG <==> ME4600_AO_LOADSETREG_XX - -# define ME4600_AO_MODE_SINGLE 0x00000000 -# define ME4600_AO_MODE_WRAPAROUND 0x00000001 -# define ME4600_AO_MODE_CONTINUOUS 0x00000002 -# define ME4600_AO_CTRL_MODE_MASK (ME4600_AO_MODE_WRAPAROUND | ME4600_AO_MODE_CONTINUOUS) -#endif //BOSCH - -#define ME4600_AO_CTRL_BIT_MODE_WRAPAROUND ME4600_AO_MODE_WRAPAROUND -#define ME4600_AO_CTRL_BIT_MODE_CONTINOUS ME4600_AO_MODE_CONTINUOUS -#define ME4600_AO_CTRL_BIT_STOP 0x00000004 -#define ME4600_AO_CTRL_BIT_ENABLE_FIFO 0x00000008 -#define ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG 0x00000010 -#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE 0x00000020 -#define ME4600_AO_CTRL_BIT_IMMEDIATE_STOP 0x00000080 -#define ME4600_AO_CTRL_BIT_ENABLE_DO 0x00000100 -#define ME4600_AO_CTRL_BIT_ENABLE_IRQ 0x00000200 -#define ME4600_AO_CTRL_BIT_RESET_IRQ 0x00000400 -#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x00000800 -/* -#define ME4600_AO_SYNC_HOLD_0 0x00000001 -#define ME4600_AO_SYNC_HOLD_1 0x00000002 -#define ME4600_AO_SYNC_HOLD_2 0x00000004 -#define ME4600_AO_SYNC_HOLD_3 0x00000008 -*/ -#define ME4600_AO_SYNC_HOLD 0x00000001 - -/* -#define ME4600_AO_SYNC_EXT_TRIG_0 0x00010000 -#define ME4600_AO_SYNC_EXT_TRIG_1 0x00020000 -#define ME4600_AO_SYNC_EXT_TRIG_2 0x00040000 -#define ME4600_AO_SYNC_EXT_TRIG_3 0x00080000 -*/ -#define ME4600_AO_SYNC_EXT_TRIG 0x00010000 - -#define ME4600_AO_EXT_TRIG 0x80000000 - -#define ME4600_AO_STATUS_BIT_FSM 0x00000001 -#define ME4600_AO_STATUS_BIT_FF 0x00000002 -#define ME4600_AO_STATUS_BIT_HF 0x00000004 -#define ME4600_AO_STATUS_BIT_EF 0x00000008 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c deleted file mode 100644 index 457666ef61a..00000000000 --- a/drivers/staging/meilhaus/me4600_device.c +++ /dev/null @@ -1,371 +0,0 @@ -/** - * @file me4600_device.c - * - * @brief ME-4600 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "me4600_device.h" -#include "meplx_reg.h" - -#include "mefirmware.h" - -#include "mesubdevice.h" -#include "me4600_do.h" -#include "me4600_di.h" -#include "me4600_dio.h" -#include "me8254.h" -#include "me4600_ai.h" -#include "me4600_ao.h" -#include "me4600_ext_irq.h" - -/** - * @brief Global variable. - * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts). - */ -static struct workqueue_struct *me4600_workqueue; - -#ifdef BOSCH -me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw) -#else //~BOSCH -me_device_t *me4600_pci_constructor(struct pci_dev *pci_device) -#endif //BOSCH -{ - me4600_device_t *me4600_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me4600_device = kmalloc(sizeof(me4600_device_t), GFP_KERNEL); - - if (!me4600_device) { - PERROR("Cannot get memory for ME-4600 device instance.\n"); - return NULL; - } - - memset(me4600_device, 0, sizeof(me4600_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me4600_device, pci_device); - - if (err) { - kfree(me4600_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - // Download the xilinx firmware. - if (me4600_device->base.info.pci.device_id == PCI_DEVICE_ID_MEILHAUS_ME4610) { //Jekyll <=> me4610 - err = - me_xilinx_download(me4600_device->base.info.pci. - reg_bases[1], - me4600_device->base.info.pci. - reg_bases[5], &pci_device->dev, - "me4610.bin"); - } else { // General me4600 firmware -#ifdef BOSCH - err = - me_xilinx_download(me4600_device->base.info.pci. - reg_bases[1], - me4600_device->base.info.pci. - reg_bases[5], &pci_device->dev, - (me_bosch_fw) ? "me4600_bosch.bin" : - "me4600.bin"); -#else //~BOSCH - err = - me_xilinx_download(me4600_device->base.info.pci. - reg_bases[1], - me4600_device->base.info.pci. - reg_bases[5], &pci_device->dev, - "me4600.bin"); -#endif - } - - if (err) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot download firmware.\n"); - return NULL; - } - // Get the index in the device version information table. - version_idx = - me4600_versions_get_device_index(me4600_device->base.info.pci. - device_id); - - // Initialize spin locks. - spin_lock_init(&me4600_device->preload_reg_lock); - - me4600_device->preload_flags = 0; - - spin_lock_init(&me4600_device->dio_lock); - spin_lock_init(&me4600_device->ai_ctrl_lock); - spin_lock_init(&me4600_device->ctr_ctrl_reg_lock); - spin_lock_init(&me4600_device->ctr_clk_src_reg_lock); - - // Create digital input instances. - for (i = 0; i < me4600_versions[version_idx].di_subdevices; i++) { - subdevice = - (me_subdevice_t *) me4600_di_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - &me4600_device-> - dio_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create digital output instances. - for (i = 0; i < me4600_versions[version_idx].do_subdevices; i++) { - subdevice = - (me_subdevice_t *) me4600_do_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - &me4600_device-> - dio_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create digital input/output instances. - for (i = 0; i < me4600_versions[version_idx].dio_subdevices; i++) { - subdevice = - (me_subdevice_t *) me4600_dio_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - me4600_versions - [version_idx]. - do_subdevices + - me4600_versions - [version_idx]. - di_subdevices + i, - &me4600_device-> - dio_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create analog input instances. - for (i = 0; i < me4600_versions[version_idx].ai_subdevices; i++) { - subdevice = - (me_subdevice_t *) me4600_ai_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - me4600_versions - [version_idx]. - ai_channels, - me4600_versions - [version_idx]. - ai_ranges, - me4600_versions - [version_idx]. - ai_isolated, - me4600_versions - [version_idx]. - ai_sh, - me4600_device-> - base.irq, - &me4600_device-> - ai_ctrl_lock, - me4600_workqueue); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create analog output instances. - for (i = 0; i < me4600_versions[version_idx].ao_subdevices; i++) { -#ifdef BOSCH - subdevice = - (me_subdevice_t *) me4600_ao_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - &me4600_device-> - preload_reg_lock, - &me4600_device-> - preload_flags, i, - me4600_versions - [version_idx]. - ao_fifo, - me4600_device-> - base.irq); -#else //~BOSCH - subdevice = - (me_subdevice_t *) me4600_ao_constructor(me4600_device-> - base.info.pci. - reg_bases[2], - &me4600_device-> - preload_reg_lock, - &me4600_device-> - preload_flags, i, - me4600_versions - [version_idx]. - ao_fifo, - me4600_device-> - base.irq, - me4600_workqueue); -#endif - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create counter instances. - for (i = 0; i < me4600_versions[version_idx].ctr_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8254_constructor(me4600_device->base. - info.pci.device_id, - me4600_device->base. - info.pci.reg_bases[3], - 0, i, - &me4600_device-> - ctr_ctrl_reg_lock, - &me4600_device-> - ctr_clk_src_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - // Create external interrupt instances. - for (i = 0; i < me4600_versions[version_idx].ext_irq_subdevices; i++) { - subdevice = - (me_subdevice_t *) - me4600_ext_irq_constructor(me4600_device->base.info.pci. - reg_bases[2], - me4600_device->base.irq, - &me4600_device->ai_ctrl_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me4600_device); - kfree(me4600_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me4600_device->base.slist, - subdevice); - } - - return (me_device_t *) me4600_device; -} -EXPORT_SYMBOL(me4600_pci_constructor); - -// Init and exit of module. - -static int __init me4600_init(void) -{ - PDEBUG("executed.\n"); - -#ifndef BOSCH - me4600_workqueue = create_singlethread_workqueue("me4600"); -#endif - return 0; -} - -static void __exit me4600_exit(void) -{ - PDEBUG("executed.\n"); - -#ifndef BOSCH - flush_workqueue(me4600_workqueue); - destroy_workqueue(me4600_workqueue); -#endif -} - -module_init(me4600_init); -module_exit(me4600_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me4600_device.h b/drivers/staging/meilhaus/me4600_device.h deleted file mode 100644 index c755c574cda..00000000000 --- a/drivers/staging/meilhaus/me4600_device.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @file me4600_device.h - * - * @brief ME-4600 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_DEVICE_H -#define _ME4600_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-4600 device capabilities. - */ -typedef struct me4600_version { - uint16_t device_id; - unsigned int do_subdevices; - unsigned int di_subdevices; - unsigned int dio_subdevices; - unsigned int ctr_subdevices; - unsigned int ai_subdevices; - unsigned int ai_channels; - unsigned int ai_ranges; - unsigned int ai_isolated; - unsigned int ai_sh; - unsigned int ao_subdevices; - unsigned int ao_fifo; //How many devices have FIFO - unsigned int ext_irq_subdevices; -} me4600_version_t; - -/** - * @brief ME-4600 device capabilities. - */ -static me4600_version_t me4600_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME4610, 0, 0, 4, 3, 1, 16, 1, 0, 0, 0, 0, 1}, - - {PCI_DEVICE_ID_MEILHAUS_ME4650, 0, 0, 4, 0, 1, 16, 4, 0, 0, 0, 0, 1}, - - {PCI_DEVICE_ID_MEILHAUS_ME4660, 0, 0, 4, 3, 1, 16, 4, 0, 0, 2, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4660I, 1, 1, 2, 3, 1, 16, 4, 1, 0, 2, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4660S, 0, 0, 4, 3, 1, 16, 4, 0, 1, 2, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4660IS, 1, 1, 2, 3, 1, 16, 4, 1, 1, 2, 0, 1}, - - {PCI_DEVICE_ID_MEILHAUS_ME4670, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4670I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4670S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 0, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4670IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 0, 1}, - - {PCI_DEVICE_ID_MEILHAUS_ME4680, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 4, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4680I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 4, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4680S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 4, 1}, - {PCI_DEVICE_ID_MEILHAUS_ME4680IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 4, 1}, - - {0}, -}; - -#define ME4600_DEVICE_VERSIONS (ARRAY_SIZE(me4600_versions) - 1) /**< Returns the number of entries in #me4600_versions. */ - -/** - * @brief Returns the index of the device entry in #me4600_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me4600_versions. - */ -static inline unsigned int me4600_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME4600_DEVICE_VERSIONS; i++) - if (me4600_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-4600 device class structure. - */ -typedef struct me4600_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t preload_reg_lock; /**< Guards the preload register of the anaolog output devices. */ - unsigned int preload_flags; /**< Used in conjunction with #preload_reg_lock. */ - spinlock_t dio_lock; /**< Locks the control register of the digital input/output subdevices. */ - spinlock_t ai_ctrl_lock; /**< Locks the control register of the analog input subdevice. */ - spinlock_t ctr_ctrl_reg_lock; /**< Locks the counter control register. */ - spinlock_t ctr_clk_src_reg_lock; /**< Not used on this device but needed for the me8254 subdevice constructor call. */ -} me4600_device_t; - -/** - * @brief The ME-4600 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * @param me_bosch_fw If set the device shall use the bosch firmware. (Only for special BOSCH build) - * - * @return On succes a new ME-4600 device instance. \n - * NULL on error. - */ - -#ifdef BOSCH -/** - * @brief The ME-4600 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * @param me_bosch_fw If set the device shall use the bosch firmware. - * - * @return On succes a new ME-4600 device instance. \n - * NULL on error. - */ -me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw) - __attribute__ ((weak)); -#else //~BOSCH -/** - * @brief The ME-4600 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-4600 device instance. \n - * NULL on error. - */ -me_device_t *me4600_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); -#endif - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c deleted file mode 100644 index e107e506138..00000000000 --- a/drivers/staging/meilhaus/me4600_di.c +++ /dev/null @@ -1,256 +0,0 @@ -/** - * @file me4600_di.c - * - * @brief ME-4000 digital input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me4600_dio_reg.h" -#include "me4600_di.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me4600_di_subdevice_t *instance; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_di_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inl(instance->ctrl_reg); - mode &= ~(ME4600_DIO_CTRL_BIT_MODE_2 | ME4600_DIO_CTRL_BIT_MODE_3); //0xFFF3 - outl(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - - outl(0, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_di_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me4600_di_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me4600_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - } else { - PERROR("Invalid port direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_di_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me4600_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inl(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inl(instance->port_reg) & 0xFF; - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_di_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base, - spinlock_t *ctrl_reg_lock) -{ - me4600_di_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me4600_di_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_di_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the subdevice index */ - subdevice->port_reg = reg_base + ME4600_DIO_PORT_1_REG; - subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_di_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_di_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_di_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me4600_di_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_di_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_di_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me4600_di.h b/drivers/staging/meilhaus/me4600_di.h deleted file mode 100644 index ec8b175755b..00000000000 --- a/drivers/staging/meilhaus/me4600_di.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file me4600_di.h - * - * @brief ME-4000 digital input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_DI_H_ -#define _ME4600_DI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me4600_di_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me4600_di_subdevice_t; - -/** - * @brief The constructor to generate a ME-4000 digital input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c deleted file mode 100644 index baa28ff6b6b..00000000000 --- a/drivers/staging/meilhaus/me4600_dio.c +++ /dev/null @@ -1,510 +0,0 @@ -/** - * @file me4600_dio.c - * - * @brief ME-4000 digital input/output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me4600_dio_reg.h" -#include "me4600_dio.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me4600_dio_subdevice_t *instance; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_dio_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - /* Set port to input mode */ - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inl(instance->ctrl_reg); - mode &= - ~((ME4600_DIO_CTRL_BIT_MODE_0 | ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - outl(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - - outl(0, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_dio_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me4600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - uint32_t size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - uint32_t mask; - - PDEBUG("executed.\n"); - - instance = (me4600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inl(instance->ctrl_reg); - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - mode &= - ~((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - mode &= - ~((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - mode |= - ME4600_DIO_CTRL_BIT_MODE_0 << (instance-> - dio_idx * 2); - } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) { - mask = - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << (instance-> - dio_idx * - 2); - mask |= - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1; - mask |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - mode &= ~mask; - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1; - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1; - mode |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else if (single_config == - ME_SINGLE_CONFIG_DIO_DEMUX32) { - mask = - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << (instance-> - dio_idx * - 2); - mask |= - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1; - mask |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - mode &= ~mask; - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0; - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0; - mode |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else if (single_config == - ME_SINGLE_CONFIG_DIO_BIT_PATTERN) { - mask = - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << (instance-> - dio_idx * - 2); - mask |= - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1; - mask |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - mode &= ~mask; - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= - (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2); - mode |= - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 << - instance->dio_idx; - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outl(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_dio_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inl(instance-> - ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - if ((mode == - (ME4600_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = - inl(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inl(instance-> - ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - if ((mode == - (ME4600_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = inl(instance->port_reg) & 0xFF; - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_dio_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me4600_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - uint32_t byte; - - PDEBUG("executed.\n"); - - instance = (me4600_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inl(instance-> - ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME4600_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - byte = inl(instance->port_reg) & 0xFF; - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outl(byte, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inl(instance-> - ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME4600_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - outl(value, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_dio_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_DIR_BYTE; - return ME_ERRNO_SUCCESS; -} - -me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t *ctrl_reg_lock) -{ - me4600_dio_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me4600_dio_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_dio_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save digital i/o index */ - subdevice->dio_idx = dio_idx; - - /* Save the subdevice index */ - subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG; - subdevice->port_reg = reg_base + ME4600_DIO_PORT_REG + (dio_idx * 4); -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_dio_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_dio_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_dio_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me4600_dio_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me4600_dio_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_dio_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_dio_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me4600_dio.h b/drivers/staging/meilhaus/me4600_dio.h deleted file mode 100644 index 4625ba91f60..00000000000 --- a/drivers/staging/meilhaus/me4600_dio.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file me4600_dio.h - * - * @brief ME-4000 digital input/output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_DIO_H_ -#define _ME4600_DIO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me4600_dio_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - unsigned int dio_idx; /**< The index of the digital i/o on the device. */ - - /* Registers */ - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me4600_dio_subdevice_t; - -/** - * @brief The constructor to generate a ME-4000 digital input/ouput subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param dio_idx The index of the digital i/o port on the device. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_dio_reg.h b/drivers/staging/meilhaus/me4600_dio_reg.h deleted file mode 100644 index 7a4016a80fd..00000000000 --- a/drivers/staging/meilhaus/me4600_dio_reg.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file me4600_dio_reg.h - * - * @brief ME-4000 digital input/output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_DIO_REG_H_ -#define _ME4600_DIO_REG_H_ - -#ifdef __KERNEL__ - -#define ME4600_DIO_PORT_0_REG 0xA0 /**< Port 0 register. */ -#define ME4600_DIO_PORT_1_REG 0xA4 /**< Port 1 register. */ -#define ME4600_DIO_PORT_2_REG 0xA8 /**< Port 2 register. */ -#define ME4600_DIO_PORT_3_REG 0xAC /**< Port 3 register. */ - -#define ME4600_DIO_DIR_REG 0xB0 /**< Direction register. */ -#define ME4600_DIO_PORT_REG ME4600_DIO_PORT_0_REG /**< Base for port's register. */ - -#define ME4600_DIO_CTRL_REG 0xB8 /**< Control register. */ -/** Port A - DO */ -#define ME4600_DIO_CTRL_BIT_MODE_0 0x0001 -#define ME4600_DIO_CTRL_BIT_MODE_1 0x0002 -/** Port B - DI */ -#define ME4600_DIO_CTRL_BIT_MODE_2 0x0004 -#define ME4600_DIO_CTRL_BIT_MODE_3 0x0008 -/** Port C - DIO */ -#define ME4600_DIO_CTRL_BIT_MODE_4 0x0010 -#define ME4600_DIO_CTRL_BIT_MODE_5 0x0020 -/** Port D - DIO */ -#define ME4600_DIO_CTRL_BIT_MODE_6 0x0040 -#define ME4600_DIO_CTRL_BIT_MODE_7 0x0080 - -#define ME4600_DIO_CTRL_BIT_FUNCTION_0 0x0100 -#define ME4600_DIO_CTRL_BIT_FUNCTION_1 0x0200 - -#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 0x0400 -#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_1 0x0800 -#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_2 0x1000 -#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_3 0x2000 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c deleted file mode 100644 index 39510f3e6e6..00000000000 --- a/drivers/staging/meilhaus/me4600_do.c +++ /dev/null @@ -1,433 +0,0 @@ -/** - * @file me4600_do.c - * - * @brief ME-4000 digital output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me4600_dio_reg.h" -#include "me4600_do.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me4600_do_subdevice_t *instance; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - /* Set port to output mode */ - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inl(instance->ctrl_reg); - mode &= ~ME4600_DIO_CTRL_BIT_MODE_1; //0xFFFD - mode |= ME4600_DIO_CTRL_BIT_MODE_0; //0x1 - outl(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - - outl(0, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me4600_do_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me4600_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - int size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - - PDEBUG("executed.\n"); - - instance = (me4600_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inl(instance->ctrl_reg); - - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1); - mode |= (ME4600_DIO_CTRL_BIT_MODE_0); - } else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) { - mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1 | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_1); - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_1 - | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else if (single_config == - ME_SINGLE_CONFIG_DIO_DEMUX32) { - mode &= - ~(ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1 | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_0); - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_0 - | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else if (single_config == - ME_SINGLE_CONFIG_DIO_BIT_PATTERN) { - mode &= - ~(ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FUNCTION_0 | - ME4600_DIO_CTRL_BIT_FUNCTION_1 | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - - if (ref == ME_REF_DIO_FIFO_LOW) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1); - } else if (ref == ME_REF_DIO_FIFO_HIGH) { - mode |= (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1 | - ME4600_DIO_CTRL_BIT_FIFO_HIGH_0); - } else { - PERROR - ("Invalid port reference specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid port direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outl(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_do_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me4600_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = - inl(instance-> - ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1); - - if (mode == ME4600_DIO_CTRL_BIT_MODE_0) { - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = - inl(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inl(instance->port_reg) & 0xFF; - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - } else { - PERROR("Port not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_do_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me4600_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t byte; - uint32_t mode; - - PDEBUG("executed.\n"); - - instance = (me4600_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = - inl(instance-> - ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 | - ME4600_DIO_CTRL_BIT_MODE_1); - - if (mode == ME4600_DIO_CTRL_BIT_MODE_0) { - switch (flags) { - - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - byte = inl(instance->port_reg) & 0xFF; - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outl(byte, instance->port_reg); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - outl(value, instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - } else { - PERROR("Port not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_do_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base, - spinlock_t *ctrl_reg_lock) -{ - me4600_do_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me4600_do_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_do_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the subdevice index */ - subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG; - subdevice->port_reg = reg_base + ME4600_DIO_PORT_0_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_do_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me4600_do_io_single_config; - subdevice->base.me_subdevice_io_single_read = me4600_do_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me4600_do_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me4600_do_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_do_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_do_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me4600_do.h b/drivers/staging/meilhaus/me4600_do.h deleted file mode 100644 index e8385648e92..00000000000 --- a/drivers/staging/meilhaus/me4600_do.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file me4600_do.h - * - * @brief ME-4000 digital output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_DO_H_ -#define _ME4600_DO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me4600_do_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me4600_do_subdevice_t; - -/** - * @brief The constructor to generate a ME-4000 digital output subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c deleted file mode 100644 index cfb4adbd41a..00000000000 --- a/drivers/staging/meilhaus/me4600_ext_irq.c +++ /dev/null @@ -1,457 +0,0 @@ -/** - * @file me4600_ext_irq.c - * - * @brief ME-4000 external interrupt subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "meids.h" -#include "me4600_reg.h" -#include "me4600_ai_reg.h" -#include "me4600_ext_irq_reg.h" -#include "me4600_ext_irq.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me4600_ext_irq_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags; - uint32_t tmp; - - PDEBUG("executed.\n"); - - instance = (me4600_ext_irq_subdevice_t *) subdevice; - - if (flags & ~ME_IO_IRQ_START_DIO_BIT) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((irq_edge != ME_IRQ_EDGE_RISING) - && (irq_edge != ME_IRQ_EDGE_FALLING) - && (irq_edge != ME_IRQ_EDGE_ANY) - ) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - - if (irq_source != ME_IRQ_SOURCE_DIO_LINE) { - PERROR("Invalid irq source specified.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - tmp = 0x0; //inl(instance->ext_irq_config_reg); - - if (irq_edge == ME_IRQ_EDGE_RISING) { - //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK; - //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_RISING; - } else if (irq_edge == ME_IRQ_EDGE_FALLING) { - //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK; - //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_FALLING; - tmp = ME4600_EXT_IRQ_CONFIG_MASK_FALLING; - } else if (irq_edge == ME_IRQ_EDGE_ANY) { - //tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK; - //tmp |= ME4600_EXT_IRQ_CONFIG_MASK_ANY; - tmp = ME4600_EXT_IRQ_CONFIG_MASK_ANY; - } - - outl(tmp, instance->ext_irq_config_reg); - PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ext_irq_config_reg - instance->reg_base, tmp); - - spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags); - tmp = inl(instance->ctrl_reg); - tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET); - tmp |= ME4600_AI_CTRL_BIT_EX_IRQ; - outl(tmp, instance->ctrl_reg); - spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags); - instance->rised = 0; - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me4600_ext_irq_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me4600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - (instance->rised != - 0), t); - - if (t == 0) { - PERROR - ("Wait on external interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on external interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - instance->rised = 0; - *irq_count = instance->count; - *value = instance->value; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice, - struct file *filep, - int channel, int flags) -{ - me4600_ext_irq_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags; - uint32_t tmp; - - PDEBUG("executed.\n"); - - instance = (me4600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->ctrl_reg_lock); - instance->rised = -1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me4600_ext_irq_subdevice_t *instance; - unsigned long cpu_flags; - uint32_t tmp; - - PDEBUG("executed.\n"); - - instance = (me4600_ext_irq_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->ctrl_reg_lock); - tmp = inl(instance->ctrl_reg); - tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET); - outl(tmp, instance->ctrl_reg); - PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->ctrl_reg_lock); - instance->rised = -1; - instance->count = 0; - outl(ME4600_EXT_IRQ_CONFIG_MASK_ANY, instance->ext_irq_config_reg); - PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ext_irq_config_reg - instance->reg_base, - ME4600_EXT_IRQ_CONFIG_MASK_ANY); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static void me4600_ext_irq_destructor(struct me_subdevice *subdevice) -{ - me4600_ext_irq_subdevice_t *instance; - - PDEBUG("executed.\n"); - instance = (me4600_ext_irq_subdevice_t *) subdevice; - me_subdevice_deinit(&instance->base); - free_irq(instance->irq, instance); - kfree(instance); -} - -static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 1; - return ME_ERRNO_SUCCESS; -} - -static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_EXT_IRQ; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = - ME_CAPS_EXT_IRQ_EDGE_RISING | ME_CAPS_EXT_IRQ_EDGE_FALLING | - ME_CAPS_EXT_IRQ_EDGE_ANY; - return ME_ERRNO_SUCCESS; -} - -static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id) -{ - me4600_ext_irq_subdevice_t *instance; - uint32_t ctrl; - uint32_t irq_status; - - instance = (me4600_ext_irq_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inl(instance->irq_status_reg); - if (!(irq_status & ME4600_IRQ_STATUS_BIT_EX)) { - PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n", - jiffies, __func__, irq_status); - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - spin_lock(&instance->subdevice_lock); - instance->rised = 1; - instance->value = inl(instance->ext_irq_value_reg); - instance->count++; - - spin_lock(instance->ctrl_reg_lock); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME4600_AI_CTRL_BIT_EX_IRQ_RESET; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - ctrl &= ~ME4600_AI_CTRL_BIT_EX_IRQ_RESET; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->ctrl_reg_lock); - - spin_unlock(&instance->subdevice_lock); - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base, - int irq, - spinlock_t * - ctrl_reg_lock) -{ - me4600_ext_irq_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me4600_ext_irq_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me4600_ext_irq_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Register interrupt */ - subdevice->irq = irq; - - if (request_irq(subdevice->irq, me4600_ext_irq_isr, - IRQF_DISABLED | IRQF_SHARED, - ME4600_NAME, subdevice)) { - PERROR("Cannot register interrupt.\n"); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - - /* Initialize registers */ - subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG; - subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG; - subdevice->ext_irq_config_reg = reg_base + ME4600_EXT_IRQ_CONFIG_REG; - subdevice->ext_irq_value_reg = reg_base + ME4600_EXT_IRQ_VALUE_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Override base class methods. */ - subdevice->base.me_subdevice_destructor = me4600_ext_irq_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me4600_ext_irq_io_reset_subdevice; - subdevice->base.me_subdevice_io_irq_start = me4600_ext_irq_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me4600_ext_irq_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me4600_ext_irq_io_irq_stop; - subdevice->base.me_subdevice_query_number_channels = - me4600_ext_irq_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me4600_ext_irq_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me4600_ext_irq_query_subdevice_caps; - - subdevice->rised = 0; - subdevice->count = 0; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me4600_ext_irq.h b/drivers/staging/meilhaus/me4600_ext_irq.h deleted file mode 100644 index 3c7b27f9e5d..00000000000 --- a/drivers/staging/meilhaus/me4600_ext_irq.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file me4600_ext_irq.h - * - * @brief Meilhaus ME-4000 external interrupt subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_EXT_IRQ_H_ -#define _ME4600_EXT_IRQ_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The subdevice class. - */ -typedef struct me4600_ext_irq_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - - wait_queue_head_t wait_queue; - - int irq; - - int rised; - int value; - int count; - - unsigned long ctrl_reg; - unsigned long irq_status_reg; - unsigned long ext_irq_config_reg; - unsigned long ext_irq_value_reg; -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me4600_ext_irq_subdevice_t; - -/** - * @brief The constructor to generate a external interrupt subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param irq The interrupt number assigned by the PCI BIOS. - * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base, - int irq, - spinlock_t * - ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_ext_irq_reg.h b/drivers/staging/meilhaus/me4600_ext_irq_reg.h deleted file mode 100644 index 898e1e74d9e..00000000000 --- a/drivers/staging/meilhaus/me4600_ext_irq_reg.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file me4600_ext_irq_reg.h - * - * @brief ME-4000 external interrupt subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_EXT_IRQ_REG_H_ -#define _ME4600_EXT_IRQ_REG_H_ - -#ifdef __KERNEL__ - -#define ME4600_EXT_IRQ_CONFIG_REG 0xCC // R/_ -#define ME4600_EXT_IRQ_VALUE_REG 0xD0 // R/_ - -#define ME4600_EXT_IRQ_CONFIG_MASK_RISING 0x0 -#define ME4600_EXT_IRQ_CONFIG_MASK_FALLING 0x1 -#define ME4600_EXT_IRQ_CONFIG_MASK_ANY 0x3 -#define ME4600_EXT_IRQ_CONFIG_MASK 0x3 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me4600_reg.h b/drivers/staging/meilhaus/me4600_reg.h deleted file mode 100644 index ae152bbc6a3..00000000000 --- a/drivers/staging/meilhaus/me4600_reg.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file me4600_reg.h - * - * @brief ME-4000 register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME4600_REG_H_ -#define _ME4600_REG_H_ - -#ifdef __KERNEL__ - -#define ME4600_IRQ_STATUS_REG 0x9C // R/_ - -#define ME4600_IRQ_STATUS_BIT_EX 0x01 -#define ME4600_IRQ_STATUS_BIT_LE 0x02 -#define ME4600_IRQ_STATUS_BIT_AI_HF 0x04 -#define ME4600_IRQ_STATUS_BIT_AO_0_HF 0x08 -#define ME4600_IRQ_STATUS_BIT_AO_1_HF 0x10 -#define ME4600_IRQ_STATUS_BIT_AO_2_HF 0x20 -#define ME4600_IRQ_STATUS_BIT_AO_3_HF 0x40 -#define ME4600_IRQ_STATUS_BIT_SC 0x80 - -#define ME4600_IRQ_STATUS_BIT_AO_HF ME4600_IRQ_STATUS_BIT_AO_0_HF - -#endif -#endif diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c deleted file mode 100644 index 66652dc5b96..00000000000 --- a/drivers/staging/meilhaus/me6000_ao.c +++ /dev/null @@ -1,3709 +0,0 @@ -/** - * @file me6000_ao.c - * - * @brief ME-6000 analog output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* Includes - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "meids.h" -#include "me6000_reg.h" -#include "me6000_ao_reg.h" -#include "me6000_ao.h" - -/* Defines - */ - -static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range); - -static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count); - -static int me6000_ao_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata); - -static int me6000_ao_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks); - -static int me6000_ao_query_number_channels(me_subdevice_t *subdevice, - int *number); - -static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype); - -static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps); - -static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count); - -/** Remove subdevice. */ -static void me6000_ao_destructor(struct me_subdevice *subdevice); - -/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */ -static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags); - -/** Set output as single */ -static int me6000_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags); - -/** Pass to user actual value of output. */ -static int me6000_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags); - -/** Write to output requed value. */ -static int me6000_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags); - -/** Set output as streamed device. */ -static int me6000_ao_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags); - -/** Wait for / Check empty space in buffer. */ -static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags); - -/** Start streaming. */ -static int me6000_ao_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags); - -/** Check actual state. / Wait for end. */ -static int me6000_ao_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags); - -/** Stop streaming. */ -static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags); - -/** Write datas to buffor. */ -static int me6000_ao_io_stream_write(me_subdevice_t *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags); - -/** Interrupt handler. Copy from buffer to FIFO. */ -static irqreturn_t me6000_ao_isr(int irq, void *dev_id); - -/** Copy data from circular buffer to fifo (fast) in wraparound mode. */ -inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from circular buffer to fifo (fast).*/ -inline int ao_write_data(me6000_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from circular buffer to fifo (slow).*/ -inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count, - int start_pos); - -/** Copy data from user space to circular buffer. */ -inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count, - int *user_values); - -/** Stop presentation. Preserve FIFOs. */ -inline int ao_stop_immediately(me6000_ao_subdevice_t *instance); - -/** Function for checking timeout in non-blocking mode. */ -static void me6000_ao_work_control_task(struct work_struct *work); - -/* Functions - */ - -static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice, - struct file *filep, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t tmp; - uint32_t ctrl; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - instance->status = ao_status_none; - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->timeout.delay = 0; - instance->timeout.start_time = jiffies; - - //Stop state machine. - err = ao_stop_immediately(instance); - - //Remove from synchronous start. - spin_lock(instance->preload_reg_lock); - tmp = inl(instance->preload_reg); - tmp &= - ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - outl(tmp, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, tmp); - *instance->preload_flags &= - ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - - //Reset triggering flag - *instance->triggering_flags &= ~(0x1 << instance->ao_idx); - spin_unlock(instance->preload_reg_lock); - - if (instance->fifo) { - //Set single mode, dissable FIFO, dissable external trigger, block interrupt. - ctrl = ME6000_AO_MODE_SINGLE; - - //Block ISM. - ctrl |= - (ME6000_AO_CTRL_BIT_STOP | - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP); - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - //Set speed - outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg); - //Reset interrupt latch - inl(instance->irq_reset_reg); - } - - instance->hardware_stop_delay = HZ / 10; //100ms - - //Set output to 0V - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - instance->preloaded_count = 0; - instance->data_count = 0; - instance->single_value = 0x8000; - instance->single_value_in_fifo = 0x8000; - - //Set status to signal that device is unconfigured. - instance->status = ao_status_none; - //Signal reset if user is on wait. - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t ctrl; - uint32_t sync; - unsigned long cpu_flags; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. ID=%d\n", instance->ao_idx); - - // Checking parameters - if (flags) { - PERROR - ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (instance->fifo) { //Stream hardware (with or without fifo) - if ((trig_edge == ME_TRIG_TYPE_SW) - && (trig_edge != ME_TRIG_EDGE_NONE)) { - PERROR - ("Invalid trigger edge. Software trigger has not edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - - if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) { - switch (trig_edge) { - case ME_TRIG_EDGE_ANY: - case ME_TRIG_EDGE_RISING: - case ME_TRIG_EDGE_FALLING: - break; - - default: - PERROR("Invalid trigger edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - } - - if ((trig_type != ME_TRIG_TYPE_SW) - && (trig_type != ME_TRIG_TYPE_EXT_DIGITAL)) { - PERROR - ("Invalid trigger type. Trigger must be software or digital.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - } else { //Single - if (trig_edge != ME_TRIG_EDGE_NONE) { - PERROR - ("Invalid trigger edge. Single output trigger hasn't own edge.\n"); - return ME_ERRNO_INVALID_TRIG_EDGE; - } - - if (trig_type != ME_TRIG_TYPE_SW) { - PERROR - ("Invalid trigger type. Trigger must be software.\n"); - return ME_ERRNO_INVALID_TRIG_TYPE; - } - - } - - if ((trig_chan != ME_TRIG_CHAN_DEFAULT) - && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) { - PERROR("Invalid trigger channel specified.\n"); - return ME_ERRNO_INVALID_TRIG_CHAN; - } -/* - if ((trig_type == ME_TRIG_TYPE_EXT_DIGITAL) && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) - { - PERROR("Invalid trigger channel specified. Must be synchronous when digital is choose.\n"); - return ME_ERRNO_INVALID_TRIG_CHAN; - } -*/ - if (ref != ME_REF_AO_GROUND) { - PERROR - ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n"); - return ME_ERRNO_INVALID_REF; - } - - if (single_config != 0) { - PERROR - ("Invalid single config specified. Only one range for anlog outputs is available.\n"); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - - if (channel != 0) { - PERROR - ("Invalid channel number specified. Analog output have only one channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - //Subdevice running in stream mode! - if ((instance->status >= ao_status_stream_run_wait) - && (instance->status < ao_status_stream_end)) { - PERROR("Subdevice is busy.\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } -/// @note For single all calls (config and write) are erasing previous state! - - instance->status = ao_status_none; - - // Correct single mirrors - instance->single_value_in_fifo = instance->single_value; - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - - if (instance->fifo) { // Set control register. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Set stop bit. Stop streaming mode (If running.). - ctrl = inl(instance->ctrl_reg); - //Reset all bits. - ctrl = - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP; - if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) { - PINFO("External digital trigger.\n"); - - if (trig_edge == ME_TRIG_EDGE_ANY) { -// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - instance->ctrl_trg = - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - } else if (trig_edge == ME_TRIG_EDGE_FALLING) { -// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE; - instance->ctrl_trg = - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE; - } else if (trig_edge == ME_TRIG_EDGE_RISING) { - instance->ctrl_trg = 0x0; - } - } else if (trig_type == ME_TRIG_TYPE_SW) { - PDEBUG("SOFTWARE TRIGGER\n"); - instance->ctrl_trg = 0x0; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } else { - PDEBUG("SOFTWARE TRIGGER\n"); - } - - // Set preload/synchronization register. - spin_lock(instance->preload_reg_lock); - - if (trig_type == ME_TRIG_TYPE_SW) { - *instance->preload_flags &= - ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx); - } else //if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) - { - *instance->preload_flags |= - ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx; - } - - if (trig_chan == ME_TRIG_CHAN_DEFAULT) { - *instance->preload_flags &= - ~(ME6000_AO_SYNC_HOLD << instance->ao_idx); - } else //if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) - { - *instance->preload_flags |= - ME6000_AO_SYNC_HOLD << instance->ao_idx; - } - - //Reset hardware register - sync = inl(instance->preload_reg); - PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync); - sync &= ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx); - sync |= ME6000_AO_SYNC_HOLD << instance->ao_idx; - - //Output configured in default mode (safe one) - outl(sync, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync); - spin_unlock(instance->preload_reg_lock); - - instance->status = ao_status_single_configured; - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - unsigned long j; - unsigned long delay = 0; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & ~ME_IO_SINGLE_NONBLOCKING) { - PERROR("Invalid flag specified. %d\n", flags); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((instance->status >= ao_status_stream_configured) - && (instance->status <= ao_status_stream_end)) { - PERROR("Subdevice not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - ME_SUBDEVICE_ENTER; - if ((!flags) && (instance->status == ao_status_single_run_wait)) { //Blocking mode. Wait for trigger. - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - j = jiffies; - - //Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_single_run_wait), - (delay) ? delay : LONG_MAX); - - if (instance->status == ao_status_none) { - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - PDEBUG("Timeout reached.\n"); - err = ME_ERRNO_TIMEOUT; - } - - *value = - (!err) ? instance->single_value_in_fifo : instance-> - single_value; - } else { //Non-blocking mode - //Read value - *value = instance->single_value; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags; - unsigned long j; - unsigned long delay = 0; - - uint32_t sync_mask; - uint32_t mode; - - uint32_t tmp; - -/// Workaround for mix-mode - begin - uint32_t ctrl = 0x0; - uint32_t status; -/// Workaround for mix-mode - end - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & - ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS | - ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((instance->status == ao_status_none) - || (instance->status > ao_status_single_end)) { - PERROR("Subdevice not configured to work in single mode!\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - if (channel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (value & ~ME6000_AO_MAX_DATA) { - PERROR("Invalid value provided.\n"); - return ME_ERRNO_VALUE_OUT_OF_RANGE; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - ME_SUBDEVICE_ENTER; - -/// @note For single all calls (config and write) are erasing previous state! - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - // Correct single mirrors - instance->single_value_in_fifo = instance->single_value; - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - - if (delay == 0) - delay = 1; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - - instance->single_value_in_fifo = value; - - if (instance->fifo) { - ctrl = inl(instance->ctrl_reg); - } - - if (instance->fifo & ME6000_AO_HAS_FIFO) { /// Workaround for mix-mode - begin - //Set speed - outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg); - PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->timer_reg - instance->reg_base, - (int)ME6000_AO_MIN_CHAN_TICKS); - instance->hardware_stop_delay = HZ / 10; //100ms - - status = inl(instance->status_reg); - - //Set the continous mode. - ctrl &= ~ME6000_AO_CTRL_MODE_MASK; - ctrl |= ME6000_AO_MODE_CONTINUOUS; - - //Prepare FIFO - if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. - PINFO("Enableing FIFO.\n"); - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO; - } else { //Check if FIFO is empty - if (status & ME6000_AO_STATUS_BIT_EF) { //FIFO not empty - PINFO("Reseting FIFO.\n"); - ctrl &= - ~(ME6000_AO_CTRL_BIT_ENABLE_FIFO | - ME6000_AO_CTRL_BIT_ENABLE_IRQ); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - - instance->reg_base, ctrl); - - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO; - } else { //FIFO empty, only interrupt needs to be disabled! - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - } - } - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - //Write output - 1 value to FIFO - if (instance->ao_idx & 0x1) { - outl(value <<= 16, instance->fifo_reg); - PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->fifo_reg - instance->reg_base, - value <<= 16); - } else { - outl(value, instance->fifo_reg); - PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->fifo_reg - instance->reg_base, - value); - } - /// Workaround for mix-mode - end - } else { //No FIFO - always in single mode - //Write value - PDEBUG("Write value\n"); - outl(value, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, value); - } - - mode = *instance->preload_flags >> instance->ao_idx; - mode &= (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG); - - PINFO("Triggering mode: 0x%08x\n", mode); - - spin_lock(instance->preload_reg_lock); - sync_mask = inl(instance->preload_reg); - PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, sync_mask); - switch (mode) { - case 0: //0x00000000: Individual software - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode. - sync_mask &= - ~((ME6000_AO_SYNC_EXT_TRIG | - ME6000_AO_SYNC_HOLD) << instance-> - ao_idx); - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } else { // No FIFO - Single mode: In this case resetting 'ME6000_AO_SYNC_HOLD' will trigger output. - if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME6000_AO_SYNC_HOLD) { //Now we can set correct mode. This is exception. It is set to synchronous and triggered later. - sync_mask &= - ~(ME6000_AO_SYNC_EXT_TRIG << instance-> - ao_idx); - sync_mask |= - ME6000_AO_SYNC_HOLD << instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } - instance->single_value = value; - break; - - case ME6000_AO_SYNC_EXT_TRIG: //0x00010000: Individual hardware - PDEBUG("DIGITAL TRIGGER\n"); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode - if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) { //Now we can set correct mode. - sync_mask &= - ~((ME6000_AO_SYNC_EXT_TRIG | - ME6000_AO_SYNC_HOLD) << instance-> - ao_idx); - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } else { // No FIFO - Single mode - if ((sync_mask & - ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << - instance->ao_idx)) != ME6000_AO_SYNC_HOLD) { - //Now we can set correct mode - sync_mask &= - ~(ME6000_AO_SYNC_EXT_TRIG << instance-> - ao_idx); - sync_mask |= - ME6000_AO_SYNC_HOLD << instance->ao_idx; - - outl(sync_mask, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - } - break; - - case ME6000_AO_SYNC_HOLD: //0x00000001: Synchronous software - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if ((sync_mask & - ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << - instance->ao_idx)) != - (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) { - //Now we can set correct mode - sync_mask |= - ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx; - sync_mask |= ME6000_AO_SYNC_HOLD << instance->ao_idx; - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - //Set triggering flag - *instance->triggering_flags |= 0x1 << instance->ao_idx; - break; - - case (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG): //0x00010001: Synchronous hardware - PDEBUG("DIGITAL TRIGGER\n"); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - - if ((sync_mask & - ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << - instance->ao_idx)) != - (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) { - //Now we can set correct mode - sync_mask |= - (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << - instance->ao_idx; - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - } - //Set triggering flag - *instance->triggering_flags |= 0x1 << instance->ao_idx; - break; - } -// spin_unlock(instance->preload_reg_lock); // Moved down. - - if (instance->fifo) { //Activate ISM (remove 'stop' bits) - ctrl &= - ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH); - ctrl |= instance->ctrl_trg; - ctrl &= - ~(ME6000_AO_CTRL_BIT_STOP | - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP); - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - } - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - -/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS! - - PINFO("<%s> start mode= 0x%08x %s\n", __func__, mode, - (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" : - ""); - if (instance->fifo & ME6000_AO_HAS_FIFO) { // FIFO - Continous mode - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs - //Add channel to start list - outl(sync_mask | - (ME6000_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask | (ME6000_AO_SYNC_HOLD << - instance->ao_idx)); - - //Fire - PINFO - ("Fired all software synchronous outputs by software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - 0x8000); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - - } else if (!mode) { //Trigger outputs -/* //Remove channel from start list - outl(sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx)); -*/ - //Fire - PINFO("Software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - 0x8000); - -/* //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask); -*/ - } -/// @note This is mix-mode case. For now I do not have possibility to trigger first 4 channels (continous mode) and other (single) ones at once. -/// @note Because triggering is not working it can not be add to synchronous list. First 4 channels don't need this information, anyway. - *instance->triggering_flags &= 0xFFFFFFF0; - } else { // No FIFO - Single mode - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Fired all software synchronous outputs. - tmp = ~(*instance->preload_flags | 0xFFFF0000); - PINFO - ("Fired all software synchronous outputs. mask:0x%08x\n", - tmp); - tmp |= sync_mask & 0xFFFF0000; - // Add this channel to list - tmp &= ~(ME6000_AO_SYNC_HOLD << instance->ao_idx); - - //Fire - PINFO("Software trigger.\n"); - outl(tmp, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - tmp); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - - //Set all as triggered. - *instance->triggering_flags = 0x0; - } else if (!mode) { // Add this channel to list - outl(sync_mask & - ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask & ~(ME6000_AO_SYNC_HOLD << - instance->ao_idx)); - - //Fire - PINFO("Software trigger.\n"); - - //Restore save settings - outl(sync_mask, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - sync_mask); - - //Set all as triggered. - *instance->triggering_flags = 0x0; - } - - } - spin_unlock(instance->preload_reg_lock); - - instance->status = ao_status_single_run_wait; - - instance->timeout.delay = delay; - instance->timeout.start_time = jiffies; - instance->ao_control_task_flag = 1; - queue_delayed_work(instance->me6000_workqueue, - &instance->ao_control_task, 1); - - if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) { - j = jiffies; - - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_single_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if (instance->status != ao_status_single_end) { - PDEBUG("Single canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - ao_stop_immediately(instance); - instance->status = ao_status_none; - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - j) >= delay)) { - if (instance->status == ao_status_single_end) { - PDEBUG("Timeout reached.\n"); - } else if ((jiffies - j) > delay) { - PERROR - ("Timeout reached. Not handled by control task!\n"); - ao_stop_immediately(instance); - } else { - PERROR - ("Timeout reached. Signal come but status is strange: %d\n", - instance->status); - ao_stop_immediately(instance); - } - - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->status = ao_status_single_end; - err = ME_ERRNO_TIMEOUT; - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_stream_config(me_subdevice_t *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t ctrl; - unsigned long cpu_flags; - uint64_t conv_ticks; - unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow; - unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - conv_ticks = - (uint64_t) conv_start_ticks_low + - ((uint64_t) conv_start_ticks_high << 32); - - if (flags & - ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY | - ME_IO_STREAM_CONFIG_WRAPAROUND)) { - PERROR("Invalid flags.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { - if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) { - PERROR - ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE) - || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) { - PERROR - ("Hardware wraparound mode must be in infinite mode.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - } - - if (count != 1) { - PERROR("Only 1 entry in config list acceptable.\n"); - return ME_ERRNO_INVALID_CONFIG_LIST_COUNT; - } - - if (config_list[0].iChannel != 0) { - PERROR("Invalid channel number specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (config_list[0].iStreamConfig != 0) { - PERROR("Only one range available.\n"); - return ME_ERRNO_INVALID_STREAM_CONFIG; - } - - if (config_list[0].iRef != ME_REF_AO_GROUND) { - PERROR("Output is referenced to ground.\n"); - return ME_ERRNO_INVALID_REF; - } - - if ((trigger->iAcqStartTicksLow != 0) - || (trigger->iAcqStartTicksHigh != 0)) { - PERROR - ("Invalid acquisition start trigger argument specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_ARG; - } - - if (config_list[0].iFlags) { - PERROR("Invalid config list flag.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW) - && (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL)) { - PERROR("Invalid acquisition start trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE; - } - - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_RISING: - case ME_TRIG_EDGE_FALLING: - case ME_TRIG_EDGE_ANY: - break; - - default: - PERROR - ("Invalid acquisition start trigger edge specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - } - } - - if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) - && (trigger->iAcqStartTrigEdge != ME_TRIG_TYPE_NONE)) { - PERROR("Invalid acquisition start trigger edge specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE; - } - - if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) { - PERROR("Invalid scan start trigger type specified.\n"); - return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE; - } - - if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) { - PERROR("Invalid conv start trigger type specified.\n"); - return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE; - } - - if ((conv_ticks < ME6000_AO_MIN_CHAN_TICKS) - || (conv_ticks > ME6000_AO_MAX_CHAN_TICKS)) { - PERROR("Invalid conv start trigger argument specified.\n"); - return ME_ERRNO_INVALID_CONV_START_ARG; - } - - if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) { - PERROR("Invalid acq start trigger argument specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_ARG; - } - - if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) { - PERROR("Invalid scan start trigger argument specified.\n"); - return ME_ERRNO_INVALID_SCAN_START_ARG; - } - - switch (trigger->iScanStopTrigType) { - case ME_TRIG_TYPE_NONE: - if (trigger->iScanStopCount != 0) { - PERROR("Invalid scan stop count specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_ARG; - } - break; - - case ME_TRIG_TYPE_COUNT: - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iScanStopCount <= 0) { - PERROR("Invalid scan stop count specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_ARG; - } - } else { - PERROR("The continous mode has not 'scan' contects.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - break; - - default: - PERROR("Invalid scan stop trigger type specified.\n"); - return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE; - } - - switch (trigger->iAcqStopTrigType) { - case ME_TRIG_TYPE_NONE: - if (trigger->iAcqStopCount != 0) { - PERROR("Invalid acq stop count specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_ARG; - } - break; - - case ME_TRIG_TYPE_COUNT: - if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) { - PERROR("Invalid acq stop trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { - if (trigger->iAcqStopCount <= 0) { - PERROR - ("The continous mode has not 'scan' contects.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_ARG; - } - } -// else -// { -// PERROR("Invalid acq stop trigger type specified.\n"); -// return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; -// } - - break; - - default: - PERROR("Invalid acq stop trigger type specified.\n"); - return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE; - } - - switch (trigger->iAcqStartTrigChan) { - case ME_TRIG_CHAN_DEFAULT: - case ME_TRIG_CHAN_SYNCHRONOUS: - break; - - default: - PERROR("Invalid acq start trigger channel specified.\n"); - return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN; - } - - ME_SUBDEVICE_ENTER; - - //Stop device - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - //Check if state machine is stopped. - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - //Reset control register. Block all actions. Disable IRQ. Disable FIFO. - ctrl = ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - //This is paranoic, but to be sure. - instance->preloaded_count = 0; - instance->data_count = 0; - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - - /* Set mode. */ - if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) { //Wraparound - if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) { //Hardware wraparound - PINFO("Hardware wraparound.\n"); - ctrl |= ME6000_AO_MODE_WRAPAROUND; - instance->mode = ME6000_AO_HW_WRAP_MODE; - } else { //Software wraparound - PINFO("Software wraparound.\n"); - ctrl |= ME6000_AO_MODE_CONTINUOUS; - instance->mode = ME6000_AO_SW_WRAP_MODE; - } - } else { //Continous - PINFO("Continous.\n"); - ctrl |= ME6000_AO_MODE_CONTINUOUS; - instance->mode = ME6000_AO_CONTINOUS; - } - - //Set the trigger edge. - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Set the trigger type and edge for external trigger. - PINFO("External digital trigger.\n"); - instance->start_mode = ME6000_AO_EXT_TRIG; - - switch (trigger->iAcqStartTrigEdge) { - case ME_TRIG_EDGE_RISING: - PINFO("Set the trigger edge: rising.\n"); - instance->ctrl_trg = 0x0; - break; - - case ME_TRIG_EDGE_FALLING: - PINFO("Set the trigger edge: falling.\n"); -// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE; - instance->ctrl_trg = ME6000_AO_CTRL_BIT_EX_TRIG_EDGE; - break; - - case ME_TRIG_EDGE_ANY: - PINFO("Set the trigger edge: both edges.\n"); -// ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - instance->ctrl_trg = - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH; - break; - } - } else { - PINFO("Internal software trigger.\n"); - instance->start_mode = 0; - } - - //Set the stop mode and value. - if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of data - instance->stop_mode = ME6000_AO_ACQ_STOP_MODE; - instance->stop_count = trigger->iAcqStopCount; - } else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) { //Amount of 'scans' - instance->stop_mode = ME6000_AO_SCAN_STOP_MODE; - instance->stop_count = trigger->iScanStopCount; - } else { //Infinite - instance->stop_mode = ME6000_AO_INF_STOP_MODE; - instance->stop_count = 0; - } - - PINFO("Stop count: %d.\n", instance->stop_count); - - if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) { //Synchronous start - instance->start_mode |= ME6000_AO_SYNC_HOLD; - if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) { //Externaly triggered - PINFO("Synchronous start. Externaly trigger active.\n"); - instance->start_mode |= ME6000_AO_SYNC_EXT_TRIG; - } -#ifdef MEDEBUG_INFO - else { - PINFO - ("Synchronous start. Externaly trigger dissabled.\n"); - } -#endif - - } - //Set speed - outl(conv_ticks - 2, instance->timer_reg); - PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base, - instance->timer_reg - instance->reg_base, conv_ticks - 2); - instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME6000_AO_BASE_FREQUENCY; //<== MUST be with cast! - - // Write the control word - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Set status. - instance->status = ao_status_stream_configured; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice, - struct file *filep, - int time_out, int *count, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - long j; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (!instance->circ_buf.buf) { - PERROR("Circular buffer not exists.\n"); - return ME_ERRNO_INTERNAL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - ME_SUBDEVICE_ENTER; - - if (me_circ_buf_space(&instance->circ_buf)) { //The buffer is NOT full. - *count = me_circ_buf_space(&instance->circ_buf); - } else { //The buffer is full. - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } else { //Max time. - t = LONG_MAX; - } - - *count = 0; - - j = jiffies; - - //Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled. - wait_event_interruptible_timeout(instance->wait_queue, - ((me_circ_buf_space - (&instance->circ_buf)) - || !(inl(instance->status_reg) - & - ME6000_AO_STATUS_BIT_FSM)), - t); - - if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) { - PERROR("AO subdevice is not running.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - } else if (signal_pending(current)) { - PERROR("Wait on values interrupted from signal.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } else if ((jiffies - j) >= t) { - PERROR("Wait on values timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } else { //Uff... all is good. Inform user about empty space. - *count = me_circ_buf_space(&instance->circ_buf); - } - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_stream_start(me_subdevice_t *subdevice, - struct file *filep, - int start_mode, int time_out, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long cpu_flags = 0; - uint32_t status; - uint32_t ctrl; - uint32_t synch; - int count = 0; - int circ_buffer_count; - - unsigned long ref; - unsigned long delay = 0; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) { - PERROR("Invalid flags.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid timeout specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if ((start_mode != ME_START_MODE_BLOCKING) - && (start_mode != ME_START_MODE_NONBLOCKING)) { - PERROR("Invalid start mode specified.\n"); - return ME_ERRNO_INVALID_START_MODE; - } - - if (time_out) { - delay = (time_out * HZ) / 1000; - if (delay == 0) - delay = 1; - } - - switch (instance->status) { //Checking actual mode. - case ao_status_stream_configured: - case ao_status_stream_end: - //Correct modes! - break; - - //The device is in wrong mode. - case ao_status_none: - case ao_status_single_configured: - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - PERROR - ("Subdevice must be preinitialize correctly for streaming.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - PDEBUG("Before restart broke stream 'STOP' must be caled.\n"); - return ME_STATUS_ERROR; - - case ao_status_stream_run_wait: - case ao_status_stream_run: - case ao_status_stream_end_wait: - PDEBUG("Stream is already working.\n"); - return ME_ERRNO_SUBDEVICE_BUSY; - - default: - instance->status = ao_status_stream_error; - PERROR_CRITICAL("Status is in wrong state!\n"); - return ME_ERRNO_INTERNAL; - - } - - ME_SUBDEVICE_ENTER; - - if (instance->mode == ME6000_AO_CONTINOUS) { //Continous - instance->circ_buf.tail += instance->preloaded_count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } - circ_buffer_count = me_circ_buf_values(&instance->circ_buf); - - if (!circ_buffer_count && !instance->preloaded_count) { //No values in buffer - ME_SUBDEVICE_EXIT; - PERROR("No values in buffer!\n"); - return ME_ERRNO_LACK_OF_RESOURCES; - } - - //Cancel control task - PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx); - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - - //Stop device - err = ao_stop_immediately(instance); - if (err) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUBDEVICE_BUSY; - } - //Set values for single_read() - instance->single_value = ME6000_AO_MAX_DATA + 1; - instance->single_value_in_fifo = ME6000_AO_MAX_DATA + 1; - - //Setting stop points - if (instance->stop_mode == ME6000_AO_SCAN_STOP_MODE) { - instance->stop_data_count = - instance->stop_count * circ_buffer_count; - } else { - instance->stop_data_count = instance->stop_count; - } - - if ((instance->stop_data_count != 0) - && (instance->stop_data_count < circ_buffer_count)) { - PERROR("More data in buffer than previously set limit!\n"); - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - //Check FIFO - if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD - PINFO("Enableing FIFO.\n"); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO; - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - - instance->preloaded_count = 0; - instance->data_count = 0; - } else { //Block IRQ - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - //Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it. - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_EF)) { //FIFO empty - if (instance->stop_data_count != 0) { - count = ME6000_AO_FIFO_COUNT; - } else { - count = - (ME6000_AO_FIFO_COUNT < - instance-> - stop_data_count) ? ME6000_AO_FIFO_COUNT : - instance->stop_data_count; - } - - //Copy data - count = - ao_write_data(instance, count, instance->preloaded_count); - - if (count < 0) { //This should never happend! - PERROR_CRITICAL("COPY FINISH WITH ERROR!\n"); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - //Set pre-load features. - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - synch &= - ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - synch |= - (instance->start_mode & ~ME6000_AO_EXT_TRIG) << instance->ao_idx; - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); - - //Default count is '0' - if (instance->mode == ME6000_AO_CONTINOUS) { //Continous - instance->preloaded_count = 0; - instance->circ_buf.tail += count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } else { //Wraparound - instance->preloaded_count += count; - instance->data_count += count; - - //Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode. - if ((instance->stop_mode == ME6000_AO_INF_STOP_MODE) - && (circ_buffer_count <= ME6000_AO_FIFO_COUNT)) { //Change to hardware wraparound - PDEBUG - ("Changeing mode from software wraparound to hardware wraparound.\n"); - //Copy all data - count = - ao_write_data(instance, circ_buffer_count, - instance->preloaded_count); - ctrl &= ~ME6000_AO_CTRL_MODE_MASK; - ctrl |= ME6000_AO_MODE_WRAPAROUND; - } - - if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator. - instance->preloaded_count = 0; - } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend! - PERROR_CRITICAL - ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n"); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - - //Set status to 'wait for start' - instance->status = ao_status_stream_run_wait; - - status = inl(instance->status_reg); - //Start state machine and interrupts - PINFO("<%s:%d> Start state machine.\n", __func__, __LINE__); - ctrl &= ~(ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP); - if (instance->start_mode == ME6000_AO_EXT_TRIG) { - PDEBUG("DIGITAL TRIGGER\n"); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG; - } - if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half! - if ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS) { //Enable IRQ only when hardware_continous is set and FIFO is more than half - PINFO("<%s:%d> Start interrupts.\n", __func__, - __LINE__); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ; - } - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - //Trigger output - PINFO("<%s> start mode= 0x%x %s\n", __func__, instance->start_mode, - (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" : - ""); - if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) { //Trigger outputs - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - //Add channel to start list - outl(synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx), - instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx)); - - //Fire - PINFO - ("Fired all software synchronous outputs by software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - - //Restore save settings - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); - } else if (!instance->start_mode) { //Trigger outputs -/* - spin_lock(instance->preload_reg_lock); - synch = inl(instance->preload_reg); - //Remove channel from start list - outl(synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx)); -*/ - //Fire - PINFO("Software trigger.\n"); - outl(0x8000, instance->single_reg); - PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, 0x8000); - -/* - //Restore save settings - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch); - spin_unlock(instance->preload_reg_lock); -*/ - } - // Set control task's timeout - instance->timeout.delay = delay; - instance->timeout.start_time = jiffies; - - if (status & ME6000_AO_STATUS_BIT_HF) { //Less than half but not empty! - PINFO("Less than half.\n"); - if (instance->stop_data_count == 0) { - count = ME6000_AO_FIFO_COUNT / 2; - } else { - count = - ((ME6000_AO_FIFO_COUNT / 2) < - instance->stop_data_count) ? ME6000_AO_FIFO_COUNT / - 2 : instance->stop_data_count; - } - - //Copy data - count = - ao_write_data(instance, count, instance->preloaded_count); - - if (count < 0) { //This should never happend! - PERROR_CRITICAL("COPY FINISH WITH ERROR!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - - if (instance->mode == ME6000_AO_CONTINOUS) { //Continous - instance->circ_buf.tail += count; - instance->circ_buf.tail &= instance->circ_buf.mask; - } else { //Wraparound - instance->data_count += count; - instance->preloaded_count += count; - - if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) { //Reset position indicator. - instance->preloaded_count = 0; - } else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) { //This should never happend! - PERROR_CRITICAL - ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - } - - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_HF)) { //More than half! - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - PINFO("<%s:%d> Start interrupts.\n", __func__, - __LINE__); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - } - } - //Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt. - if ((instance->stop_mode != ME6000_AO_INF_STOP_MODE) - && (instance->mode == ME6000_AO_SW_WRAP_MODE) - && (circ_buffer_count <= (ME6000_AO_FIFO_COUNT / 2))) { //Put more data to FIFO - PINFO("Limited wraparound with less than HALF FIFO datas.\n"); - if (instance->preloaded_count) { //This should never happend! - PERROR_CRITICAL - ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - - while (instance->stop_data_count > instance->data_count) { //Maximum data not set jet. - //Copy to buffer - if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) { //This should never happend! - PERROR_CRITICAL - ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n"); - ME_SUBDEVICE_EXIT; - return ME_ERRNO_INTERNAL; - } - instance->data_count += circ_buffer_count; - - if (!((status = inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF)) { //FIFO is more than half. Enable IRQ and end copy. - //Reset interrupt latch - inl(instance->irq_reset_reg); - - spin_lock_irqsave(&instance->subdevice_lock, - cpu_flags); - PINFO("<%s:%d> Start interrupts.\n", - __func__, __LINE__); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - break; - } - } - } - // Schedule control task - instance->ao_control_task_flag = 1; - queue_delayed_work(instance->me6000_workqueue, - &instance->ao_control_task, 1); - - if (start_mode == ME_START_MODE_BLOCKING) { //Wait for start. - ref = jiffies; - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_stream_run_wait), - (delay) ? delay + - 1 : LONG_MAX); - - if ((instance->status != ao_status_stream_run) - && (instance->status != ao_status_stream_end)) { - PDEBUG("Starting stream canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait on start of state machine interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - - if ((delay) && ((jiffies - ref) >= delay)) { - if (instance->status != ao_status_stream_run) { - if (instance->status == ao_status_stream_end) { - PDEBUG("Timeout reached.\n"); - } else if ((jiffies - ref) > delay) { - PERROR - ("Timeout reached. Not handled by control task!\n"); - ao_stop_immediately(instance); - } else { - PERROR - ("Timeout reached. Signal come but status is strange: %d\n", - instance->status); - ao_stop_immediately(instance); - } - - instance->ao_control_task_flag = 0; - cancel_delayed_work(&instance->ao_control_task); - instance->status = ao_status_stream_end; - err = ME_ERRNO_TIMEOUT; - } - } - } - - ME_SUBDEVICE_EXIT; - return err; -} - -static int me6000_ao_io_stream_status(me_subdevice_t *subdevice, - struct file *filep, - int wait, - int *status, int *values, int flags) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) { - PERROR("Invalid wait argument specified.\n"); - *status = ME_STATUS_INVALID; - return ME_ERRNO_INVALID_WAIT; - } - - ME_SUBDEVICE_ENTER; - - switch (instance->status) { - case ao_status_single_configured: - case ao_status_single_end: - case ao_status_stream_configured: - case ao_status_stream_end: - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - *status = ME_STATUS_IDLE; - break; - - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - case ao_status_stream_run_wait: - case ao_status_stream_run: - case ao_status_stream_end_wait: - *status = ME_STATUS_BUSY; - break; - - case ao_status_none: - default: - *status = - (inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM) ? - ME_STATUS_BUSY : ME_STATUS_IDLE; - break; - } - - if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) { - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - ((instance->status != - ao_status_single_run_wait) - && (instance->status != - ao_status_single_run) - && (instance->status != - ao_status_single_end_wait) - && (instance->status != - ao_status_stream_run_wait) - && (instance->status != - ao_status_stream_run) - && (instance->status != - ao_status_stream_end_wait)), - LONG_MAX); - - if (instance->status != ao_status_stream_end) { - PDEBUG("Wait for IDLE canceled. %d\n", - instance->status); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Wait for IDLE interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - - *status = ME_STATUS_IDLE; - } - - *values = me_circ_buf_space(&instance->circ_buf); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice, - struct file *filep, - int stop_mode, int flags) -{ /// @note Stop work and empty buffer and FIFO - int err = ME_ERRNO_SUCCESS; - me6000_ao_subdevice_t *instance; - unsigned long cpu_flags; - volatile uint32_t ctrl; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((stop_mode != ME_STOP_MODE_IMMEDIATE) - && (stop_mode != ME_STOP_MODE_LAST_VALUE)) { - PERROR("Invalid stop mode specified.\n"); - return ME_ERRNO_INVALID_STOP_MODE; - } - - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (instance->status < ao_status_stream_configured) { - //There is nothing to stop! - PERROR("Subdevice not in streaming mode. %d\n", - instance->status); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - ME_SUBDEVICE_ENTER; - - //Mark as stopping. => Software stop. - instance->status = ao_status_stream_end_wait; - - if (stop_mode == ME_STOP_MODE_IMMEDIATE) { //Stopped now! - err = ao_stop_immediately(instance); - } else if (stop_mode == ME_STOP_MODE_LAST_VALUE) { - ctrl = inl(instance->ctrl_reg) & ME6000_AO_CTRL_MODE_MASK; - if (ctrl == ME6000_AO_MODE_WRAPAROUND) { //Hardware wraparound => Hardware stop. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME6000_AO_CTRL_BIT_STOP; - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - } - //Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason. - wait_event_interruptible_timeout(instance->wait_queue, - (instance->status != - ao_status_stream_end_wait), - LONG_MAX); - - if (instance->status != ao_status_stream_end) { - PDEBUG("Stopping stream canceled.\n"); - err = ME_ERRNO_CANCELLED; - } - - if (signal_pending(current)) { - PERROR("Stopping stream interrupted.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - } - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP; - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - if (!flags) { //Reset FIFO - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO; - } - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - if (!flags) { //Reset software buffer - instance->circ_buf.head = 0; - instance->circ_buf.tail = 0; - instance->preloaded_count = 0; - instance->data_count = 0; - } - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_ao_io_stream_write(me_subdevice_t *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me6000_ao_subdevice_t *instance; - unsigned long cpu_flags = 0; - uint32_t reg_copy; - - int copied_from_user = 0; - int left_to_copy_from_user = *count; - - int copied_values; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - //Checking arguments - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { - PERROR("Not a streaming ao.\n"); - return ME_ERRNO_NOT_SUPPORTED; - } - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (*count <= 0) { - PERROR("Invalid count of values specified.\n"); - return ME_ERRNO_INVALID_VALUE_COUNT; - } - - if (values == NULL) { - PERROR("Invalid address of values specified.\n"); - return ME_ERRNO_INVALID_POINTER; - } - - if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) { //The device is in single mode. - PERROR - ("Subdevice must be preinitialize correctly for streaming.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - - switch (write_mode) { - case ME_WRITE_MODE_PRELOAD: - - //Device must be stopped. - if ((instance->status != ao_status_stream_configured) - && (instance->status != ao_status_stream_end)) { - PERROR - ("Subdevice mustn't be runing when 'pre-load' mode is used.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; - } - break; - case ME_WRITE_MODE_NONBLOCKING: - case ME_WRITE_MODE_BLOCKING: - /// @note In blocking mode: When device is not runing and there is not enought space call will blocked up! - /// @note Some other thread must empty buffer by strating engine. - break; - - default: - PERROR("Invalid write mode specified.\n"); - return ME_ERRNO_INVALID_WRITE_MODE; - } - - if (instance->mode & ME6000_AO_WRAP_MODE) { //Wraparound mode. Device must be stopped. - if ((instance->status != ao_status_stream_configured) - && (instance->status != ao_status_stream_end)) { - PERROR - ("Subdevice mustn't be runing when 'pre-load' mode is used.\n"); - return ME_ERRNO_INVALID_WRITE_MODE; - } - } - - if ((instance->mode == ME6000_AO_HW_WRAP_MODE) - && (write_mode != ME_WRITE_MODE_PRELOAD)) { -/* - PERROR("Only 'pre-load' write is acceptable in hardware wraparound mode.\n"); - return ME_ERRNO_PREVIOUS_CONFIG; -*/ - //This is transparent for user. - PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n"); - write_mode = ME_WRITE_MODE_PRELOAD; - } - - ME_SUBDEVICE_ENTER; - - if (write_mode == ME_WRITE_MODE_PRELOAD) { //Init enviroment - preload - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - //Check FIFO - if (!(reg_copy & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) { //FIFO not active. Enable it. - reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_FIFO; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - instance->preloaded_count = 0; - } - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - } - - while (1) { - //Copy to buffer. This step is common for all modes. - copied_from_user = - ao_get_data_from_user(instance, left_to_copy_from_user, - values + (*count - - left_to_copy_from_user)); - left_to_copy_from_user -= copied_from_user; - - reg_copy = inl(instance->status_reg); - if ((instance->status == ao_status_stream_run) && !(reg_copy & ME6000_AO_STATUS_BIT_FSM)) { //BROKEN PIPE! The state machine is stoped but logical status show that should be working. - PERROR("Broken pipe in write.\n"); - err = ME_ERRNO_SUBDEVICE_NOT_RUNNING; - break; - } - - if ((instance->status == ao_status_stream_run) && (instance->mode == ME6000_AO_CONTINOUS) && (reg_copy & ME6000_AO_STATUS_BIT_HF)) { //Continous mode runing and data are below half! - - // Block interrupts. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - reg_copy &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - //Fast copy - copied_values = - ao_write_data(instance, ME6000_AO_FIFO_COUNT / 2, - 0); - if (copied_values > 0) { - instance->circ_buf.tail += copied_values; - instance->circ_buf.tail &= - instance->circ_buf.mask; - continue; - } - //Reset interrupt latch - inl(instance->irq_reset_reg); - - // Activate interrupts. - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - reg_copy = inl(instance->ctrl_reg); - reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(reg_copy, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - reg_copy); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (copied_values == 0) { //This was checked and never should happend! - PERROR_CRITICAL("COPY FINISH WITH 0!\n"); - } - - if (copied_values < 0) { //This was checked and never should happend! - PERROR_CRITICAL("COPY FINISH WITH ERROR!\n"); - instance->status = ao_status_stream_fifo_error; - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - break; - } - } - - if (!left_to_copy_from_user) { //All datas were copied. - break; - } else { //Not all datas were copied. - if (instance->mode & ME6000_AO_WRAP_MODE) { //Error too much datas! Wraparound is limited in size! - PERROR - ("Too much data for wraparound mode! Exceeded size of %ld.\n", - ME6000_AO_CIRC_BUF_COUNT - 1); - err = ME_ERRNO_RING_BUFFER_OVERFLOW; - break; - } - - if (write_mode != ME_WRITE_MODE_BLOCKING) { //Non blocking calls - break; - } - - wait_event_interruptible(instance->wait_queue, - me_circ_buf_space(&instance-> - circ_buf)); - - if (signal_pending(current)) { - PERROR("Writing interrupted by signal.\n"); - instance->status = ao_status_none; - ao_stop_immediately(instance); - err = ME_ERRNO_SIGNAL; - break; - } - - if (instance->status == ao_status_none) { //Reset - PERROR("Writing interrupted by reset.\n"); - err = ME_ERRNO_CANCELLED; - break; - } - } - } - - if (write_mode == ME_WRITE_MODE_PRELOAD) { //Copy data to FIFO - preload - copied_values = - ao_write_data_pooling(instance, ME6000_AO_FIFO_COUNT, - instance->preloaded_count); - instance->preloaded_count += copied_values; - instance->data_count += copied_values; - - if ((instance->mode == ME6000_AO_HW_WRAP_MODE) - && (me_circ_buf_values(&instance->circ_buf) > - ME6000_AO_FIFO_COUNT)) { - PERROR - ("Too much data for hardware wraparound mode! Exceeded size of %d.\n", - ME6000_AO_FIFO_COUNT); - err = ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } - } - - *count = *count - left_to_copy_from_user; - ME_SUBDEVICE_EXIT; - - return err; -} - -static irqreturn_t me6000_ao_isr(int irq, void *dev_id) -{ - me6000_ao_subdevice_t *instance = dev_id; - uint32_t irq_status; - uint32_t ctrl; - uint32_t status; - int count = 0; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inl(instance->irq_status_reg); - if (!(irq_status & (ME6000_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) { - PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n", - jiffies, __func__, instance->ao_idx, irq_status); - return IRQ_NONE; - } - - if (!instance->circ_buf.buf) { - instance->status = ao_status_stream_error; - PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n"); - //Block interrupts. Stop machine. - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Inform user - wake_up_interruptible_all(&instance->wait_queue); - return IRQ_HANDLED; - } - - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_FSM)) { //Too late. Not working! END? BROKEN PIPE? - /// @note Error checking was moved to separate task. - PDEBUG("Interrupt come but ISM is not working!\n"); - //Block interrupts. Stop machine. - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - ctrl |= - ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - /// @note User notification was also moved to separate task. - return IRQ_HANDLED; - } - //General procedure. Process more datas. - -#ifdef MEDEBUG_DEBUG - if (!me_circ_buf_values(&instance->circ_buf)) { //Buffer is empty! - PDEBUG("Circular buffer empty!\n"); - } -#endif - - //Check FIFO - if (status & ME6000_AO_STATUS_BIT_HF) { //OK less than half - - //Block interrupts - ctrl = inl(instance->ctrl_reg); - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ; - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - - do { - //Calculate how many should be copied. - count = - (instance->stop_data_count) ? instance-> - stop_data_count - - instance->data_count : ME6000_AO_FIFO_COUNT / 2; - if (ME6000_AO_FIFO_COUNT / 2 < count) { - count = ME6000_AO_FIFO_COUNT / 2; - } - //Copy data - if (instance->mode == ME6000_AO_CONTINOUS) { //Continous - count = ao_write_data(instance, count, 0); - if (count > 0) { - instance->circ_buf.tail += count; - instance->circ_buf.tail &= - instance->circ_buf.mask; - instance->data_count += count; - - if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) { //Stoping. Whole buffer was copied. - break; - } - } - } else if ((instance->mode == ME6000_AO_SW_WRAP_MODE) && ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS)) { //Wraparound (software) - if (instance->status == ao_status_stream_end_wait) { //We stoping => Copy to the end of the buffer. - count = - ao_write_data(instance, count, 0); - } else { //Copy in wraparound mode. - count = - ao_write_data_wraparound(instance, - count, - instance-> - preloaded_count); - } - - if (count > 0) { - instance->data_count += count; - instance->preloaded_count += count; - instance->preloaded_count %= - me_circ_buf_values(&instance-> - circ_buf); - - if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) { //Stoping. Whole buffer was copied. - break; - } - } - } - - if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) { //End of work. - break; - } - } //Repeat if still is under half fifo - while ((status = - inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF); - - //Unblock interrupts - ctrl = inl(instance->ctrl_reg); - if (count >= 0) { //Copy was successful. - if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. No more interrupts. - PDEBUG("Finishing work. Interrupt disabled.\n"); - instance->status = ao_status_stream_end_wait; - } else if (count > 0) { //Normal work. Enable interrupt. - PDEBUG("Normal work. Enable interrupt.\n"); - ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ; - } else { //Normal work but there are no more data in buffer. Interrupt blocked. stream_write() will unblock it. - PDEBUG - ("No data in software buffer. Interrupt blocked.\n"); - } - } else { //Error during copy. - instance->status = ao_status_stream_fifo_error; - } - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - } else { //?? more than half - PDEBUG - ("Interrupt come but FIFO more than half full! Reset interrupt.\n"); - } - - PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n", - me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail, - instance->circ_buf.head); - PINFO("ISR: Stop count: %d.\n", instance->stop_count); - PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count); - PINFO("ISR: Data count: %d.\n", instance->data_count); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - //Inform user - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -static void me6000_ao_destructor(struct me_subdevice *subdevice) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - instance->ao_control_task_flag = 0; - - // Reset subdevice to asure clean exit. - me6000_ao_io_reset_subdevice(subdevice, NULL, - ME_IO_RESET_SUBDEVICE_NO_FLAGS); - - // Remove any tasks from work queue. This is paranoic because it was done allready in reset(). - if (!cancel_delayed_work(&instance->ao_control_task)) { //Wait 2 ticks to be sure that control task is removed from queue. - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(2); - } - - if (instance->fifo & ME6000_AO_HAS_FIFO) { - if (instance->irq) { - free_irq(instance->irq, instance); - instance->irq = 0; - } - - if (instance->circ_buf.buf) { - PDEBUG("free circ_buf = %p size=%d", - instance->circ_buf.buf, - PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER); - free_pages((unsigned long)instance->circ_buf.buf, - ME6000_AO_CIRC_BUF_SIZE_ORDER); - } - instance->circ_buf.buf = NULL; - } - - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base, - spinlock_t *preload_reg_lock, - uint32_t *preload_flags, - uint32_t *triggering_flags, - int ao_idx, - int fifo, - int irq, - int high_range, - struct workqueue_struct *me6000_wq) -{ - me6000_ao_subdevice_t *subdevice; - int err; - - PDEBUG("executed ID=%d.\n", ao_idx); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me6000_ao_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me6000_ao_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->preload_reg_lock = preload_reg_lock; - subdevice->preload_flags = preload_flags; - subdevice->triggering_flags = triggering_flags; - - /* Store analog output index */ - subdevice->ao_idx = ao_idx; - - /* Store if analog output has fifo */ - subdevice->fifo = fifo; - - if (subdevice->fifo & ME6000_AO_HAS_FIFO) { - /* Allocate and initialize circular buffer */ - subdevice->circ_buf.mask = ME6000_AO_CIRC_BUF_COUNT - 1; - subdevice->circ_buf.buf = - (void *)__get_free_pages(GFP_KERNEL, - ME6000_AO_CIRC_BUF_SIZE_ORDER); - PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf, - ME6000_AO_CIRC_BUF_SIZE); - - if (!subdevice->circ_buf.buf) { - PERROR - ("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - - memset(subdevice->circ_buf.buf, 0, ME6000_AO_CIRC_BUF_SIZE); - } else { - subdevice->circ_buf.mask = 0; - subdevice->circ_buf.buf = NULL; - } - subdevice->circ_buf.head = 0; - subdevice->circ_buf.tail = 0; - - subdevice->status = ao_status_none; - subdevice->ao_control_task_flag = 0; - subdevice->timeout.delay = 0; - subdevice->timeout.start_time = jiffies; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Initialize single value to 0V */ - subdevice->single_value = 0x8000; - subdevice->single_value_in_fifo = 0x8000; - - /* Initialize range boarders */ - if (high_range) { - subdevice->min = ME6000_AO_MIN_RANGE_HIGH; - subdevice->max = ME6000_AO_MAX_RANGE_HIGH; - } else { - subdevice->min = ME6000_AO_MIN_RANGE; - subdevice->max = ME6000_AO_MAX_RANGE; - } - - /* Register interrupt service routine */ - - if (subdevice->fifo & ME6000_AO_HAS_FIFO) { - subdevice->irq = irq; - if (request_irq(subdevice->irq, me6000_ao_isr, - IRQF_DISABLED | IRQF_SHARED, - ME6000_NAME, subdevice)) { - PERROR("Cannot get interrupt line.\n"); - PDEBUG("free circ_buf = %p size=%d", - subdevice->circ_buf.buf, - PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER); - free_pages((unsigned long)subdevice->circ_buf.buf, - ME6000_AO_CIRC_BUF_SIZE_ORDER); - subdevice->circ_buf.buf = NULL; - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - } else { - subdevice->irq = 0; - } - - /* Initialize registers */ - // Only streamed subdevices support interrupts. For the rest this register has no meaning. - subdevice->irq_status_reg = reg_base + ME6000_AO_IRQ_STATUS_REG; - subdevice->preload_reg = reg_base + ME6000_AO_PRELOAD_REG; - - if (ao_idx == 0) { - subdevice->ctrl_reg = reg_base + ME6000_AO_00_CTRL_REG; - subdevice->status_reg = reg_base + ME6000_AO_00_STATUS_REG; - subdevice->fifo_reg = reg_base + ME6000_AO_00_FIFO_REG; - subdevice->timer_reg = reg_base + ME6000_AO_00_TIMER_REG; - subdevice->irq_reset_reg = - reg_base + ME6000_AO_00_IRQ_RESET_REG; - subdevice->single_reg = reg_base + ME6000_AO_00_SINGLE_REG; - } else if (ao_idx == 1) { - subdevice->ctrl_reg = reg_base + ME6000_AO_01_CTRL_REG; - subdevice->status_reg = reg_base + ME6000_AO_01_STATUS_REG; - subdevice->fifo_reg = reg_base + ME6000_AO_01_FIFO_REG; - subdevice->timer_reg = reg_base + ME6000_AO_01_TIMER_REG; - subdevice->irq_reset_reg = - reg_base + ME6000_AO_01_IRQ_RESET_REG; - subdevice->single_reg = reg_base + ME6000_AO_01_SINGLE_REG; - } else if (ao_idx == 2) { - subdevice->ctrl_reg = reg_base + ME6000_AO_02_CTRL_REG; - subdevice->status_reg = reg_base + ME6000_AO_02_STATUS_REG; - subdevice->fifo_reg = reg_base + ME6000_AO_02_FIFO_REG; - subdevice->timer_reg = reg_base + ME6000_AO_02_TIMER_REG; - subdevice->irq_reset_reg = - reg_base + ME6000_AO_02_IRQ_RESET_REG; - subdevice->single_reg = reg_base + ME6000_AO_02_SINGLE_REG; - } else if (ao_idx == 3) { - subdevice->ctrl_reg = reg_base + ME6000_AO_03_CTRL_REG; - subdevice->status_reg = reg_base + ME6000_AO_03_STATUS_REG; - subdevice->fifo_reg = reg_base + ME6000_AO_03_FIFO_REG; - subdevice->timer_reg = reg_base + ME6000_AO_03_TIMER_REG; - subdevice->irq_reset_reg = - reg_base + ME6000_AO_03_IRQ_RESET_REG; - subdevice->single_reg = reg_base + ME6000_AO_03_SINGLE_REG; - } else { - subdevice->ctrl_reg = reg_base + ME6000_AO_DUMY; - subdevice->fifo_reg = reg_base + ME6000_AO_DUMY; - subdevice->timer_reg = reg_base + ME6000_AO_DUMY; - subdevice->irq_reset_reg = reg_base + ME6000_AO_DUMY; - subdevice->single_reg = reg_base + ME6000_AO_DUMY; - - subdevice->status_reg = reg_base + ME6000_AO_SINGLE_STATUS_REG; - if (ao_idx == 4) { - subdevice->single_reg = - reg_base + ME6000_AO_04_SINGLE_REG; - } else if (ao_idx == 5) { - subdevice->single_reg = - reg_base + ME6000_AO_05_SINGLE_REG; - } else if (ao_idx == 6) { - subdevice->single_reg = - reg_base + ME6000_AO_06_SINGLE_REG; - } else if (ao_idx == 7) { - subdevice->single_reg = - reg_base + ME6000_AO_07_SINGLE_REG; - } else if (ao_idx == 8) { - subdevice->single_reg = - reg_base + ME6000_AO_08_SINGLE_REG; - } else if (ao_idx == 9) { - subdevice->single_reg = - reg_base + ME6000_AO_09_SINGLE_REG; - } else if (ao_idx == 10) { - subdevice->single_reg = - reg_base + ME6000_AO_10_SINGLE_REG; - } else if (ao_idx == 11) { - subdevice->single_reg = - reg_base + ME6000_AO_11_SINGLE_REG; - } else if (ao_idx == 12) { - subdevice->single_reg = - reg_base + ME6000_AO_12_SINGLE_REG; - } else if (ao_idx == 13) { - subdevice->single_reg = - reg_base + ME6000_AO_13_SINGLE_REG; - } else if (ao_idx == 14) { - subdevice->single_reg = - reg_base + ME6000_AO_14_SINGLE_REG; - } else if (ao_idx == 15) { - subdevice->single_reg = - reg_base + ME6000_AO_15_SINGLE_REG; - } else { - PERROR_CRITICAL("WRONG SUBDEVICE ID=%d!", ao_idx); - me_subdevice_deinit((me_subdevice_t *) subdevice); - if (subdevice->fifo) { - free_pages((unsigned long)subdevice->circ_buf. - buf, ME6000_AO_CIRC_BUF_SIZE_ORDER); - } - subdevice->circ_buf.buf = NULL; - kfree(subdevice); - return NULL; - } - } -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Override base class methods. */ - subdevice->base.me_subdevice_destructor = me6000_ao_destructor; - subdevice->base.me_subdevice_io_reset_subdevice = - me6000_ao_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me6000_ao_io_single_config; - subdevice->base.me_subdevice_io_single_read = me6000_ao_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me6000_ao_io_single_write; - subdevice->base.me_subdevice_io_stream_config = - me6000_ao_io_stream_config; - subdevice->base.me_subdevice_io_stream_new_values = - me6000_ao_io_stream_new_values; - subdevice->base.me_subdevice_io_stream_write = - me6000_ao_io_stream_write; - subdevice->base.me_subdevice_io_stream_start = - me6000_ao_io_stream_start; - subdevice->base.me_subdevice_io_stream_status = - me6000_ao_io_stream_status; - subdevice->base.me_subdevice_io_stream_stop = me6000_ao_io_stream_stop; - subdevice->base.me_subdevice_query_number_channels = - me6000_ao_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me6000_ao_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me6000_ao_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me6000_ao_query_subdevice_caps_args; - subdevice->base.me_subdevice_query_range_by_min_max = - me6000_ao_query_range_by_min_max; - subdevice->base.me_subdevice_query_number_ranges = - me6000_ao_query_number_ranges; - subdevice->base.me_subdevice_query_range_info = - me6000_ao_query_range_info; - subdevice->base.me_subdevice_query_timer = me6000_ao_query_timer; - - //prepare work queue and work function - subdevice->me6000_workqueue = me6000_wq; - -/* workqueue API changed in kernel 2.6.20 */ - INIT_DELAYED_WORK(&subdevice->ao_control_task, - me6000_ao_work_control_task); - - if (subdevice->fifo) { //Set speed - outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg); - subdevice->hardware_stop_delay = HZ / 10; //100ms - } - - return subdevice; -} - -/** @brief Stop presentation. Preserve FIFOs. -* -* @param instance The subdevice instance (pointer). -*/ -inline int ao_stop_immediately(me6000_ao_subdevice_t *instance) -{ - unsigned long cpu_flags; - uint32_t ctrl; - int timeout; - int i; - uint32_t single_mask; - - if (instance->ao_idx < ME6000_AO_SINGLE_STATUS_OFFSET) - single_mask = 0x0000; - else - single_mask = 0x0001 << (instance->ao_idx - - ME6000_AO_SINGLE_STATUS_OFFSET); - - timeout = - (instance->hardware_stop_delay > - (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10; - for (i = 0; i <= timeout; i++) { - if (instance->fifo) { - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched! - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME6000_AO_CTRL_BIT_STOP | - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP; - ctrl &= - ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ | - ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) { // Exit. - break; - } - } else { - if (!(inl(instance->status_reg) & single_mask)) { // Exit. - break; - } - } - - PINFO("<%s> Wait for stop: %d\n", __func__, i); - - //Still working! - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - if (i > timeout) { - PERROR_CRITICAL("FSM IS BUSY!\n"); - return ME_ERRNO_INTERNAL; - } - return ME_ERRNO_SUCCESS; -} - -/** @brief Copy data from circular buffer to fifo (fast) in wraparound. -* @note This is time critical function. Checking is done at begining and end only. -* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied data. -* @return On error/success: 0. No datas were copied => no data in buffer. -* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW. -*/ -inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is time critical function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int i = 1; - - if (count <= 0) { //Wrong count! - return 0; - } - - while (i < local_count) { - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - if (pos == instance->circ_buf.head) { - pos = instance->circ_buf.tail; - } - i++; - } - - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied! - PERROR("idx=%d FIFO is full before all datas were copied!\n", - instance->ao_idx); - return -ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } else { //Add last value - value = *(instance->circ_buf.buf + pos); - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - } - - PINFO("idx=%d WRAPAROUND LOADED %d values\n", instance->ao_idx, - local_count); - return local_count; -} - -/** @brief Copy data from software buffer to fifo (fast). -* @note This is time critical function. Checking is done at begining and end only. -* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied data. -* @return On error/success: 0. No datas were copied => no data in buffer. -* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW. -*/ -inline int ao_write_data(me6000_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is time critical function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int max_count; - int i = 1; - - if (count <= 0) { //Wrong count! - return 0; - } - - max_count = me_circ_buf_values(&instance->circ_buf) - start_pos; - if (max_count <= 0) { //No data to copy! - return 0; - } - - if (max_count < count) { - local_count = max_count; - } - - while (i < local_count) { - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - i++; - } - - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full before all datas were copied! - PERROR("idx=%d FIFO is full before all datas were copied!\n", - instance->ao_idx); - return -ME_ERRNO_FIFO_BUFFER_OVERFLOW; - } else { //Add last value - value = *(instance->circ_buf.buf + pos); - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - } - - PINFO("idx=%d FAST LOADED %d values\n", instance->ao_idx, local_count); - return local_count; -} - -/** @brief Copy data from software buffer to fifo (slow). -* @note This is slow function that copy all data from buffer to FIFO with full control. -* -* @param instance The subdevice instance (pointer). -* @param count Maximum number of copied data. -* @param start_pos Position of the firs value in buffer. -* -* @return On success: Number of copied values. -* @return On error/success: 0. FIFO was full at begining. -* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW. -*/ -inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count, - int start_pos) -{ /// @note This is slow function! - uint32_t status; - uint32_t value; - int pos = - (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask; - int local_count = count; - int i; - int max_count; - - if (count <= 0) { //Wrong count! - PERROR("idx=%d SLOW LOADED: Wrong count!\n", instance->ao_idx); - return 0; - } - - max_count = me_circ_buf_values(&instance->circ_buf) - start_pos; - if (max_count <= 0) { //No data to copy! - PERROR("idx=%d SLOW LOADED: No data to copy!\n", - instance->ao_idx); - return 0; - } - - if (max_count < count) { - local_count = max_count; - } - - for (i = 0; i < local_count; i++) { - status = inl(instance->status_reg); - if (!(status & ME6000_AO_STATUS_BIT_FF)) { //FIFO is full! - return i; - } - //Get value from buffer - value = *(instance->circ_buf.buf + pos); - //Prepare it - if (instance->ao_idx & 0x1) { - value <<= 16; - } - //Put value to FIFO - outl(value, instance->fifo_reg); - //PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value); - - pos++; - pos &= instance->circ_buf.mask; - } - - PINFO("idx=%d SLOW LOADED %d values\n", instance->ao_idx, local_count); - return local_count; -} - -/** @brief Copy data from user space to circular buffer. -* @param instance The subdevice instance (pointer). -* @param count Number of datas in user space. -* @param user_values Buffer's pointer. -* -* @return On success: Number of copied values. -* @return On error: -ME_ERRNO_INTERNAL. -*/ -inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count, - int *user_values) -{ - int i, err; - int empty_space; - int copied; - int value; - - empty_space = me_circ_buf_space(&instance->circ_buf); - //We have only this space free. - copied = (count < empty_space) ? count : empty_space; - for (i = 0; i < copied; i++) { //Copy from user to buffer - if ((err = get_user(value, (int *)(user_values + i)))) { - PERROR - ("idx=%d BUFFER LOADED: get_user(0x%p) return an error: %d\n", - instance->ao_idx, user_values + i, err); - return -ME_ERRNO_INTERNAL; - } - /// @note The analog output in me6000 series has size of 16 bits. - *(instance->circ_buf.buf + instance->circ_buf.head) = - (uint16_t) value; - instance->circ_buf.head++; - instance->circ_buf.head &= instance->circ_buf.mask; - } - - PINFO("idx=%d BUFFER LOADED %d values\n", instance->ao_idx, copied); - return copied; -} - -static void me6000_ao_work_control_task(struct work_struct *work) -{ - me6000_ao_subdevice_t *instance; - unsigned long cpu_flags = 0; - uint32_t status; - uint32_t ctrl; - uint32_t synch; - int reschedule = 0; - int signaling = 0; - uint32_t single_mask; - - instance = - container_of((void *)work, me6000_ao_subdevice_t, ao_control_task); - PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies, - instance->ao_idx); - - status = inl(instance->status_reg); - PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->status_reg - instance->reg_base, status); - -/// @note AO_STATUS_BIT_FSM doesn't work as should be for pure single channels (idx>=4) -// single_mask = (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET < 0) ? 0x0000 : (0x0001 << (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET)); - single_mask = *instance->triggering_flags & (0x1 << instance->ao_idx); - - switch (instance->status) { // Checking actual mode. - - // Not configured for work. - case ao_status_none: - break; - - //This are stable modes. No need to do anything. (?) - case ao_status_single_configured: - case ao_status_stream_configured: - case ao_status_stream_fifo_error: - case ao_status_stream_buffer_error: - case ao_status_stream_error: - PERROR("Shouldn't be running!.\n"); - break; - - // Single modes - case ao_status_single_run_wait: - case ao_status_single_run: - case ao_status_single_end_wait: - if (instance->fifo) { // Extra registers. - if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. - if (((instance->fifo & ME6000_AO_HAS_FIFO) - && (!(status & ME6000_AO_STATUS_BIT_EF))) - || (!(instance->fifo & ME6000_AO_HAS_FIFO))) { // Single is in end state. - PDEBUG - ("Single call has been complited.\n"); - - // Set correct value for single_read(); - instance->single_value = - instance->single_value_in_fifo; - - // Set status as 'ao_status_single_end' - instance->status = ao_status_single_end; - - spin_lock(instance->preload_reg_lock); - if ((single_mask) && (*instance->preload_flags & (ME6000_AO_SYNC_HOLD << instance->ao_idx))) { // This is one of synchronous start channels. Set all as triggered. - *instance->triggering_flags = - 0x00000000; - } else { - //Set this channel as triggered (none active). - *instance->triggering_flags &= - ~(0x1 << instance->ao_idx); - } - spin_unlock(instance->preload_reg_lock); - - // Signal the end. - signaling = 1; - // Wait for stop ISM. - reschedule = 1; - - break; - } - } - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched! - spin_lock_irqsave(&instance->subdevice_lock, - cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME6000_AO_CTRL_BIT_STOP | - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP; - ctrl &= - ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ | - ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG); - ctrl &= - ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | - ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH); - //Disabling FIFO - ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO; - - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - - instance->reg_base, ctrl); - spin_unlock_irqrestore(&instance-> - subdevice_lock, - cpu_flags); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - spin_lock(instance->preload_reg_lock); - //Remove from synchronous start. Block triggering from this output. - synch = inl(instance->preload_reg); - synch &= - ~((ME6000_AO_SYNC_HOLD | - ME6000_AO_SYNC_EXT_TRIG) << instance-> - ao_idx); - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - set to single safe mode - synch |= - ME6000_AO_SYNC_HOLD << instance-> - ao_idx; - } - outl(synch, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch); - //Set this channel as triggered (none active). - *instance->triggering_flags &= - ~(0x1 << instance->ao_idx); - spin_unlock(instance->preload_reg_lock); - - // Set correct value for single_read(); - instance->single_value_in_fifo = - instance->single_value; - - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - } - } else { // No extra registers. -/* - if (!(status & single_mask)) - {// State machine is not working. - PDEBUG("Single call has been complited.\n"); - - // Set correct value for single_read(); - instance->single_value = instance->single_value_in_fifo; - - // Set status as 'ao_status_single_end' - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - // Wait for stop ISM. - reschedule = 1; - - break; - } -*/ - if (!single_mask) { // Was triggered. - PDEBUG("Single call has been complited.\n"); - - // Set correct value for single_read(); - instance->single_value = - instance->single_value_in_fifo; - - // Set status as 'ao_status_single_end' - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - - break; - } - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - - spin_lock(instance->preload_reg_lock); - //Remove from synchronous start. Block triggering from this output. - synch = inl(instance->preload_reg); - synch &= - ~(ME6000_AO_SYNC_EXT_TRIG << instance-> - ao_idx); - synch |= - ME6000_AO_SYNC_HOLD << instance->ao_idx; - - outl(synch, instance->preload_reg); - PDEBUG_REG - ("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch); - //Set this channel as triggered (none active). - *instance->triggering_flags &= - ~(0x1 << instance->ao_idx); - spin_unlock(instance->preload_reg_lock); - - // Restore old settings. - PDEBUG("Write old value back to register.\n"); - outl(instance->single_value, - instance->single_reg); - PDEBUG_REG - ("single_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->single_reg - instance->reg_base, - instance->single_value); - - // Set correct value for single_read(); - instance->single_value_in_fifo = - instance->single_value; - - instance->status = ao_status_single_end; - - // Signal the end. - signaling = 1; - } - } - - // Wait for stop. - reschedule = 1; - break; - - case ao_status_stream_end: - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - case ao_status_single_end: - if (instance->fifo) { // Extra registers. - if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working but the status is set to end. Force stop. - - // Wait for stop. - reschedule = 1; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - // Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched! - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | - ME6000_AO_CTRL_BIT_STOP; - ctrl &= - ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ | - ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - } else { // No extra registers. -/* - if (status & single_mask) - {// State machine is working but the status is set to end. Force stop. - - // Wait for stop. - reschedule = 1; - } -*/ - } - break; - - // Stream modes - case ao_status_stream_run_wait: - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (status & ME6000_AO_STATUS_BIT_FSM) { // State machine is working. Waiting for start finish. - instance->status = ao_status_stream_run; - - // Signal end of this step - signaling = 1; - } else { // State machine is not working. - if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty. Procedure has started and finish already! - instance->status = ao_status_stream_end; - - // Signal the end. - signaling = 1; - // Wait for stop. - reschedule = 1; - break; - } - } - - // Check timeout. - if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) { // Timeout - PDEBUG("Timeout reached.\n"); - // Stop all actions. No conditions! Block interrupts. Leave FIFO untouched! - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - ctrl = inl(instance->ctrl_reg); - ctrl |= - ME6000_AO_CTRL_BIT_STOP | - ME6000_AO_CTRL_BIT_IMMEDIATE_STOP; - ctrl &= - ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ | - ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG); - outl(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, - ctrl); - spin_unlock_irqrestore(&instance->subdevice_lock, - cpu_flags); - - //Reset interrupt latch - inl(instance->irq_reset_reg); - - spin_lock(instance->preload_reg_lock); - //Remove from synchronous start. Block triggering from this output. - synch = inl(instance->preload_reg); - synch &= - ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << - instance->ao_idx); - outl(synch, instance->preload_reg); - PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->preload_reg - instance->reg_base, - synch); - spin_unlock(instance->preload_reg_lock); - - instance->status = ao_status_stream_end; - - // Signal the end. - signaling = 1; - } - // Wait for stop. - reschedule = 1; - break; - - case ao_status_stream_run: - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. This is an error. - // BROKEN PIPE! - if (!(status & ME6000_AO_STATUS_BIT_EF)) { // FIFO is empty. - if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty. - if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) { //Finishing work. Requed data shown. - PDEBUG - ("ISM stoped. No data in FIFO. Buffer is not empty.\n"); - instance->status = - ao_status_stream_end; - } else { - PERROR - ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n"); - instance->status = - ao_status_stream_buffer_error; - } - } else { // Software buffer is empty. - PDEBUG - ("ISM stoped. No data in FIFO. Buffer is empty.\n"); - instance->status = ao_status_stream_end; - } - } else { // There are still datas in FIFO. - if (me_circ_buf_values(&instance->circ_buf)) { // Software buffer is not empty. - PERROR - ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n"); - } else { // Software buffer is empty. - PERROR - ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n"); - } - instance->status = ao_status_stream_fifo_error; - - } - - // Signal the failure. - signaling = 1; - break; - } - // Wait for stop. - reschedule = 1; - break; - - case ao_status_stream_end_wait: - if (!(instance->fifo & ME6000_AO_HAS_FIFO)) { // No FIFO - PERROR_CRITICAL - ("Streaming on single device! This feature is not implemented in this version!\n"); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - } - - if (!(status & ME6000_AO_STATUS_BIT_FSM)) { // State machine is not working. Waiting for stop finish. - instance->status = ao_status_stream_end; - signaling = 1; - } - // State machine is working. - reschedule = 1; - break; - - default: - PERROR_CRITICAL("Status is in wrong state (%d)!\n", - instance->status); - instance->status = ao_status_stream_error; - // Signal the end. - signaling = 1; - break; - - } - - if (signaling) { //Signal it. - wake_up_interruptible_all(&instance->wait_queue); - } - - if (instance->ao_control_task_flag && reschedule) { // Reschedule task - queue_delayed_work(instance->me6000_workqueue, - &instance->ao_control_task, 1); - } else { - PINFO("<%s> Ending control task.\n", __func__); - } - -} - -static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((*max - *min) < 0) { - PERROR("Invalid minimum and maximum values specified.\n"); - return ME_ERRNO_INVALID_MIN_MAX; - } - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - if ((*max <= (instance->max + 1000)) && (*min >= instance->min)) { - *min = instance->min; - *max = instance->max; - *maxdata = ME6000_AO_MAX_DATA; - *range = 0; - } else { - PERROR("No matching range available.\n"); - return ME_ERRNO_NO_RANGE; - } - } else { - PERROR("Invalid physical unit specified.\n"); - return ME_ERRNO_INVALID_UNIT; - } - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice, - int unit, int *count) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) { - *count = 1; - } else { - *count = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_range_info(me_subdevice_t *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (range == 0) { - *unit = ME_UNIT_VOLT; - *min = instance->min; - *max = instance->max; - *maxdata = ME6000_AO_MAX_DATA; - } else { - PERROR("Invalid range number specified.\n"); - return ME_ERRNO_INVALID_RANGE; - } - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_timer(me_subdevice_t *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (instance->fifo) { //Streaming device. - *base_frequency = ME6000_AO_BASE_FREQUENCY; - if (timer == ME_TIMER_ACQ_START) { - *min_ticks = ME6000_AO_MIN_ACQ_TICKS; - *max_ticks = ME6000_AO_MAX_ACQ_TICKS; - } else if (timer == ME_TIMER_CONV_START) { - *min_ticks = ME6000_AO_MIN_CHAN_TICKS; - *max_ticks = ME6000_AO_MAX_CHAN_TICKS; - } - } else { //Not streaming device! - *base_frequency = 0; - *min_ticks = 0; - *max_ticks = 0; - } - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - me6000_ao_subdevice_t *instance; - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *number = 1; - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - me6000_ao_subdevice_t *instance; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *type = ME_TYPE_AO; - *subtype = - (instance-> - fifo & ME6000_AO_HAS_FIFO) ? ME_SUBTYPE_STREAMING : - ME_SUBTYPE_SINGLE; - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - me6000_ao_subdevice_t *instance; - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - *caps = - ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO : - ME_CAPS_NONE); - - return ME_ERRNO_SUCCESS; -} - -static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count) -{ - me6000_ao_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - instance = (me6000_ao_subdevice_t *) subdevice; - - PDEBUG("executed. idx=%d\n", instance->ao_idx); - - if (count != 1) { - PERROR("Invalid capability argument count.\n"); - return ME_ERRNO_INVALID_CAP_ARG_COUNT; - } - - switch (cap) { - case ME_CAP_AI_FIFO_SIZE: - args[0] = (instance->fifo) ? ME6000_AO_FIFO_COUNT : 0; - break; - - case ME_CAP_AI_BUFFER_SIZE: - args[0] = - (instance->circ_buf.buf) ? ME6000_AO_CIRC_BUF_COUNT : 0; - break; - - default: - PERROR("Invalid capability.\n"); - err = ME_ERRNO_INVALID_CAP; - args[0] = 0; - } - - return err; -} diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h deleted file mode 100644 index d86fb29265f..00000000000 --- a/drivers/staging/meilhaus/me6000_ao.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file me6000_ao.h - * - * @brief Meilhaus ME-6000 analog output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME6000_AO_H_ -#define _ME6000_AO_H_ - -#include "mesubdevice.h" -#include "mecirc_buf.h" -#include "meioctl.h" - -#ifdef __KERNEL__ - -#define ME6000_AO_MAX_SUBDEVICES 16 -#define ME6000_AO_FIFO_COUNT 8192 - -#define ME6000_AO_BASE_FREQUENCY 33000000L - -#define ME6000_AO_MIN_ACQ_TICKS 0LL -#define ME6000_AO_MAX_ACQ_TICKS 0LL - -#define ME6000_AO_MIN_CHAN_TICKS 66LL -#define ME6000_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL - -#define ME6000_AO_MIN_RANGE -10000000 -#define ME6000_AO_MAX_RANGE 9999694 - -#define ME6000_AO_MIN_RANGE_HIGH 0 -#define ME6000_AO_MAX_RANGE_HIGH 49999237 - -#define ME6000_AO_MAX_DATA 0xFFFF - -#ifdef ME_SYNAPSE -# define ME6000_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse -#else -# define ME6000_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB -#endif -#define ME6000_AO_CIRC_BUF_SIZE PAGE_SIZE< bit 0 in ME6000_AO_SINGLE_STATUS_REG. - -#define ME6000_AO_04_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_04_SINGLE_REG 0x74 // _/W - -#define ME6000_AO_05_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_05_SINGLE_REG 0x78 // _/W - -#define ME6000_AO_06_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_06_SINGLE_REG 0x7C // _/W - -#define ME6000_AO_07_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_07_SINGLE_REG 0x80 // _/W - -#define ME6000_AO_08_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_08_SINGLE_REG 0x84 // _/W - -#define ME6000_AO_09_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_09_SINGLE_REG 0x88 // _/W - -#define ME6000_AO_10_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_10_SINGLE_REG 0x8C // _/W - -#define ME6000_AO_11_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_11_SINGLE_REG 0x90 // _/W - -#define ME6000_AO_12_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_12_SINGLE_REG 0x94 // _/W - -#define ME6000_AO_13_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_13_SINGLE_REG 0x98 // _/W - -#define ME6000_AO_14_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_14_SINGLE_REG 0x9C // _/W - -#define ME6000_AO_15_STATUS_REG ME6000_AO_SINGLE_STATUS_REG -#define ME6000_AO_15_SINGLE_REG 0xA0 // _/W - -//ME6000_AO_CTRL_REG -#define ME6000_AO_MODE_SINGLE 0x00 -#define ME6000_AO_MODE_WRAPAROUND 0x01 -#define ME6000_AO_MODE_CONTINUOUS 0x02 -#define ME6000_AO_CTRL_MODE_MASK (ME6000_AO_MODE_WRAPAROUND | ME6000_AO_MODE_CONTINUOUS) - -#define ME6000_AO_CTRL_BIT_MODE_WRAPAROUND 0x001 -#define ME6000_AO_CTRL_BIT_MODE_CONTINUOUS 0x002 -#define ME6000_AO_CTRL_BIT_STOP 0x004 -#define ME6000_AO_CTRL_BIT_ENABLE_FIFO 0x008 -#define ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010 -#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020 -#define ME6000_AO_CTRL_BIT_ENABLE_IRQ 0x040 -#define ME6000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080 -#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 0x800 - -//ME6000_AO_STATUS_REG -#define ME6000_AO_STATUS_BIT_FSM 0x01 -#define ME6000_AO_STATUS_BIT_FF 0x02 -#define ME6000_AO_STATUS_BIT_HF 0x04 -#define ME6000_AO_STATUS_BIT_EF 0x08 - -#define ME6000_AO_PRELOAD_REG 0xA8 // R/W ///ME6000_AO_SYNC_REG <==> ME6000_AO_PRELOAD_REG -/* -#define ME6000_AO_SYNC_HOLD_0 0x00000001 -#define ME6000_AO_SYNC_HOLD_1 0x00000002 -#define ME6000_AO_SYNC_HOLD_2 0x00000004 -#define ME6000_AO_SYNC_HOLD_3 0x00000008 -#define ME6000_AO_SYNC_HOLD_4 0x00000010 -#define ME6000_AO_SYNC_HOLD_5 0x00000020 -#define ME6000_AO_SYNC_HOLD_6 0x00000040 -#define ME6000_AO_SYNC_HOLD_7 0x00000080 -#define ME6000_AO_SYNC_HOLD_8 0x00000100 -#define ME6000_AO_SYNC_HOLD_9 0x00000200 -#define ME6000_AO_SYNC_HOLD_10 0x00000400 -#define ME6000_AO_SYNC_HOLD_11 0x00000800 -#define ME6000_AO_SYNC_HOLD_12 0x00001000 -#define ME6000_AO_SYNC_HOLD_13 0x00002000 -#define ME6000_AO_SYNC_HOLD_14 0x00004000 -#define ME6000_AO_SYNC_HOLD_15 0x00008000 -*/ -#define ME6000_AO_SYNC_HOLD 0x00000001 -/* -#define ME6000_AO_SYNC_EXT_TRIG_0 0x00010000 -#define ME6000_AO_SYNC_EXT_TRIG_1 0x00020000 -#define ME6000_AO_SYNC_EXT_TRIG_2 0x00040000 -#define ME6000_AO_SYNC_EXT_TRIG_3 0x00080000 -#define ME6000_AO_SYNC_EXT_TRIG_4 0x00100000 -#define ME6000_AO_SYNC_EXT_TRIG_5 0x00200000 -#define ME6000_AO_SYNC_EXT_TRIG_6 0x00400000 -#define ME6000_AO_SYNC_EXT_TRIG_7 0x00800000 -#define ME6000_AO_SYNC_EXT_TRIG_8 0x01000000 -#define ME6000_AO_SYNC_EXT_TRIG_9 0x02000000 -#define ME6000_AO_SYNC_EXT_TRIG_10 0x04000000 -#define ME6000_AO_SYNC_EXT_TRIG_11 0x08000000 -#define ME6000_AO_SYNC_EXT_TRIG_12 0x10000000 -#define ME6000_AO_SYNC_EXT_TRIG_13 0x20000000 -#define ME6000_AO_SYNC_EXT_TRIG_14 0x40000000 -#define ME6000_AO_SYNC_EXT_TRIG_15 0x80000000 -*/ -#define ME6000_AO_SYNC_EXT_TRIG 0x00010000 - -#define ME6000_AO_EXT_TRIG 0x80000000 - -// AO-IRQ -#define ME6000_AO_IRQ_STATUS_REG 0x60 // R/_ -#define ME6000_AO_00_IRQ_RESET_REG 0x64 // R/_ -#define ME6000_AO_01_IRQ_RESET_REG 0x68 // R/_ -#define ME6000_AO_02_IRQ_RESET_REG 0x6C // R/_ -#define ME6000_AO_03_IRQ_RESET_REG 0x70 // R/_ - -#define ME6000_IRQ_STATUS_BIT_0 0x01 -#define ME6000_IRQ_STATUS_BIT_1 0x02 -#define ME6000_IRQ_STATUS_BIT_2 0x04 -#define ME6000_IRQ_STATUS_BIT_3 0x08 - -#define ME6000_IRQ_STATUS_BIT_AO_HF ME6000_IRQ_STATUS_BIT_0 - -//DUMY register -#define ME6000_AO_DUMY 0xFC -#endif -#endif diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c deleted file mode 100644 index 1a6cf7f4325..00000000000 --- a/drivers/staging/meilhaus/me6000_device.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file me6000_device.c - * - * @brief Device class template implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "mefirmware.h" - -#include "mesubdevice.h" -#include "medebug.h" -#include "medevice.h" -#include "me6000_reg.h" -#include "me6000_device.h" -#include "meplx_reg.h" -#include "me6000_dio.h" -#include "me6000_ao.h" - -/** - * @brief Global variable. - * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts). - */ -static struct workqueue_struct *me6000_workqueue; - -me_device_t *me6000_pci_constructor(struct pci_dev *pci_device) -{ - me6000_device_t *me6000_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - int high_range = 0; - int fifo; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me6000_device = kmalloc(sizeof(me6000_device_t), GFP_KERNEL); - - if (!me6000_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me6000_device, 0, sizeof(me6000_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me6000_device, pci_device); - - if (err) { - kfree(me6000_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Download the xilinx firmware */ - err = me_xilinx_download(me6000_device->base.info.pci.reg_bases[1], - me6000_device->base.info.pci.reg_bases[2], - &pci_device->dev, "me6000.bin"); - - if (err) { - me_device_deinit((me_device_t *) me6000_device); - kfree(me6000_device); - PERROR("Can't download firmware.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - me6000_versions_get_device_index(me6000_device->base.info.pci. - device_id); - - // Initialize spin lock . - spin_lock_init(&me6000_device->preload_reg_lock); - spin_lock_init(&me6000_device->dio_ctrl_reg_lock); - - /* Create digital input/output instances. */ - for (i = 0; i < me6000_versions[version_idx].dio_subdevices; i++) { - subdevice = - (me_subdevice_t *) me6000_dio_constructor(me6000_device-> - base.info.pci. - reg_bases[3], i, - &me6000_device-> - dio_ctrl_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me6000_device); - kfree(me6000_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me6000_device->base.slist, - subdevice); - } - - /* Create analog output instances. */ - for (i = 0; i < me6000_versions[version_idx].ao_subdevices; i++) { - high_range = ((i == 8) - && - ((me6000_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME6359) - || (me6000_device->base.info.pci.device_id == - PCI_DEVICE_ID_MEILHAUS_ME6259) - ) - )? 1 : 0; - - fifo = - (i < - me6000_versions[version_idx]. - ao_fifo) ? ME6000_AO_HAS_FIFO : 0x0; - fifo |= (i < 4) ? ME6000_AO_EXTRA_HARDWARE : 0x0; - - subdevice = - (me_subdevice_t *) me6000_ao_constructor(me6000_device-> - base.info.pci. - reg_bases[2], - &me6000_device-> - preload_reg_lock, - &me6000_device-> - preload_flags, - &me6000_device-> - triggering_flags, - i, fifo, - me6000_device-> - base.irq, - high_range, - me6000_workqueue); - - if (!subdevice) { - me_device_deinit((me_device_t *) me6000_device); - kfree(me6000_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me6000_device->base.slist, - subdevice); - } - - return (me_device_t *) me6000_device; -} -EXPORT_SYMBOL(me6000_pci_constructor); - -// Init and exit of module. - -static int __init me6000_init(void) -{ - PDEBUG("executed.\n"); - - me6000_workqueue = create_singlethread_workqueue("me6000"); - return 0; -} - -static void __exit me6000_exit(void) -{ - PDEBUG("executed.\n"); - - flush_workqueue(me6000_workqueue); - destroy_workqueue(me6000_workqueue); -} - -module_init(me6000_init); -module_exit(me6000_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me6000_device.h b/drivers/staging/meilhaus/me6000_device.h deleted file mode 100644 index eed40115210..00000000000 --- a/drivers/staging/meilhaus/me6000_device.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file me6000_device.h - * - * @brief ME-6000 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME6000_DEVICE_H -#define _ME6000_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-6000 device capabilities. - */ -typedef struct me6000_version { - uint16_t device_id; - unsigned int dio_subdevices; - unsigned int ao_subdevices; - unsigned int ao_fifo; //How many devices have FIFO -} me6000_version_t; - -/** - * @brief ME-6000 device capabilities. - */ -static me6000_version_t me6000_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME6004, 0, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6008, 0, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME600F, 0, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6014, 0, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6018, 0, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME601F, 0, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6034, 0, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6038, 0, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME603F, 0, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6104, 0, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6108, 0, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME610F, 0, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6114, 0, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6118, 0, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME611F, 0, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6134, 0, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6138, 0, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME613F, 0, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6044, 2, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6048, 2, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME604F, 2, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6054, 2, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6058, 2, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME605F, 2, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6074, 2, 4, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME6078, 2, 8, 0}, - {PCI_DEVICE_ID_MEILHAUS_ME607F, 2, 16, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6144, 2, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6148, 2, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME614F, 2, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6154, 2, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6158, 2, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME615F, 2, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6174, 2, 4, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME6178, 2, 8, 4}, - {PCI_DEVICE_ID_MEILHAUS_ME617F, 2, 16, 4}, - - {PCI_DEVICE_ID_MEILHAUS_ME6259, 2, 9, 0}, - - {PCI_DEVICE_ID_MEILHAUS_ME6359, 2, 9, 4}, - - {0}, -}; - -#define ME6000_DEVICE_VERSIONS (ARRAY_SIZE(me6000_versions) - 1) /**< Returns the number of entries in #me6000_versions. */ - -/** - * @brief Returns the index of the device entry in #me6000_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me6000_versions. - */ -static inline unsigned int me6000_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME6000_DEVICE_VERSIONS; i++) - if (me6000_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-6000 device class structure. - */ -typedef struct me6000_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t preload_reg_lock; /**< Guards the preload register. */ - uint32_t preload_flags; - uint32_t triggering_flags; - - spinlock_t dio_ctrl_reg_lock; -} me6000_device_t; - -/** - * @brief The ME-6000 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-6000 device instance. \n - * NULL on error. - */ -me_device_t *me6000_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c deleted file mode 100644 index c90686efc38..00000000000 --- a/drivers/staging/meilhaus/me6000_dio.c +++ /dev/null @@ -1,415 +0,0 @@ -/** - * @file me6000_dio.c - * - * @brief ME-6000 digital input/output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me6000_dio_reg.h" -#include "me6000_dio.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me6000_dio_subdevice_t *instance; - uint8_t mode; - - PDEBUG("executed.\n"); - - instance = (me6000_dio_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - mode &= ~(0x3 << (instance->dio_idx * 2)); - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - - outb(0x00, instance->port_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, 0x00); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me6000_dio_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me6000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - int size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - - PDEBUG("executed.\n"); - - instance = (me6000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - mode &= - ~((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - mode &= - ~((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - mode |= - ME6000_DIO_CTRL_BIT_MODE_0 << (instance-> - dio_idx * 2); - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_dio_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me6000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - - PDEBUG("executed.\n"); - - instance = (me6000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - if ((mode == - (ME6000_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = - inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - if ((mode == - (ME6000_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = inb(instance->port_reg) & 0x00FF; - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_dio_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me6000_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - uint8_t byte; - - PDEBUG("executed.\n"); - - instance = (me6000_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME6000_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - byte = inb(instance->port_reg) & 0x00FF; - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outb(byte, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 | - ME6000_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME6000_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - outb(value, instance->port_reg); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me6000_dio_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_DIR_BYTE; - return ME_ERRNO_SUCCESS; -} - -me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t *ctrl_reg_lock) -{ - me6000_dio_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me6000_dio_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me6000_dio_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - - /* Set the subdevice ports */ - subdevice->ctrl_reg = reg_base + ME6000_DIO_CTRL_REG; - switch (dio_idx) { - case 0: - subdevice->port_reg = reg_base + ME6000_DIO_PORT_0_REG; - break; - case 1: - subdevice->port_reg = reg_base + ME6000_DIO_PORT_1_REG; - break; - default: - err = ME_ERRNO_INVALID_SUBDEVICE; - } - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save digital i/o index */ - subdevice->dio_idx = dio_idx; - -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me6000_dio_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me6000_dio_io_single_config; - subdevice->base.me_subdevice_io_single_read = me6000_dio_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me6000_dio_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me6000_dio_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me6000_dio_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me6000_dio_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me6000_dio.h b/drivers/staging/meilhaus/me6000_dio.h deleted file mode 100644 index 858bec1c459..00000000000 --- a/drivers/staging/meilhaus/me6000_dio.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file me6000_dio.h - * - * @brief ME-6000 digital input/output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME6000_DIO_H_ -#define _ME6000_DIO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me6000_dio_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - unsigned int dio_idx; /**< The index of the digital i/o on the device. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me6000_dio_subdevice_t; - -/** - * @brief The constructor to generate a ME-6000 digital input/ouput subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param dio_idx The index of the digital i/o port on the device. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me6000_dio_reg.h b/drivers/staging/meilhaus/me6000_dio_reg.h deleted file mode 100644 index e67a791a1e6..00000000000 --- a/drivers/staging/meilhaus/me6000_dio_reg.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file me6000_dio_reg.h - * - * @brief ME-6000 digital input/output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME6000_DIO_REG_H_ -#define _ME6000_DIO_REG_H_ - -#ifdef __KERNEL__ - -#define ME6000_DIO_CTRL_REG 0x00 // R/W -#define ME6000_DIO_PORT_0_REG 0x01 // R/W -#define ME6000_DIO_PORT_1_REG 0x02 // R/W -#define ME6000_DIO_PORT_REG ME6000_DIO_PORT_0_REG // R/W - -#define ME6000_DIO_CTRL_BIT_MODE_0 0x01 -#define ME6000_DIO_CTRL_BIT_MODE_1 0x02 -#define ME6000_DIO_CTRL_BIT_MODE_2 0x04 -#define ME6000_DIO_CTRL_BIT_MODE_3 0x08 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me6000_reg.h b/drivers/staging/meilhaus/me6000_reg.h deleted file mode 100644 index d3527300341..00000000000 --- a/drivers/staging/meilhaus/me6000_reg.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file me6000_reg.h - * - * @brief ME-6000 device register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME6000_REG_H_ -#define _ME6000_REG_H_ - -#ifdef __KERNEL__ - -#define ME6000_INIT_XILINX_REG 0xAC // R/- - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c deleted file mode 100644 index 41a9345cee5..00000000000 --- a/drivers/staging/meilhaus/me8100_device.c +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file me8100_device.c - * - * @brief ME-8100 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "me8100_device.h" -#include "mesubdevice.h" -#include "me8100_di.h" -#include "me8100_do.h" -#include "me8254.h" - -me_device_t *me8100_pci_constructor(struct pci_dev *pci_device) -{ - me8100_device_t *me8100_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me8100_device = kmalloc(sizeof(me8100_device_t), GFP_KERNEL); - - if (!me8100_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me8100_device, 0, sizeof(me8100_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me8100_device, pci_device); - - if (err) { - kfree(me8100_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - me8100_versions_get_device_index(me8100_device->base.info.pci. - device_id); - - // Initialize spin lock . - spin_lock_init(&me8100_device->dio_ctrl_reg_lock); - spin_lock_init(&me8100_device->ctr_ctrl_reg_lock); - spin_lock_init(&me8100_device->clk_src_reg_lock); - - // Create subdevice instances. - - for (i = 0; i < me8100_versions[version_idx].di_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8100_di_constructor(me8100_device-> - base.info.pci. - reg_bases[2], - me8100_device-> - base.info.pci. - reg_bases[1], i, - me8100_device-> - base.irq, - &me8100_device-> - dio_ctrl_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8100_device); - kfree(me8100_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8100_device->base.slist, - subdevice); - } - - for (i = 0; i < me8100_versions[version_idx].do_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8100_do_constructor(me8100_device-> - base.info.pci. - reg_bases[2], i, - &me8100_device-> - dio_ctrl_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8100_device); - kfree(me8100_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8100_device->base.slist, - subdevice); - } - - for (i = 0; i < me8100_versions[version_idx].ctr_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8254_constructor(me8100_device->base. - info.pci.device_id, - me8100_device->base. - info.pci.reg_bases[2], - 0, i, - &me8100_device-> - ctr_ctrl_reg_lock, - &me8100_device-> - clk_src_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8100_device); - kfree(me8100_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8100_device->base.slist, - subdevice); - } - - return (me_device_t *) me8100_device; -} -EXPORT_SYMBOL(me8100_pci_constructor); - -// Init and exit of module. - -static int __init me8100_init(void) -{ - PDEBUG("executed.\n."); - return ME_ERRNO_SUCCESS; -} - -static void __exit me8100_exit(void) -{ - PDEBUG("executed.\n."); -} - -module_init(me8100_init); - -module_exit(me8100_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR("Guenter Gebhardt "); -MODULE_DESCRIPTION("Device Driver Module for Template Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me8100_device.h b/drivers/staging/meilhaus/me8100_device.h deleted file mode 100644 index 238dc062280..00000000000 --- a/drivers/staging/meilhaus/me8100_device.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file me8100_device.h - * - * @brief ME-8100 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_DEVICE_H -#define _ME8100_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-8100 device capabilities. - */ -typedef struct me8100_version { - uint16_t device_id; - unsigned int di_subdevices; - unsigned int do_subdevices; - unsigned int ctr_subdevices; -} me8100_version_t; - -/** - * @brief Device capabilities. - */ -static me8100_version_t me8100_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME8100_A, 1, 1, 3}, - {PCI_DEVICE_ID_MEILHAUS_ME8100_B, 2, 2, 3}, - {0}, -}; - -#define ME8100_DEVICE_VERSIONS (ARRAY_SIZE(me8100_versions) - 1) /**< Returns the number of entries in #me8100_versions. */ - -/** - * @brief Returns the index of the device entry in #me8100_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me8100_versions. - */ -static inline unsigned int me8100_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME8100_DEVICE_VERSIONS; i++) - if (me8100_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-8100 device class structure. - */ -typedef struct me8100_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t dio_ctrl_reg_lock; - spinlock_t ctr_ctrl_reg_lock; - spinlock_t clk_src_reg_lock; -} me8100_device_t; - -/** - * @brief The ME-8100 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-8100 device instance. \n - * NULL on error. - */ -me_device_t *me8100_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c deleted file mode 100644 index 1a3f2692d7a..00000000000 --- a/drivers/staging/meilhaus/me8100_di.c +++ /dev/null @@ -1,684 +0,0 @@ -/** - * @file me8100_di.c - * - * @brief ME-8100 digital input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meerror.h" - -#include "meids.h" -#include "medebug.h" -#include "meplx_reg.h" -#include "me8100_reg.h" -#include "me8100_di_reg.h" -#include "me8100_di.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8100_di_subdevice_t *instance; - unsigned short ctrl; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->ctrl_reg_lock); - ctrl = inw(instance->ctrl_reg); - ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0); - outw(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->ctrl_reg_lock); - - outw(0, instance->mask_reg); - PDEBUG_REG("mask_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->mask_reg - instance->reg_base, 0); - outw(0, instance->pattern_reg); - PDEBUG_REG("pattern_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->pattern_reg - instance->reg_base, 0); - instance->rised = -1; - instance->irq_count = 0; - instance->filtering_flag = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - outl(PLX_INTCSR_LOCAL_INT1_EN | - PLX_INTCSR_LOCAL_INT1_POL | - PLX_INTCSR_LOCAL_INT2_EN | - PLX_INTCSR_LOCAL_INT2_POL | - PLX_INTCSR_PCI_INT_EN, instance->irq_status_reg); - PDEBUG_REG("plx:irq_status_reg outl(0x%lX)=0x%x\n", - instance->irq_status_reg, - PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL | - PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL | - PLX_INTCSR_PCI_INT_EN); - - wake_up_interruptible_all(&instance->wait_queue); - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8100_di_io_irq_start(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me8100_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint16_t ctrl; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - if (flags & - ~(ME_IO_IRQ_START_PATTERN_FILTERING | - ME_IO_IRQ_START_DIO_WORD)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (irq_edge != ME_IRQ_EDGE_NOT_USED) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - if (flags & - ~(ME_IO_IRQ_START_EXTENDED_STATUS | - ME_IO_IRQ_START_DIO_WORD)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (irq_edge != ME_IRQ_EDGE_ANY) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - - if (!(irq_arg & 0xFFFF)) { - PERROR("No mask specified.\n"); - return ME_ERRNO_INVALID_IRQ_ARG; - } - } else { - PERROR("Invalid irq source specified.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - outw(irq_arg, instance->pattern_reg); - instance->compare_value = irq_arg; - instance->filtering_flag = - (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0; - } - if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - outw(irq_arg, instance->mask_reg); - } - - spin_lock(instance->ctrl_reg_lock); - ctrl = inw(instance->ctrl_reg); - ctrl |= ME8100_DIO_CTRL_BIT_INTB_0; - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - ctrl &= ~ME8100_DIO_CTRL_BIT_INTB_1; - } - - if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - ctrl |= ME8100_DIO_CTRL_BIT_INTB_1; - } - outw(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->ctrl_reg_lock); - - instance->rised = 0; - instance->status_value = 0; - instance->status_value_edges = 0; - instance->line_value = inw(instance->port_reg); - instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_di_io_irq_wait(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me8100_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - unsigned long cpu_flags; - int count; - - PDEBUG("executed.\n"); - PDEVELOP("PID: %d.\n", current->pid); - - instance = (me8100_di_subdevice_t *) subdevice; - - if (flags & - ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - count = instance->irq_count; - - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - ((count != - instance-> - irq_count) - || (instance-> - rised < 0)), - t); -// t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t); - if (t == 0) { - PERROR("Wait on interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - ((count != instance->irq_count) - || (instance->rised < 0))); -// wait_event_interruptible(instance->wait_queue, (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - *irq_count = instance->irq_count; - if (!err) { - if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) { - *value = instance->status_value; - } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) { - *value = instance->status_value_edges; - } else { // Use default - if (!instance->status_flag) { - *value = instance->status_value; - } else { - *value = instance->status_value_edges; - } - } - instance->rised = 0; -/* - instance->status_value = 0; - instance->status_value_edges = 0; -*/ - } else { - *value = 0; - } - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_di_io_irq_stop(me_subdevice_t *subdevice, - struct file *filep, int channel, int flags) -{ - me8100_di_subdevice_t *instance; - uint16_t ctrl; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->ctrl_reg_lock); - ctrl = inw(instance->ctrl_reg); - ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0); - outw(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->ctrl_reg_lock); - instance->rised = -1; - instance->status_value = 0; - instance->status_value_edges = 0; - instance->filtering_flag = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8100_di_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8100_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_WORD: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_di_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8100_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - - switch (flags) { - - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 16)) { - *value = inw(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inw(instance->port_reg) & 0xFF; - } else if (channel == 1) { - *value = (inw(instance->port_reg) >> 8) & 0xFF; - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_WORD: - if (channel == 0) { - *value = inw(instance->port_reg); - } else { - PERROR("Invalid word number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_di_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 16; - return ME_ERRNO_SUCCESS; -} - -static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8100_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY; - return ME_ERRNO_SUCCESS; -} - -static void me8100_di_destructor(struct me_subdevice *subdevice) -{ - me8100_di_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) subdevice; - - free_irq(instance->irq, (void *)instance); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -static irqreturn_t me8100_isr(int irq, void *dev_id) -{ - me8100_di_subdevice_t *instance; - uint32_t icsr; - - uint16_t irq_status; - uint16_t line_value = 0; - - uint32_t status_val = 0; - - PDEBUG("executed.\n"); - - instance = (me8100_di_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - icsr = inl(instance->irq_status_reg); - if (instance->di_idx == 0) { - - if ((icsr & - (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN | - PLX_INTCSR_LOCAL_INT1_EN)) != - (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN | - PLX_INTCSR_LOCAL_INT1_EN)) { - PINFO - ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n", - jiffies, __func__, icsr); - return IRQ_NONE; - } - } else if (instance->di_idx == 1) { - if ((icsr & - (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN | - PLX_INTCSR_LOCAL_INT2_EN)) != - (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN | - PLX_INTCSR_LOCAL_INT2_EN)) { - PINFO - ("%ld Shared interrupt. %s(): idx=1 plx:irq_status_reg=0x%04X\n", - jiffies, __func__, icsr); - return IRQ_NONE; - } - } else { - PERROR("%s():Wrong interrupt idx=%d csr=0x%X.\n", __func__, - instance->di_idx, icsr); - return IRQ_NONE; - } - - PDEBUG("me8100_isr():Interrupt from idx=%d occured.\n", - instance->di_idx); - spin_lock(&instance->subdevice_lock); - inw(instance->irq_reset_reg); - line_value = inw(instance->port_reg); - - irq_status = instance->line_value ^ line_value; - - // Make extended information. - status_val |= (0x00FF & (~(uint16_t) instance->line_value & line_value)) << 16; //Raise - status_val |= (0x00FF & ((uint16_t) instance->line_value & ~line_value)); //Fall - - instance->line_value = line_value; - - if (instance->rised == 0) { - instance->status_value = irq_status; - instance->status_value_edges = status_val; - } else { - instance->status_value |= irq_status; - instance->status_value_edges |= status_val; - } - - if (instance->filtering_flag) { // For compare mode only. - if (instance->compare_value == instance->line_value) { - instance->rised = 1; - instance->irq_count++; - } - } else { - instance->rised = 1; - instance->irq_count++; - } - - spin_unlock(&instance->subdevice_lock); - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base, - uint32_t plx_reg_base, - unsigned int di_idx, - int irq, - spinlock_t *ctrl_reg_lock) -{ - me8100_di_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8100_di_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8100_di_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the subdevice index. */ - subdevice->di_idx = di_idx; - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Register interrupt service routine. */ - subdevice->irq = irq; - err = request_irq(subdevice->irq, me8100_isr, - IRQF_DISABLED | IRQF_SHARED, - ME8100_NAME, (void *)subdevice); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", subdevice->irq); - - /* Initialize the registers */ - subdevice->ctrl_reg = - me8100_reg_base + ME8100_CTRL_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->port_reg = - me8100_reg_base + ME8100_DI_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->mask_reg = - me8100_reg_base + ME8100_MASK_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->pattern_reg = - me8100_reg_base + ME8100_PATTERN_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->din_int_reg = - me8100_reg_base + ME8100_INT_DI_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->irq_reset_reg = - me8100_reg_base + ME8100_RES_INT_REG_A + di_idx * ME8100_REG_OFFSET; - subdevice->irq_status_reg = plx_reg_base + PLX_INTCSR; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = me8100_reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_irq_start = me8100_di_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me8100_di_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me8100_di_io_irq_stop; - subdevice->base.me_subdevice_io_reset_subdevice = - me8100_di_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me8100_di_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8100_di_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me8100_di_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8100_di_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8100_di_query_subdevice_caps; - subdevice->base.me_subdevice_destructor = me8100_di_destructor; - - subdevice->rised = 0; - subdevice->irq_count = 0; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8100_di.h b/drivers/staging/meilhaus/me8100_di.h deleted file mode 100644 index e1db7912917..00000000000 --- a/drivers/staging/meilhaus/me8100_di.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file me8100_di.h - * - * @brief ME-8100 digital input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_DI_H_ -#define _ME8100_DI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me8100_di_subdevice { - // Inheritance - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; - - unsigned di_idx; - - int irq; - volatile int rised; - unsigned int irq_count; - - uint status_flag; /**< Default interupt status flag */ - uint status_value; /**< Interupt status */ - uint status_value_edges; /**< Extended interupt status */ - uint line_value; - - uint16_t compare_value; - uint8_t filtering_flag; - - wait_queue_head_t wait_queue; - - unsigned long ctrl_reg; - unsigned long port_reg; - unsigned long mask_reg; - unsigned long pattern_reg; - unsigned long long din_int_reg; - unsigned long irq_reset_reg; - unsigned long irq_status_reg; -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif - -} me8100_di_subdevice_t; - -/** - * @brief The constructor to generate a ME-8100 digital input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base, - uint32_t plx_reg_base, - unsigned int di_idx, - int irq, - spinlock_t * ctrl_leg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_di_reg.h b/drivers/staging/meilhaus/me8100_di_reg.h deleted file mode 100644 index 063bd193709..00000000000 --- a/drivers/staging/meilhaus/me8100_di_reg.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @file me8100_di_reg.h - * - * @brief ME-8100 digital input subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_DI_REG_H_ -#define _ME8100_DI_REG_H_ - -#ifdef __KERNEL__ - -#define ME8100_RES_INT_REG_A 0x02 //(r, ) -#define ME8100_DI_REG_A 0x04 //(r, ) -#define ME8100_PATTERN_REG_A 0x08 //( ,w) -#define ME8100_MASK_REG_A 0x0A //( ,w) -#define ME8100_INT_DI_REG_A 0x0A //(r, ) - -#define ME8100_RES_INT_REG_B 0x0E //(r, ) -#define ME8100_DI_REG_B 0x10 //(r, ) -#define ME8100_PATTERN_REG_B 0x14 //( ,w) -#define ME8100_MASK_REG_B 0x16 //( ,w) -#define ME8100_INT_DI_REG_B 0x16 //(r, ) - -#define ME8100_REG_OFFSET 0x0C - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c deleted file mode 100644 index 81651a90cc0..00000000000 --- a/drivers/staging/meilhaus/me8100_do.c +++ /dev/null @@ -1,391 +0,0 @@ -/** - * @file me8100_do.c - * - * @brief ME-8100 digital output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me8100_reg.h" -#include "me8100_do_reg.h" -#include "me8100_do.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8100_do_subdevice_t *instance; - uint16_t ctrl; - - PDEBUG("executed.\n"); - - instance = (me8100_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - ctrl = inw(instance->ctrl_reg); - ctrl &= ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0; - outw(ctrl, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->ctrl_reg_lock); - outw(0, instance->port_reg); - instance->port_reg_mirror = 0; - PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8100_do_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8100_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - int config; - - PDEBUG("executed.\n"); - - instance = (me8100_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - config = inw(instance->ctrl_reg); - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_WORD: - if (channel == 0) { - if (single_config == - ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE) { - config &= ~(ME8100_DIO_CTRL_BIT_ENABLE_DIO); - } else if (single_config == ME_SINGLE_CONFIG_DIO_SINK) { - config |= ME8100_DIO_CTRL_BIT_ENABLE_DIO; - config &= ~ME8100_DIO_CTRL_BIT_SOURCE; - } else if (single_config == ME_SINGLE_CONFIG_DIO_SOURCE) { - config |= - ME8100_DIO_CTRL_BIT_ENABLE_DIO | - ME8100_DIO_CTRL_BIT_SOURCE; - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid word number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outw(config, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, config); - } - - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_do_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8100_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8100_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 16)) { - *value = instance->port_reg_mirror & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = instance->port_reg_mirror & 0xFF; - } else if (channel == 1) { - *value = (instance->port_reg_mirror >> 8) & 0xFF; - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_WORD: - if (channel == 0) { - *value = instance->port_reg_mirror; - } else { - PERROR("Invalid word number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_do_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me8100_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8100_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 16)) { - instance->port_reg_mirror = - value ? (instance-> - port_reg_mirror | (0x1 << channel)) - : (instance->port_reg_mirror & ~(0x1 << channel)); - outw(instance->port_reg_mirror, instance->port_reg); - PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - instance->port_reg_mirror); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - instance->port_reg_mirror &= ~0xFF; - instance->port_reg_mirror |= value & 0xFF; - outw(instance->port_reg_mirror, instance->port_reg); - PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - instance->port_reg_mirror); - } else if (channel == 1) { - instance->port_reg_mirror &= ~0xFF00; - instance->port_reg_mirror |= (value << 8) & 0xFF00; - outw(instance->port_reg_mirror, instance->port_reg); - PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - instance->port_reg_mirror); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_WORD: - if (channel == 0) { - instance->port_reg_mirror = value; - outw(value, instance->port_reg); - PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - value); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8100_do_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 16; - return ME_ERRNO_SUCCESS; -} - -static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_SINK_SOURCE; - return ME_ERRNO_SUCCESS; -} - -me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base, - unsigned int do_idx, - spinlock_t *ctrl_reg_lock) -{ - me8100_do_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8100_do_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8100_do_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - - /* Initialize registers */ - if (do_idx == 0) { - subdevice->port_reg = reg_base + ME8100_DO_REG_A; - subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_A; - } else if (do_idx == 1) { - subdevice->port_reg = reg_base + ME8100_DO_REG_B; - subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_B; - } else { - PERROR("Wrong subdevice idx=%d.\n", do_idx); - kfree(subdevice); - return NULL; - } -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the subdevice index */ - subdevice->do_idx = do_idx; - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me8100_do_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me8100_do_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8100_do_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me8100_do_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me8100_do_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8100_do_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8100_do_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8100_do.h b/drivers/staging/meilhaus/me8100_do.h deleted file mode 100644 index acf88013666..00000000000 --- a/drivers/staging/meilhaus/me8100_do.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file me8100_do.h - * - * @brief ME-8100 digital output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_DO_H_ -#define _ME8100_DO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me8100_do_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the #ctrl_reg. */ - - unsigned int do_idx; - - uint16_t port_reg_mirror; /**< Mirror used to store current port register setting which is write only. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Control register. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me8100_do_subdevice_t; - -/** - * @brief The constructor to generate a ME-8100 digital output subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param do_idx The index of the digital output subdevice on this device. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base, - unsigned int do_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_do_reg.h b/drivers/staging/meilhaus/me8100_do_reg.h deleted file mode 100644 index 13a23802b31..00000000000 --- a/drivers/staging/meilhaus/me8100_do_reg.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file me8100_ao_reg.h - * - * @brief ME-8100 analog output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_DO_REG_H_ -#define _ME8100_DO_REG_H_ - -#ifdef __KERNEL__ - -#define ME8100_DO_REG_A 0x06 //( ,w) -#define ME8100_DO_REG_B 0x12 //( ,w) - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8100_reg.h b/drivers/staging/meilhaus/me8100_reg.h deleted file mode 100644 index d8c4b1c6b15..00000000000 --- a/drivers/staging/meilhaus/me8100_reg.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file me8100_reg.h - * - * @brief ME-8100 register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8100_REG_H_ -#define _ME8100_REG_H_ - -#ifdef __KERNEL__ - -#define ME8100_CTRL_REG_A 0x00 //( ,w) -#define ME8100_CTRL_REG_B 0x0C //( ,w) - -#define ME8100_DIO_CTRL_BIT_SOURCE 0x10 -#define ME8100_DIO_CTRL_BIT_INTB_1 0x20 -#define ME8100_DIO_CTRL_BIT_INTB_0 0x40 -#define ME8100_DIO_CTRL_BIT_ENABLE_DIO 0x80 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c deleted file mode 100644 index b313679fc5c..00000000000 --- a/drivers/staging/meilhaus/me8200_device.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file me8200_device.c - * - * @brief ME-8200 device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include "meids.h" -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "meplx_reg.h" -#include "medevice.h" -#include "me8200_device.h" -#include "mesubdevice.h" -#include "me8200_di.h" -#include "me8200_do.h" -#include "me8200_dio.h" - -me_device_t *me8200_pci_constructor(struct pci_dev *pci_device) -{ - me8200_device_t *me8200_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - me8200_device = kmalloc(sizeof(me8200_device_t), GFP_KERNEL); - - if (!me8200_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(me8200_device, 0, sizeof(me8200_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) me8200_device, pci_device); - - if (err) { - kfree(me8200_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - me8200_versions_get_device_index(me8200_device->base.info.pci. - device_id); - - // Initialize spin lock . - spin_lock_init(&me8200_device->irq_ctrl_lock); - spin_lock_init(&me8200_device->irq_mode_lock); - spin_lock_init(&me8200_device->dio_ctrl_lock); - - /* Setup the PLX interrupt configuration */ - outl(PLX_INTCSR_LOCAL_INT1_EN | - PLX_INTCSR_LOCAL_INT1_POL | - PLX_INTCSR_LOCAL_INT2_EN | - PLX_INTCSR_LOCAL_INT2_POL | - PLX_INTCSR_PCI_INT_EN, - me8200_device->base.info.pci.reg_bases[1] + PLX_INTCSR); - - // Create subdevice instances. - - for (i = 0; i < me8200_versions[version_idx].di_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8200_di_constructor(me8200_device-> - base.info.pci. - reg_bases[2], i, - me8200_device-> - base.irq, - &me8200_device-> - irq_ctrl_lock, - &me8200_device-> - irq_mode_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8200_device); - kfree(me8200_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8200_device->base.slist, - subdevice); - } - - for (i = 0; i < me8200_versions[version_idx].do_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8200_do_constructor(me8200_device-> - base.info.pci. - reg_bases[2], i, - me8200_device-> - base.irq, - &me8200_device-> - irq_mode_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8200_device); - kfree(me8200_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8200_device->base.slist, - subdevice); - } - - for (i = 0; i < me8200_versions[version_idx].dio_subdevices; i++) { - subdevice = - (me_subdevice_t *) me8200_dio_constructor(me8200_device-> - base.info.pci. - reg_bases[2], i, - &me8200_device-> - dio_ctrl_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) me8200_device); - kfree(me8200_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&me8200_device->base.slist, - subdevice); - } - - return (me_device_t *) me8200_device; -} -EXPORT_SYMBOL(me8200_pci_constructor); - -// Init and exit of module. - -static int __init me8200_init(void) -{ - PDEBUG("executed.\n."); - return 0; -} - -static void __exit me8200_exit(void) -{ - PDEBUG("executed.\n."); -} - -module_init(me8200_init); - -module_exit(me8200_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR("Guenter Gebhardt "); -MODULE_DESCRIPTION("Device Driver Module for Template Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/me8200_device.h b/drivers/staging/meilhaus/me8200_device.h deleted file mode 100644 index 66f50842dac..00000000000 --- a/drivers/staging/meilhaus/me8200_device.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file me8200_device.h - * - * @brief ME-8200 device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DEVICE_H -#define _ME8200_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding ME-8200 device capabilities. - */ -typedef struct me8200_version { - uint16_t device_id; - unsigned int di_subdevices; - unsigned int do_subdevices; - unsigned int dio_subdevices; -} me8200_version_t; - -/** - * @brief Device capabilities. - */ -static me8200_version_t me8200_versions[] = { - {PCI_DEVICE_ID_MEILHAUS_ME8200_A, 1, 1, 2}, - {PCI_DEVICE_ID_MEILHAUS_ME8200_B, 2, 2, 2}, - {0}, -}; - -#define ME8200_DEVICE_VERSIONS (ARRAY_SIZE(me8200_versions) - 1) /**< Returns the number of entries in #me8200_versions. */ - -/** - * @brief Returns the index of the device entry in #me8200_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #me8200_versions. - */ -static inline unsigned int me8200_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < ME8200_DEVICE_VERSIONS; i++) - if (me8200_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The ME-8200 device class structure. - */ -typedef struct me8200_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t irq_ctrl_lock; /**< Lock for the interrupt control register. */ - spinlock_t irq_mode_lock; /**< Lock for the interrupt mode register. */ - spinlock_t dio_ctrl_lock; /**< Lock for the digital i/o control register. */ -} me8200_device_t; - -/** - * @brief The ME-8200 device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new ME-8200 device instance. \n - * NULL on error. - */ -me_device_t *me8200_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c deleted file mode 100644 index fd1af0f0565..00000000000 --- a/drivers/staging/meilhaus/me8200_di.c +++ /dev/null @@ -1,832 +0,0 @@ -/** - * @file me8200_di.c - * - * @brief ME-8200 digital input subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -///Includes -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meerror.h" - -#include "meids.h" -#include "medebug.h" -#include "me8200_reg.h" -#include "me8200_di_reg.h" -#include "me8200_di.h" - -/// Defines -static void me8200_di_destructor(struct me_subdevice *subdevice); -static int me8200_di_io_irq_start(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags); -static int me8200_di_io_irq_wait(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags); -static int me8200_di_io_irq_stop(me_subdevice_t *subdevice, - struct file *filep, int channel, int flags); -static int me8200_di_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags); -static int me8200_di_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags); -static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags); -static int me8200_di_query_number_channels(me_subdevice_t *subdevice, - int *number); -static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype); -static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps); -static irqreturn_t me8200_isr(int irq, void *dev_id); -static irqreturn_t me8200_isr_EX(int irq, void *dev_id); -static void me8200_di_check_version(me8200_di_subdevice_t *instance, - unsigned long addr); - -///Functions -static int me8200_di_io_irq_start(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me8200_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - volatile uint8_t tmp; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_di_subdevice_t *) subdevice; - - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - if (flags & - ~(ME_IO_IRQ_START_PATTERN_FILTERING | - ME_IO_IRQ_START_DIO_BYTE)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (irq_edge != ME_IRQ_EDGE_NOT_USED) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - } else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - if (flags & - ~(ME_IO_IRQ_START_EXTENDED_STATUS | - ME_IO_IRQ_START_DIO_BYTE)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if ((irq_edge != ME_IRQ_EDGE_RISING) - && (irq_edge != ME_IRQ_EDGE_FALLING) - && (irq_edge != ME_IRQ_EDGE_ANY)) { - PERROR("Invalid irq edge specified.\n"); - return ME_ERRNO_INVALID_IRQ_EDGE; - } - - if (!(irq_arg & 0xFF)) { - PERROR("No mask specified.\n"); - return ME_ERRNO_INVALID_IRQ_ARG; - } - } else { - PERROR("Invalid irq source specified.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - outb(irq_arg, instance->compare_reg); - PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->compare_reg - instance->reg_base, irq_arg); - outb(0xFF, instance->mask_reg); - PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->mask_reg - instance->reg_base, 0xff); - instance->compare_value = irq_arg; - instance->filtering_flag = - (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0; - } - if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - outb(irq_arg, instance->mask_reg); - PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->mask_reg - instance->reg_base, irq_arg); - instance->filtering_flag = 0; - } - - spin_lock(instance->irq_mode_lock); - tmp = inb(instance->irq_mode_reg); - tmp &= - ~(ME8200_IRQ_MODE_MASK << - (ME8200_IRQ_MODE_DI_SHIFT * instance->di_idx)); - if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) { - tmp |= - ME8200_IRQ_MODE_MASK_COMPARE << (ME8200_IRQ_MODE_DI_SHIFT * - instance->di_idx); - } - - if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - tmp |= - ME8200_IRQ_MODE_MASK_MASK << (ME8200_IRQ_MODE_DI_SHIFT * - instance->di_idx); - } - outb(tmp, instance->irq_mode_reg); - PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_mode_reg - instance->reg_base, tmp); - spin_unlock(instance->irq_mode_lock); - - spin_lock(instance->irq_ctrl_lock); - tmp = inb(instance->irq_ctrl_reg); - tmp |= - (ME8200_DI_IRQ_CTRL_BIT_CLEAR << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - tmp |= - ME8200_DI_IRQ_CTRL_BIT_ENABLE << (ME8200_DI_IRQ_CTRL_SHIFT * - instance->di_idx); - - if (irq_source == ME_IRQ_SOURCE_DIO_MASK) { - tmp &= - ~(ME8200_DI_IRQ_CTRL_MASK_EDGE << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - if (irq_edge == ME_IRQ_EDGE_RISING) { - tmp |= - ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx); - } else if (irq_edge == ME_IRQ_EDGE_FALLING) { - tmp |= - ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx); - } else if (irq_edge == ME_IRQ_EDGE_ANY) { - tmp |= - ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx); - } - } - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - tmp &= - ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - - instance->line_value = inb(instance->port_reg); - spin_unlock(instance->irq_ctrl_lock); - - instance->rised = 0; - instance->status_value = 0; - instance->status_value_edges = 0; - instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS; - spin_unlock_irqrestore(&instance->subdevice_lock, status); - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_di_io_irq_wait(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me8200_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - unsigned long cpu_flags; - int count; - - PDEBUG("executed.\n"); - PDEVELOP("PID: %d.\n", current->pid); - - instance = (me8200_di_subdevice_t *) subdevice; - - if (flags & - ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - count = instance->count; - - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - ((count != - instance->count) - || (instance-> - rised < 0)), - t); -// t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t); - if (t == 0) { - PERROR("Wait on interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - ((count != instance->count) - || (instance->rised < 0))); -// wait_event_interruptible(instance->wait_queue, (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - *irq_count = instance->count; - if (!err) { - if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) { - *value = instance->status_value; - } else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) { - *value = instance->status_value_edges; - } else { // Use default - if (!instance->status_flag) { - *value = instance->status_value; - } else { - *value = instance->status_value_edges; - } - } - instance->rised = 0; -/* - instance->status_value = 0; - instance->status_value_edges = 0; -*/ - } else { - *value = 0; - } - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_di_io_irq_stop(me_subdevice_t *subdevice, - struct file *filep, int channel, int flags) -{ - me8200_di_subdevice_t *instance; - uint8_t tmp; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_di_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status); - spin_lock(instance->irq_ctrl_lock); - tmp = inb(instance->irq_ctrl_reg); - tmp |= - (ME8200_DI_IRQ_CTRL_BIT_ENABLE << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - tmp &= - ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - tmp |= - (ME8200_DI_IRQ_CTRL_BIT_CLEAR << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); -// tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->irq_ctrl_lock); - - instance->rised = -1; - instance->status_value = 0; - instance->status_value_edges = 0; - instance->filtering_flag = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, status); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8200_di_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8200_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - } else { - PERROR("Invalid port direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_di_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8200_di_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_di_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_reg); - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8200_di_subdevice_t *instance = (me8200_di_subdevice_t *) subdevice; - - PDEBUG("executed.\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - instance->count = 0; - return me8200_di_io_irq_stop(subdevice, filep, 0, 0); -} - -static int me8200_di_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DI; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = - ME_CAPS_DIO_BIT_PATTERN_IRQ | - ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING | - ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING | - ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY; - return ME_ERRNO_SUCCESS; -} - -static irqreturn_t me8200_isr(int irq, void *dev_id) -{ - me8200_di_subdevice_t *instance; - uint8_t ctrl; - uint8_t irq_status; - uint8_t line_value = 0; - uint8_t line_status = 0; - uint32_t status_val = 0; - - instance = (me8200_di_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inb(instance->irq_status_reg); - if (!irq_status) { - PINFO - ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n", - jiffies, __func__, instance->di_idx, irq_status); - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->irq_ctrl_lock); - ctrl = inb(instance->irq_ctrl_reg); - ctrl |= - ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * - instance->di_idx); - outb(ctrl, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, ctrl); - ctrl &= - ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << - (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx)); - outb(ctrl, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, ctrl); - - line_value = inb(instance->port_reg); - spin_unlock(instance->irq_ctrl_lock); - - line_status = ((uint8_t) instance->line_value ^ line_value); - - // Make extended information. - status_val |= (0x00FF & (~(uint8_t) instance->line_value & line_value)) << 16; //Raise - status_val |= (0x00FF & ((uint8_t) instance->line_value & ~line_value)); //Fall - - instance->line_value = (int)line_value; - - if (instance->rised == 0) { - instance->status_value = irq_status | line_status; - instance->status_value_edges = status_val; - } else { - instance->status_value |= irq_status | line_status; - instance->status_value_edges |= status_val; - } - - if (instance->filtering_flag) { // For compare mode only. - if (instance->compare_value == instance->line_value) { - instance->rised = 1; - instance->count++; - } - } else { - instance->rised = 1; - instance->count++; - } - spin_unlock(&instance->subdevice_lock); - - spin_unlock(&instance->subdevice_lock); - - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -static irqreturn_t me8200_isr_EX(int irq, void *dev_id) -{ - me8200_di_subdevice_t *instance; - uint8_t irq_status = 0; - uint16_t irq_status_EX = 0; - uint32_t status_val = 0; - int i, j; - - instance = (me8200_di_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - //Reset latches. Copy status to extended registers. - irq_status = inb(instance->irq_status_reg); - PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance->di_idx, - irq_status); - - if (!irq_status) { - PINFO - ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n", - jiffies, __func__, instance->di_idx, irq_status); - return IRQ_NONE; - } - - irq_status_EX = inb(instance->irq_status_low_reg); - irq_status_EX |= (inb(instance->irq_status_high_reg) << 8); - - PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX); - instance->line_value = inb(instance->port_reg); - - // Format extended information. - for (i = 0, j = 0; i < 8; i++, j += 2) { - status_val |= ((0x01 << j) & irq_status_EX) >> (j - i); //Fall - status_val |= ((0x01 << (j + 1)) & irq_status_EX) << (15 - j + i); //Raise - } - - spin_lock(&instance->subdevice_lock); - if (instance->rised == 0) { - instance->status_value = irq_status; - instance->status_value_edges = status_val; - } else { - instance->status_value |= irq_status; - instance->status_value_edges |= status_val; - } - - if (instance->filtering_flag) { // For compare mode only. - if (instance->compare_value == instance->line_value) { - instance->rised = 1; - instance->count++; - } - } else { - instance->rised = 1; - instance->count++; - } - spin_unlock(&instance->subdevice_lock); - - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -static void me8200_di_destructor(struct me_subdevice *subdevice) -{ - me8200_di_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me8200_di_subdevice_t *) subdevice; - - free_irq(instance->irq, (void *)instance); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase, - unsigned int di_idx, - int irq, - spinlock_t *irq_ctrl_lock, - spinlock_t *irq_mode_lock) -{ - me8200_di_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8200_di_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Check firmware version. - me8200_di_check_version(subdevice, - me8200_regbase + ME8200_FIRMWARE_VERSION_REG); - - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->irq_ctrl_lock = irq_ctrl_lock; - subdevice->irq_mode_lock = irq_mode_lock; - - /* Save the subdevice index. */ - subdevice->di_idx = di_idx; - - /* Initialize registers */ - if (di_idx == 0) { - subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_0_REG; - subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_0_REG; - subdevice->compare_reg = - me8200_regbase + ME8200_DI_COMPARE_0_REG; - subdevice->irq_status_reg = - me8200_regbase + ME8200_DI_CHANGE_0_REG; - - subdevice->irq_status_low_reg = - me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_LOW_REG; - subdevice->irq_status_high_reg = - me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_HIGH_REG; - } else if (di_idx == 1) { - subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_1_REG; - subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_1_REG; - subdevice->compare_reg = - me8200_regbase + ME8200_DI_COMPARE_1_REG; - subdevice->irq_status_reg = - me8200_regbase + ME8200_DI_CHANGE_1_REG; - - subdevice->irq_status_low_reg = - me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_LOW_REG; - subdevice->irq_status_high_reg = - me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_HIGH_REG; - } else { - PERROR("Wrong subdevice idx=%d.\n", di_idx); - kfree(subdevice); - return NULL; - } - subdevice->irq_ctrl_reg = me8200_regbase + ME8200_DI_IRQ_CTRL_REG; - subdevice->irq_mode_reg = me8200_regbase + ME8200_IRQ_MODE_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = me8200_regbase; -#endif - - /* Initialize wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_irq_start = me8200_di_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me8200_di_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me8200_di_io_irq_stop; - subdevice->base.me_subdevice_io_reset_subdevice = - me8200_di_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me8200_di_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8200_di_io_single_read; - subdevice->base.me_subdevice_query_number_channels = - me8200_di_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8200_di_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8200_di_query_subdevice_caps; - subdevice->base.me_subdevice_destructor = me8200_di_destructor; - - subdevice->rised = 0; - subdevice->count = 0; - - /* Register interrupt service routine. */ - subdevice->irq = irq; - if (subdevice->version > 0) { // NEW - err = request_irq(subdevice->irq, me8200_isr_EX, - IRQF_DISABLED | IRQF_SHARED, - ME8200_NAME, (void *)subdevice); - } else { //OLD - err = request_irq(subdevice->irq, me8200_isr, - IRQF_DISABLED | IRQF_SHARED, - ME8200_NAME, (void *)subdevice); - } - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - PDEBUG("Registred irq=%d.\n", subdevice->irq); - - return subdevice; -} - -static void me8200_di_check_version(me8200_di_subdevice_t *instance, - unsigned long addr) -{ - - PDEBUG("executed.\n"); - instance->version = 0x000000FF & inb(addr); - PDEVELOP("me8200 firmware version: %d\n", instance->version); - - /// @note Fix for wrong values in this registry. - if ((instance->version < 0x7) || (instance->version > 0x1F)) - instance->version = 0x0; -} diff --git a/drivers/staging/meilhaus/me8200_di.h b/drivers/staging/meilhaus/me8200_di.h deleted file mode 100644 index 2a3b005b67d..00000000000 --- a/drivers/staging/meilhaus/me8200_di.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file me8200_di.h - * - * @brief ME-8200 digital input subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DI_H_ -#define _ME8200_DI_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me8200_di_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; - spinlock_t *irq_ctrl_lock; - spinlock_t *irq_mode_lock; - - unsigned int di_idx; - unsigned int version; - - int irq; /**< The number of the interrupt request. */ - volatile int rised; /**< Flag to indicate if an interrupt occured. */ - uint status_flag; /**< Default interupt status flag */ - uint status_value; /**< Interupt status */ - uint status_value_edges; /**< Extended interupt status */ - uint line_value; - int count; /**< Counts the number of interrupts occured. */ - uint8_t compare_value; - uint8_t filtering_flag; - - wait_queue_head_t wait_queue; /**< To wait on interrupts. */ - - unsigned long port_reg; /**< The digital input port. */ - unsigned long compare_reg; /**< The register to hold the value to compare with. */ - unsigned long mask_reg; /**< The register to hold the mask. */ - unsigned long irq_mode_reg; /**< The interrupt mode register. */ - unsigned long irq_ctrl_reg; /**< The interrupt control register. */ - unsigned long irq_status_reg; /**< The interrupt status register. Also interrupt reseting register (firmware version 7 and later).*/ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif - unsigned long firmware_version_reg; /**< The interrupt reseting register. */ - - unsigned long irq_status_low_reg; /**< The interrupt extended status register (low part). */ - unsigned long irq_status_high_reg; /**< The interrupt extended status register (high part). */ -} me8200_di_subdevice_t; - -/** - * @brief The constructor to generate a ME-8200 digital input subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_reg_base, - unsigned int di_idx, - int irq, - spinlock_t * irq_ctrl_lock, - spinlock_t * irq_mode_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_di_reg.h b/drivers/staging/meilhaus/me8200_di_reg.h deleted file mode 100644 index b9a619d31c2..00000000000 --- a/drivers/staging/meilhaus/me8200_di_reg.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file me8200_di_reg.h - * - * @brief ME-8200 digital input subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DI_REG_H_ -#define _ME8200_DI_REG_H_ - -#ifdef __KERNEL__ - -// Common registry for whole family. -#define ME8200_DI_PORT_0_REG 0x3 // R -#define ME8200_DI_PORT_1_REG 0x4 // R - -#define ME8200_DI_MASK_0_REG 0x5 // R/W -#define ME8200_DI_MASK_1_REG 0x6 // R/W - -#define ME8200_DI_COMPARE_0_REG 0xA // R/W -#define ME8200_DI_COMPARE_1_REG 0xB // R/W - -#define ME8200_DI_IRQ_CTRL_REG 0xC // R/W - -#ifndef ME8200_IRQ_MODE_REG -# define ME8200_IRQ_MODE_REG 0xD // R/W -#endif - -// This registry are for all versions -#define ME8200_DI_CHANGE_0_REG 0xE // R -#define ME8200_DI_CHANGE_1_REG 0xF // R - -#define ME8200_DI_IRQ_CTRL_BIT_CLEAR 0x4 -#define ME8200_DI_IRQ_CTRL_BIT_ENABLE 0x8 - -// This registry are for firmware versions 7 and later -#define ME8200_DI_EXTEND_CHANGE_0_LOW_REG 0x10 // R -#define ME8200_DI_EXTEND_CHANGE_0_HIGH_REG 0x11 // R -#define ME8200_DI_EXTEND_CHANGE_1_LOW_REG 0x12 // R -#define ME8200_DI_EXTEND_CHANGE_1_HIGH_REG 0x13 // R - -#ifndef ME8200_FIRMWARE_VERSION_REG -# define ME8200_FIRMWARE_VERSION_REG 0x14 // R -#endif - -// Bit definitions -#define ME8200_DI_IRQ_CTRL_MASK_EDGE 0x3 -#define ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING 0x0 -#define ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING 0x1 -#define ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY 0x3 - -// Others -#define ME8200_DI_IRQ_CTRL_SHIFT 4 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c deleted file mode 100644 index c7f43f011f3..00000000000 --- a/drivers/staging/meilhaus/me8200_dio.c +++ /dev/null @@ -1,418 +0,0 @@ -/** - * @file me8200_dio.c - * - * @brief ME-8200 digital input/output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me8200_dio_reg.h" -#include "me8200_dio.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8200_dio_subdevice_t *instance; - uint8_t mode; - - PDEBUG("executed.\n"); - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - instance = (me8200_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - mode &= ~(0x3 << (instance->dio_idx * 2)); - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - spin_unlock(instance->ctrl_reg_lock); - outb(0x00, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0x00); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8200_dio_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8200_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint32_t mode; - uint32_t size = - flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE - | ME_IO_SINGLE_CONFIG_DIO_WORD | - ME_IO_SINGLE_CONFIG_DIO_DWORD); - - PDEBUG("executed.\n"); - - instance = (me8200_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - mode = inb(instance->ctrl_reg); - switch (size) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - mode &= - ~((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - mode &= - ~((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - mode |= - ME8200_DIO_CTRL_BIT_MODE_0 << (instance-> - dio_idx * 2); - } else { - PERROR - ("Invalid port configuration specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid channel number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - - break; - - default: - PERROR("Invalid flags.\n"); - - err = ME_ERRNO_INVALID_FLAGS; - } - - if (!err) { - outb(mode, instance->ctrl_reg); - PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->ctrl_reg - instance->reg_base, mode); - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_dio_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8200_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - - PDEBUG("executed.\n"); - - instance = (me8200_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if ((mode == - (ME8200_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = - inb(instance-> - port_reg) & (0x0001 << channel); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if ((mode == - (ME8200_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) || !mode) { - *value = inb(instance->port_reg) & 0x00FF; - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_dio_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me8200_dio_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t mode; - uint8_t byte; - - PDEBUG("executed.\n"); - - instance = (me8200_dio_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - mode = - inb(instance-> - ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME8200_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - byte = inb(instance->port_reg); - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outb(byte, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, byte); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - mode = - inb(instance-> - ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 | - ME8200_DIO_CTRL_BIT_MODE_1) << - (instance->dio_idx * 2)); - - if (mode == - (ME8200_DIO_CTRL_BIT_MODE_0 << - (instance->dio_idx * 2))) { - outb(value, instance->port_reg); - PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - - instance->reg_base, value); - } else { - PERROR("Port not in output or input mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(instance->ctrl_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_dio_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_DIR_BYTE; - return ME_ERRNO_SUCCESS; -} - -me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t *ctrl_reg_lock) -{ - me8200_dio_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8200_dio_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8200_dio_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save digital i/o index */ - subdevice->dio_idx = dio_idx; - - /* Save the subdevice index */ - subdevice->ctrl_reg = reg_base + ME8200_DIO_CTRL_REG; - subdevice->port_reg = reg_base + ME8200_DIO_PORT_REG + dio_idx; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me8200_dio_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me8200_dio_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8200_dio_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me8200_dio_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me8200_dio_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8200_dio_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8200_dio_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8200_dio.h b/drivers/staging/meilhaus/me8200_dio.h deleted file mode 100644 index 9ddd93d26f1..00000000000 --- a/drivers/staging/meilhaus/me8200_dio.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file me8200_dio.h - * - * @brief ME-8200 digital input/output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DIO_H_ -#define _ME8200_DIO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me8200_dio_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - unsigned int dio_idx; /**< The index of the digital i/o on the device. */ - - unsigned long port_reg; /**< Register holding the port status. */ - unsigned long ctrl_reg; /**< Register to configure the port direction. */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me8200_dio_subdevice_t; - -/** - * @brief The constructor to generate a ME-8200 digital input/ouput subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param dio_idx The index of the digital i/o port on the device. - * @param ctrl_reg_lock Spin lock protecting the control register. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base, - unsigned int dio_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_dio_reg.h b/drivers/staging/meilhaus/me8200_dio_reg.h deleted file mode 100644 index ac94a133aba..00000000000 --- a/drivers/staging/meilhaus/me8200_dio_reg.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file me8200_dio_reg.h - * - * @brief ME-8200 digital input/output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DIO_REG_H_ -#define _ME8200_DIO_REG_H_ - -#ifdef __KERNEL__ - -#define ME8200_DIO_CTRL_REG 0x7 // R/W -#define ME8200_DIO_PORT_0_REG 0x8 // R/W -#define ME8200_DIO_PORT_1_REG 0x9 // R/W -#define ME8200_DIO_PORT_REG ME8200_DIO_PORT_0_REG // R/W - -#define ME8200_DIO_CTRL_BIT_MODE_0 0x01 -#define ME8200_DIO_CTRL_BIT_MODE_1 0x02 -#define ME8200_DIO_CTRL_BIT_MODE_2 0x04 -#define ME8200_DIO_CTRL_BIT_MODE_3 0x08 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c deleted file mode 100644 index e42a137617a..00000000000 --- a/drivers/staging/meilhaus/me8200_do.c +++ /dev/null @@ -1,591 +0,0 @@ -/** - * @file me8200_do.c - * - * @brief ME-8200 digital output subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "meids.h" -#include "medebug.h" -#include "me8200_reg.h" -#include "me8200_do_reg.h" -#include "me8200_do.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static int me8200_do_io_irq_start(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - me8200_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t tmp; - unsigned long status; - - if (flags & ~ME_IO_IRQ_START_DIO_BYTE) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel != 0) { - PERROR("Invalid channel specified.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - if (irq_source != ME_IRQ_SOURCE_DIO_OVER_TEMP) { - PERROR("Invalid interrupt source specified.\n"); - return ME_ERRNO_INVALID_IRQ_SOURCE; - } - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - spin_lock(instance->irq_mode_lock); - tmp = inb(instance->irq_ctrl_reg); - tmp |= - ME8200_IRQ_MODE_BIT_ENABLE_POWER << (ME8200_IRQ_MODE_POWER_SHIFT * - instance->do_idx); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->irq_mode_lock); - instance->rised = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_do_io_irq_wait(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - me8200_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - long t = 0; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (time_out < 0) { - PERROR("Invalid time_out specified.\n"); - return ME_ERRNO_INVALID_TIMEOUT; - } - - if (time_out) { - t = (time_out * HZ) / 1000; - - if (t == 0) - t = 1; - } - - ME_SUBDEVICE_ENTER; - - if (instance->rised <= 0) { - instance->rised = 0; - - if (time_out) { - t = wait_event_interruptible_timeout(instance-> - wait_queue, - (instance->rised != - 0), t); - - if (t == 0) { - PERROR - ("Wait on external interrupt timed out.\n"); - err = ME_ERRNO_TIMEOUT; - } - } else { - wait_event_interruptible(instance->wait_queue, - (instance->rised != 0)); - } - - if (instance->rised < 0) { - PERROR("Wait on interrupt aborted by user.\n"); - err = ME_ERRNO_CANCELLED; - } - } - - if (signal_pending(current)) { - PERROR("Wait on external interrupt aborted by signal.\n"); - err = ME_ERRNO_SIGNAL; - } - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - instance->rised = 0; - *irq_count = instance->count; - *value = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_do_io_irq_stop(me_subdevice_t *subdevice, - struct file *filep, int channel, int flags) -{ - me8200_do_subdevice_t *instance; - uint8_t tmp; - unsigned long cpu_flags; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - spin_lock(instance->irq_mode_lock); - tmp = inb(instance->irq_ctrl_reg); - tmp &= - ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER << - (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx)); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->irq_mode_lock); - instance->rised = -1; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8200_do_subdevice_t *instance; - unsigned long cpu_flags; - uint8_t tmp; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, cpu_flags); - outb(0x00, instance->port_reg); - PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->port_reg - instance->reg_base, 0x00); - spin_lock(instance->irq_mode_lock); - tmp = inb(instance->irq_ctrl_reg); - tmp &= - ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER << - (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx)); - outb(tmp, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, tmp); - spin_unlock(instance->irq_mode_lock); - instance->rised = -1; - instance->count = 0; - spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags); - wake_up_interruptible_all(&instance->wait_queue); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8200_do_io_single_config(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8200_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - switch (flags) { - case ME_IO_SINGLE_CONFIG_NO_FLAGS: - case ME_IO_SINGLE_CONFIG_DIO_BYTE: - if (channel == 0) { - if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - } else { - PERROR("Invalid byte direction specified.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - PERROR("Invalid byte specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_do_io_single_read(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8200_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_reg); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_do_io_single_write(me_subdevice_t *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me8200_do_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - uint8_t state; - unsigned long status; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock_irqsave(&instance->subdevice_lock, status); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - state = inb(instance->port_reg); - state = - value ? (state | (0x1 << channel)) : (state & - ~(0x1 << - channel)); - outb(state, instance->port_reg); - PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - state); - } else { - PERROR("Invalid bit number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - outb(value, instance->port_reg); - PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", - instance->reg_base, - instance->port_reg - instance->reg_base, - value); - } else { - PERROR("Invalid byte number specified.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock_irqrestore(&instance->subdevice_lock, status); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8200_do_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 8; - return ME_ERRNO_SUCCESS; -} - -static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_OVER_TEMP_IRQ; - return ME_ERRNO_SUCCESS; -} - -static void me8200_do_destructor(struct me_subdevice *subdevice) -{ - me8200_do_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me8200_do_subdevice_t *) subdevice; - - free_irq(instance->irq, (void *)instance); - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -static irqreturn_t me8200_do_isr(int irq, void *dev_id) -{ - me8200_do_subdevice_t *instance; - uint16_t ctrl; - uint8_t irq_status; - - instance = (me8200_do_subdevice_t *) dev_id; - - if (irq != instance->irq) { - PERROR("Incorrect interrupt num: %d.\n", irq); - return IRQ_NONE; - } - - irq_status = inb(instance->irq_status_reg); - if (! - (irq_status & - (ME8200_DO_IRQ_STATUS_BIT_ACTIVE << instance->do_idx))) { - PINFO - ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n", - jiffies, __func__, instance->do_idx, irq_status); - return IRQ_NONE; - } - - PDEBUG("executed.\n"); - - spin_lock(&instance->subdevice_lock); - instance->rised = 1; - instance->count++; - - spin_lock(instance->irq_mode_lock); - ctrl = inw(instance->irq_ctrl_reg); - ctrl |= ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx; - outw(ctrl, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, ctrl); - ctrl &= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx); - outw(ctrl, instance->irq_ctrl_reg); - PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base, - instance->irq_ctrl_reg - instance->reg_base, ctrl); - spin_unlock(instance->irq_mode_lock); - spin_unlock(&instance->subdevice_lock); - wake_up_interruptible_all(&instance->wait_queue); - - return IRQ_HANDLED; -} - -me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base, - unsigned int do_idx, - int irq, - spinlock_t *irq_mode_lock) -{ - me8200_do_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8200_do_subdevice_t)); - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->irq_mode_lock = irq_mode_lock; - - /* Save the index of the digital output */ - subdevice->do_idx = do_idx; - subdevice->irq = irq; - - /* Initialize the registers */ - if (do_idx == 0) { - subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG; - } else if (do_idx == 1) { - subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG; - } else { - PERROR("Wrong subdevice idx=%d.\n", do_idx); - kfree(subdevice); - return NULL; - } - subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG; - subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG; -#ifdef MEDEBUG_DEBUG_REG - subdevice->reg_base = reg_base; -#endif - - /* Initialize the wait queue */ - init_waitqueue_head(&subdevice->wait_queue); - - /* Request the interrupt line */ - err = request_irq(irq, me8200_do_isr, - IRQF_DISABLED | IRQF_SHARED, - ME8200_NAME, (void *)subdevice); - - if (err) { - PERROR("Cannot get interrupt line.\n"); - kfree(subdevice); - return NULL; - } - PINFO("Registered irq=%d.\n", irq); - - /* Overload base class methods. */ - subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start; - subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait; - subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop; - subdevice->base.me_subdevice_io_reset_subdevice = - me8200_do_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = - me8200_do_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read; - subdevice->base.me_subdevice_io_single_write = - me8200_do_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me8200_do_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8200_do_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8200_do_query_subdevice_caps; - subdevice->base.me_subdevice_destructor = me8200_do_destructor; - - subdevice->rised = 0; - subdevice->count = 0; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8200_do.h b/drivers/staging/meilhaus/me8200_do.h deleted file mode 100644 index 27581251c84..00000000000 --- a/drivers/staging/meilhaus/me8200_do.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file me8200_do.h - * - * @brief ME-8200 digital output subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DO_H_ -#define _ME8200_DO_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The template subdevice class. - */ -typedef struct me8200_do_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *irq_mode_lock; - - int irq; /**< The number of the interrupt request */ - int rised; /**< Flag to indicate if an interrupt occured */ - int count; /**< Counts the number of interrupts occured */ - wait_queue_head_t wait_queue; /**< To wait on interrupts */ - - unsigned int do_idx; /**< The number of the digital output */ - - unsigned long port_reg; /**< The digital output port */ - unsigned long irq_ctrl_reg; /**< The interrupt control register */ - unsigned long irq_status_reg; /**< The interrupt status register */ -#ifdef MEDEBUG_DEBUG_REG - unsigned long reg_base; -#endif -} me8200_do_subdevice_t; - -/** - * @brief The constructor to generate a ME-8200 digital output subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param do_idx The index of the digital output subdevice on this device. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base, - unsigned int do_idx, - int irq, - spinlock_t * irq_mode_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_do_reg.h b/drivers/staging/meilhaus/me8200_do_reg.h deleted file mode 100644 index 41095046037..00000000000 --- a/drivers/staging/meilhaus/me8200_do_reg.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file me8200_ao_reg.h - * - * @brief ME-8200 analog output subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_DO_REG_H_ -#define _ME8200_DO_REG_H_ - -#ifdef __KERNEL__ - -#define ME8200_DO_IRQ_STATUS_REG 0x0 // R -#define ME8200_DO_PORT_0_REG 0x1 // R/W -#define ME8200_DO_PORT_1_REG 0x2 // R/W - -#define ME8200_DO_IRQ_STATUS_BIT_ACTIVE 0x1 -#define ME8200_DO_IRQ_STATUS_SHIFT 1 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8200_reg.h b/drivers/staging/meilhaus/me8200_reg.h deleted file mode 100644 index a73fe4d5b0f..00000000000 --- a/drivers/staging/meilhaus/me8200_reg.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file me8200_reg.h - * - * @brief ME-8200 register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8200_REG_H_ -#define _ME8200_REG_H_ - -#ifdef __KERNEL__ - -#define ME8200_IRQ_MODE_REG 0xD // R/W - -#define ME8200_IRQ_MODE_MASK 0x3 - -#define ME8200_IRQ_MODE_MASK_MASK 0x0 -#define ME8200_IRQ_MODE_MASK_COMPARE 0x1 - -#define ME8200_IRQ_MODE_BIT_ENABLE_POWER 0x10 -#define ME8200_IRQ_MODE_BIT_CLEAR_POWER 0x40 - -#define ME8200_IRQ_MODE_DI_SHIFT 2 -#define ME8200_IRQ_MODE_POWER_SHIFT 1 - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c deleted file mode 100644 index d8f742a8ca9..00000000000 --- a/drivers/staging/meilhaus/me8254.c +++ /dev/null @@ -1,1176 +0,0 @@ -/** - * @file me8254.c - * - * @brief 8254 subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "me8254_reg.h" -#include "me8254.h" - -/* - * Defines - */ -#define ME8254_NUMBER_CHANNELS 1 /**< One channel per counter. */ -#define ME8254_CTR_WIDTH 16 /**< One counter has 16 bits. */ - -/* - * Functions - */ - -static int me8254_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8254_subdevice_t *instance; - uint8_t clk_src; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8254_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - if (instance->ctr_idx == 0) - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - else if (instance->ctr_idx == 1) - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - else - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - spin_unlock(instance->ctrl_reg_lock); - - outb(0x00, instance->val_reg); - outb(0x00, instance->val_reg); - - spin_lock(instance->clk_src_reg_lock); - clk_src = inb(instance->clk_src_reg); - - switch (instance->device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME1400: - case PCI_DEVICE_ID_MEILHAUS_ME140A: - case PCI_DEVICE_ID_MEILHAUS_ME140B: - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - if (instance->me8254_idx == 0) { - if (instance->ctr_idx == 0) - clk_src &= - ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ | - ME1400AB_8254_A_0_CLK_SRC_QUARZ); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV); - else - clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV); - } else { - if (instance->ctr_idx == 0) - clk_src &= - ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ | - ME1400AB_8254_B_0_CLK_SRC_QUARZ); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV); - else - clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV); - } - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - case PCI_DEVICE_ID_MEILHAUS_ME140D: - switch (instance->me8254_idx) { - case 0: - case 2: - case 4: - case 6: - case 8: - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK); - else - clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK); - break; - - default: - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK); - else - clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK); - break; - } - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - case PCI_DEVICE_ID_MEILHAUS_ME4660: - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - case PCI_DEVICE_ID_MEILHAUS_ME4660S: - case PCI_DEVICE_ID_MEILHAUS_ME4660IS: - case PCI_DEVICE_ID_MEILHAUS_ME4670: - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - case PCI_DEVICE_ID_MEILHAUS_ME4680: - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - - /* No clock source register available */ - break; - - default: - PERROR("Invalid device type.\n"); - err = ME_ERRNO_INTERNAL; - } - - if (!err) - outb(clk_src, instance->clk_src_reg); - - spin_unlock(instance->clk_src_reg_lock); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref) -{ - uint8_t clk_src; - - spin_lock(instance->clk_src_reg_lock); - clk_src = inb(instance->clk_src_reg); - - switch (ref) { - case ME_REF_CTR_EXTERNAL: - if (instance->me8254_idx == 0) { - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_QUARZ); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV); - else - clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV); - } else { - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_QUARZ); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV); - else - clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV); - } - - break; - - case ME_REF_CTR_PREVIOUS: - if (instance->me8254_idx == 0) { - if (instance->ctr_idx == 0) { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } else if (instance->ctr_idx == 1) - clk_src |= (ME1400AB_8254_A_1_CLK_SRC_PREV); - else - clk_src |= (ME1400AB_8254_A_2_CLK_SRC_PREV); - } else { - if (instance->ctr_idx == 0) { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } else if (instance->ctr_idx == 1) - clk_src |= (ME1400AB_8254_B_1_CLK_SRC_PREV); - else - clk_src |= (ME1400AB_8254_B_2_CLK_SRC_PREV); - } - - break; - - case ME_REF_CTR_INTERNAL_1MHZ: - if (instance->me8254_idx == 0) { - if (instance->ctr_idx == 0) { - clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ); - clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - if (instance->ctr_idx == 0) { - clk_src |= (ME1400AB_8254_B_0_CLK_SRC_QUARZ); - clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } - - break; - - case ME_REF_CTR_INTERNAL_10MHZ: - if (instance->me8254_idx == 0) { - if (instance->ctr_idx == 0) { - clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ); - clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - if (instance->ctr_idx == 0) { - clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ); - clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } - - break; - - default: - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - outb(clk_src, instance->clk_src_reg); - spin_unlock(instance->clk_src_reg_lock); - - return ME_ERRNO_SUCCESS; -} - -static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref) -{ - uint8_t clk_src; - - spin_lock(instance->clk_src_reg_lock); - clk_src = inb(instance->clk_src_reg); - - switch (ref) { - case ME_REF_CTR_EXTERNAL: - switch (instance->me8254_idx) { - case 0: - case 2: - case 4: - case 6: - case 8: - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK); - else - clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK); - break; - - default: - if (instance->ctr_idx == 0) - clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); - else if (instance->ctr_idx == 1) - clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK); - else - clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK); - break; - } - break; - - case ME_REF_CTR_PREVIOUS: - switch (instance->me8254_idx) { - case 0: - case 2: - case 4: - case 6: - case 8: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_PREV); - } else if (instance->ctr_idx == 1) { - clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_ACE_1_CLK_SRC_PREV); - } else { - clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_ACE_2_CLK_SRC_PREV); - } - break; - - default: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_PREV); - } else if (instance->ctr_idx == 1) { - clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_BD_1_CLK_SRC_PREV); - } else { - clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_BD_2_CLK_SRC_PREV); - } - break; - } - - break; - - case ME_REF_CTR_INTERNAL_1MHZ: - switch (instance->me8254_idx) { - case 0: - case 2: - case 4: - case 6: - case 8: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_1MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - break; - - default: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_1MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - break; - } - - break; - - case ME_REF_CTR_INTERNAL_10MHZ: - switch (instance->me8254_idx) { - case 0: - case 2: - case 4: - case 6: - case 8: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - break; - - default: - if (instance->ctr_idx == 0) { - clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK); - clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_10MHZ); - } else { - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - break; - } - - break; - - default: - PERROR("Invalid reference.\n"); - spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - outb(clk_src, instance->clk_src_reg); - spin_unlock(instance->clk_src_reg_lock); - - return ME_ERRNO_SUCCESS; -} - -static int me4600_ref_config(me8254_subdevice_t *instance, int ref) -{ - switch (ref) { - - case ME_REF_CTR_EXTERNAL: - // Nothing to do - break; - - default: - PERROR("Invalid reference.\n"); -// spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - return ME_ERRNO_SUCCESS; -} - -static int me8100_ref_config(me8254_subdevice_t *instance, int ref) -{ - switch (ref) { - - case ME_REF_CTR_EXTERNAL: - // Nothing to do - break; - - default: - PERROR("Invalid reference.\n"); -// spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_REF; - } - - return ME_ERRNO_SUCCESS; -} - -static int me8254_io_single_config(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8254_subdevice_t *instance; - int err; - - PDEBUG("executed.\n"); - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - instance = (me8254_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - // Configure the counter modes - if (instance->ctr_idx == 0) { - if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M1 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M2 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M3 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M4 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { - outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M5 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else { - PERROR("Invalid single configuration.\n"); - spin_unlock(&instance->subdevice_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else if (instance->ctr_idx == 1) { - if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M1 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M2 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M3 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M4 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { - outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M5 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else { - PERROR("Invalid single configuration.\n"); - spin_unlock(&instance->subdevice_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } else { - if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M1 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M2 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M3 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M4 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { - outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M5 | - ME8254_CTRL_BIN, instance->ctrl_reg); - } else { - PERROR("Invalid single configuration.\n"); - spin_unlock(&instance->subdevice_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - } - - switch (instance->device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME1400: - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - case PCI_DEVICE_ID_MEILHAUS_ME140A: - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - case PCI_DEVICE_ID_MEILHAUS_ME140B: - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - err = me1400_ab_ref_config(instance, ref); - - if (err) { - spin_unlock(&instance->subdevice_lock); - return err; - } - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - case PCI_DEVICE_ID_MEILHAUS_ME140D: - err = me1400_cd_ref_config(instance, ref); - - if (err) { - spin_unlock(&instance->subdevice_lock); - return err; - } - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - case PCI_DEVICE_ID_MEILHAUS_ME4660: - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - case PCI_DEVICE_ID_MEILHAUS_ME4660S: - case PCI_DEVICE_ID_MEILHAUS_ME4660IS: - case PCI_DEVICE_ID_MEILHAUS_ME4670: - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - case PCI_DEVICE_ID_MEILHAUS_ME4680: - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - err = me4600_ref_config(instance, ref); - - if (err) { - spin_unlock(&instance->subdevice_lock); - return err; - } - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - err = me8100_ref_config(instance, ref); - - if (err) { - spin_unlock(&instance->subdevice_lock); - return err; - } - - break; - - default: - PERROR("Invalid device type.\n"); - - spin_unlock(&instance->subdevice_lock); -// spin_unlock(instance->clk_src_reg_lock); - return ME_ERRNO_INVALID_SINGLE_CONFIG; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8254_io_single_read(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8254_subdevice_t *instance; - uint16_t lo_byte; - uint16_t hi_byte; - - PDEBUG("executed.\n"); - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - instance = (me8254_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - if (instance->ctr_idx == 0) - outb(ME8254_CTRL_SC0 | ME8254_CTRL_TLO, instance->ctrl_reg); - else if (instance->ctr_idx == 1) - outb(ME8254_CTRL_SC1 | ME8254_CTRL_TLO, instance->ctrl_reg); - else - outb(ME8254_CTRL_SC2 | ME8254_CTRL_TLO, instance->ctrl_reg); - - lo_byte = inb(instance->val_reg); - hi_byte = inb(instance->val_reg); - spin_unlock(instance->ctrl_reg_lock); - - *value = lo_byte | (hi_byte << 8); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8254_io_single_write(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me8254_subdevice_t *instance; - - PDEBUG("executed.\n"); - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - instance = (me8254_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - outb(value, instance->val_reg); - outb((value >> 8), instance->val_reg); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8254_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = ME8254_NUMBER_CHANNELS; - return ME_ERRNO_SUCCESS; -} - -static int me8254_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_CTR; - *subtype = ME_SUBTYPE_CTR_8254; - return ME_ERRNO_SUCCESS; -} - -static int me8254_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - me8254_subdevice_t *instance; - PDEBUG("executed.\n"); - instance = (me8254_subdevice_t *) subdevice; - *caps = instance->caps; - return ME_ERRNO_SUCCESS; -} - -static int me8254_query_subdevice_caps_args(struct me_subdevice *subdevice, - int cap, int *args, int count) -{ - PDEBUG("executed.\n"); - - if (count != 1) { - PERROR("Invalid capability argument count.\n"); - return ME_ERRNO_INVALID_CAP_ARG_COUNT; - } - - if (cap == ME_CAP_CTR_WIDTH) { - args[0] = ME8254_CTR_WIDTH; - } else { - PERROR("Invalid capability.\n"); - return ME_ERRNO_INVALID_CAP; - } - - return ME_ERRNO_SUCCESS; -} - -static uint32_t me1400AB_get_val_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - - case 0: - return (reg_base + ME1400AB_8254_A_0_VAL_REG + ctr_idx); - - default: - return (reg_base + ME1400AB_8254_B_0_VAL_REG + ctr_idx); - } - - return 0; -} - -static uint32_t me1400AB_get_ctrl_reg(uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - case 0: - return (reg_base + ME1400AB_8254_A_CTRL_REG); - - default: - return (reg_base + ME1400AB_8254_B_CTRL_REG); - } - - return 0; -} - -static uint32_t me1400AB_get_clk_src_reg(uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - case 0: - return (reg_base + ME1400AB_CLK_SRC_REG); - - default: - return (reg_base + ME1400AB_CLK_SRC_REG); - } - - return 0; -} - -static uint32_t me1400CD_get_val_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - case 0: - return (reg_base + ME1400C_8254_A_0_VAL_REG + ctr_idx); - - case 1: - return (reg_base + ME1400C_8254_B_0_VAL_REG + ctr_idx); - - case 2: - return (reg_base + ME1400C_8254_C_0_VAL_REG + ctr_idx); - - case 3: - return (reg_base + ME1400C_8254_D_0_VAL_REG + ctr_idx); - - case 4: - return (reg_base + ME1400C_8254_E_0_VAL_REG + ctr_idx); - - case 5: - return (reg_base + ME1400D_8254_A_0_VAL_REG + ctr_idx); - - case 6: - return (reg_base + ME1400D_8254_B_0_VAL_REG + ctr_idx); - - case 7: - return (reg_base + ME1400D_8254_C_0_VAL_REG + ctr_idx); - - case 8: - return (reg_base + ME1400D_8254_D_0_VAL_REG + ctr_idx); - - default: - return (reg_base + ME1400D_8254_E_0_VAL_REG + ctr_idx); - } - - return 0; -} - -static uint32_t me1400CD_get_ctrl_reg(uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - case 0: - return (reg_base + ME1400C_8254_A_CTRL_REG); - - case 1: - return (reg_base + ME1400C_8254_B_CTRL_REG); - - case 2: - return (reg_base + ME1400C_8254_C_CTRL_REG); - - case 3: - return (reg_base + ME1400C_8254_D_CTRL_REG); - - case 4: - return (reg_base + ME1400C_8254_E_CTRL_REG); - - case 5: - return (reg_base + ME1400D_8254_A_CTRL_REG); - - case 6: - return (reg_base + ME1400D_8254_B_CTRL_REG); - - case 7: - return (reg_base + ME1400D_8254_C_CTRL_REG); - - case 8: - return (reg_base + ME1400D_8254_D_CTRL_REG); - - default: - return (reg_base + ME1400D_8254_E_CTRL_REG); - } - - return 0; -} - -static uint32_t me1400CD_get_clk_src_reg(uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx) -{ - switch (me8254_idx) { - case 0: - return (reg_base + ME1400C_CLK_SRC_0_REG); - - case 1: - return (reg_base + ME1400C_CLK_SRC_0_REG); - - case 2: - return (reg_base + ME1400C_CLK_SRC_1_REG); - - case 3: - return (reg_base + ME1400C_CLK_SRC_1_REG); - - case 4: - return (reg_base + ME1400C_CLK_SRC_2_REG); - - case 5: - return (reg_base + ME1400D_CLK_SRC_0_REG); - - case 6: - return (reg_base + ME1400D_CLK_SRC_0_REG); - - case 7: - return (reg_base + ME1400D_CLK_SRC_1_REG); - - case 8: - return (reg_base + ME1400D_CLK_SRC_1_REG); - - default: - return (reg_base + ME1400D_CLK_SRC_2_REG); - } - - return 0; -} - -static uint32_t me4600_get_val_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - return (reg_base + ME4600_8254_0_VAL_REG + ctr_idx); -} - -static uint32_t me4600_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - return (reg_base + ME4600_8254_CTRL_REG); -} - -static uint32_t me8100_get_val_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - return (reg_base + ME8100_COUNTER_REG_0 + ctr_idx * 2); -} - -static uint32_t me8100_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx, - unsigned int ctr_idx) -{ - return (reg_base + ME8100_COUNTER_CTRL_REG); -} - -me8254_subdevice_t *me8254_constructor(uint32_t device_id, - uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx, - spinlock_t *ctrl_reg_lock, - spinlock_t *clk_src_reg_lock) -{ - me8254_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - // Allocate memory for subdevice instance - subdevice = kmalloc(sizeof(me8254_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for 8254 instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8254_subdevice_t)); - - // Check if counter index is out of range - - if (ctr_idx > 2) { - PERROR("Counter index is out of range.\n"); - kfree(subdevice); - return NULL; - } - // Initialize subdevice base class - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - subdevice->ctrl_reg_lock = ctrl_reg_lock; - subdevice->clk_src_reg_lock = clk_src_reg_lock; - - // Save type of Meilhaus device - subdevice->device_id = device_id; - - // Save the indices - subdevice->me8254_idx = me8254_idx; - subdevice->ctr_idx = ctr_idx; - - // Do device specific initialization - switch (device_id) { - - case PCI_DEVICE_ID_MEILHAUS_ME140A: - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - // Check if 8254 index is out of range - if (me8254_idx > 0) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - case PCI_DEVICE_ID_MEILHAUS_ME140B: // Fall through - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - // Check if 8254 index is out of range - if (me8254_idx > 1) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - // Initialize the counters capabilities - if (ctr_idx == 0) - subdevice->caps = - ME_CAPS_CTR_CLK_INTERNAL_1MHZ | - ME_CAPS_CTR_CLK_INTERNAL_10MHZ | - ME_CAPS_CTR_CLK_EXTERNAL; - else - subdevice->caps = - ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL; - - // Get the counters registers - subdevice->val_reg = - me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx); - subdevice->ctrl_reg = - me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); - subdevice->clk_src_reg = - me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - // Check if 8254 index is out of range - if (me8254_idx > 4) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - case PCI_DEVICE_ID_MEILHAUS_ME140D: - // Check if 8254 index is out of range - if (me8254_idx > 9) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - // Initialize the counters capabilities - if (ctr_idx == 0) { - if (me8254_idx == 0) - subdevice->caps = - ME_CAPS_CTR_CLK_PREVIOUS | - ME_CAPS_CTR_CLK_INTERNAL_1MHZ | - ME_CAPS_CTR_CLK_INTERNAL_10MHZ | - ME_CAPS_CTR_CLK_EXTERNAL; - else - subdevice->caps = - ME_CAPS_CTR_CLK_INTERNAL_1MHZ | - ME_CAPS_CTR_CLK_INTERNAL_10MHZ | - ME_CAPS_CTR_CLK_EXTERNAL; - } else - subdevice->caps = - ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL; - - // Get the counters registers - subdevice->val_reg = - me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx); - subdevice->ctrl_reg = - me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); - subdevice->clk_src_reg = - me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - case PCI_DEVICE_ID_MEILHAUS_ME4660: - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - case PCI_DEVICE_ID_MEILHAUS_ME4660S: - case PCI_DEVICE_ID_MEILHAUS_ME4660IS: - case PCI_DEVICE_ID_MEILHAUS_ME4670: - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - case PCI_DEVICE_ID_MEILHAUS_ME4680: - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - // Check if 8254 index is out of range - if (me8254_idx > 0) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - // Initialize the counters capabilities - subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; - - // Get the counters registers - subdevice->val_reg = - me4600_get_val_reg(reg_base, me8254_idx, ctr_idx); - subdevice->ctrl_reg = - me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); - subdevice->clk_src_reg = 0; // Not used - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - // Check if 8254 index is out of range - if (me8254_idx > 0) { - PERROR("8254 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - // Initialize the counters capabilities - subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; - - // Get the counters registers - subdevice->val_reg = - me8100_get_val_reg(reg_base, me8254_idx, ctr_idx); - subdevice->ctrl_reg = - me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); - subdevice->clk_src_reg = 0; // Not used - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4650: - case PCI_DEVICE_ID_MEILHAUS_ME1400: - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - PERROR("No 8254 subdevices available for subdevice device.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - - default: - PERROR("Unknown device type.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - // Overload subdevice base class methods. - subdevice->base.me_subdevice_io_reset_subdevice = - me8254_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = me8254_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8254_io_single_read; - subdevice->base.me_subdevice_io_single_write = me8254_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me8254_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8254_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8254_query_subdevice_caps; - subdevice->base.me_subdevice_query_subdevice_caps_args = - me8254_query_subdevice_caps_args; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8254.h b/drivers/staging/meilhaus/me8254.h deleted file mode 100644 index 572b7196d5a..00000000000 --- a/drivers/staging/meilhaus/me8254.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file me8254.h - * - * @brief 8254 counter implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ME8254_H_ -#define _ME8254_H_ - -#include "mesubdevice.h" -#include "meslock.h" - -#ifdef __KERNEL__ - -/** - * @brief The 8254 subdevice class. - */ -typedef struct me8254_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect the control register from concurrent access. */ - spinlock_t *clk_src_reg_lock; /**< Spin lock to protect the clock source register from concurrent access. */ - - uint32_t device_id; /**< The Meilhaus device type carrying the 8254 chip. */ - int me8254_idx; /**< The index of the 8254 chip on the device. */ - int ctr_idx; /**< The index of the counter on the 8254 chip. */ - - int caps; /**< Holds the device capabilities. */ - - unsigned long val_reg; /**< Holds the actual counter value. */ - unsigned long ctrl_reg; /**< Register to configure the 8254 modes. */ - unsigned long clk_src_reg; /**< Register to configure the counter connections. */ -} me8254_subdevice_t; - -/** - * @brief The constructor to generate a 8254 instance. - * - * @param device_id The kind of Meilhaus device holding the 8254. - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param me8254_idx The index of the 8254 chip on the Meilhaus device. - * @param ctr_idx The index of the counter inside a 8254 chip. - * @param ctrl_reg_lock Pointer to spin lock protecting the 8254 control register from concurrent access. - * @param clk_src_reg_lock Pointer to spin lock protecting the clock source register from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8254_subdevice_t *me8254_constructor(uint32_t device_id, - uint32_t reg_base, - unsigned int me8254_idx, - unsigned int ctr_idx, - spinlock_t * ctrl_reg_lock, - spinlock_t * clk_src_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8254_reg.h b/drivers/staging/meilhaus/me8254_reg.h deleted file mode 100644 index 7e2c36b46f5..00000000000 --- a/drivers/staging/meilhaus/me8254_reg.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file me8254_reg.h - * - * @brief 8254 counter register definitions. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME8254_REG_H_ -#define _ME8254_REG_H_ - -#ifdef __KERNEL__ - -/* ME1400 A/B register offsets */ -#define ME1400AB_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400AB_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 1 value register. */ -#define ME1400AB_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 2 value register. */ -#define ME1400AB_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */ - -#define ME1400AB_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */ -#define ME1400AB_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 1 value register. */ -#define ME1400AB_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 2 value register. */ -#define ME1400AB_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */ - -#define ME1400AB_CLK_SRC_REG 0x0010 /**< Offset of clock source register. */ - -/* ME1400 C register offsets */ -#define ME1400C_8254_A_0_VAL_REG 0x0004 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400C_8254_A_1_VAL_REG 0x0005 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400C_8254_A_2_VAL_REG 0x0006 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400C_8254_A_CTRL_REG 0x0007 /**< Offset of 8254 A control register. */ - -#define ME1400C_8254_B_0_VAL_REG 0x000C /**< Offset of 8254 B counter 0 value register. */ -#define ME1400C_8254_B_1_VAL_REG 0x000D /**< Offset of 8254 B counter 0 value register. */ -#define ME1400C_8254_B_2_VAL_REG 0x000E /**< Offset of 8254 B counter 0 value register. */ -#define ME1400C_8254_B_CTRL_REG 0x000F /**< Offset of 8254 B control register. */ - -#define ME1400C_8254_C_0_VAL_REG 0x0010 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400C_8254_C_1_VAL_REG 0x0011 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400C_8254_C_2_VAL_REG 0x0012 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400C_8254_C_CTRL_REG 0x0013 /**< Offset of 8254 C control register. */ - -#define ME1400C_8254_D_0_VAL_REG 0x0014 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400C_8254_D_1_VAL_REG 0x0015 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400C_8254_D_2_VAL_REG 0x0016 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400C_8254_D_CTRL_REG 0x0017 /**< Offset of 8254 D control register. */ - -#define ME1400C_8254_E_0_VAL_REG 0x0018 /**< Offset of 8254 E counter 0 value register. */ -#define ME1400C_8254_E_1_VAL_REG 0x0019 /**< Offset of 8254 E counter 0 value register. */ -#define ME1400C_8254_E_2_VAL_REG 0x001A /**< Offset of 8254 E counter 0 value register. */ -#define ME1400C_8254_E_CTRL_REG 0x001B /**< Offset of 8254 E control register. */ - -#define ME1400C_CLK_SRC_0_REG 0x001C /**< Offset of clock source register 0. */ -#define ME1400C_CLK_SRC_1_REG 0x001D /**< Offset of clock source register 1. */ -#define ME1400C_CLK_SRC_2_REG 0x001E /**< Offset of clock source register 2. */ - -/* ME1400 D register offsets */ -#define ME1400D_8254_A_0_VAL_REG 0x0044 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400D_8254_A_1_VAL_REG 0x0045 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400D_8254_A_2_VAL_REG 0x0046 /**< Offset of 8254 A counter 0 value register. */ -#define ME1400D_8254_A_CTRL_REG 0x0047 /**< Offset of 8254 A control register. */ - -#define ME1400D_8254_B_0_VAL_REG 0x004C /**< Offset of 8254 B counter 0 value register. */ -#define ME1400D_8254_B_1_VAL_REG 0x004D /**< Offset of 8254 B counter 0 value register. */ -#define ME1400D_8254_B_2_VAL_REG 0x004E /**< Offset of 8254 B counter 0 value register. */ -#define ME1400D_8254_B_CTRL_REG 0x004F /**< Offset of 8254 B control register. */ - -#define ME1400D_8254_C_0_VAL_REG 0x0050 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400D_8254_C_1_VAL_REG 0x0051 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400D_8254_C_2_VAL_REG 0x0052 /**< Offset of 8254 C counter 0 value register. */ -#define ME1400D_8254_C_CTRL_REG 0x0053 /**< Offset of 8254 C control register. */ - -#define ME1400D_8254_D_0_VAL_REG 0x0054 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400D_8254_D_1_VAL_REG 0x0055 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400D_8254_D_2_VAL_REG 0x0056 /**< Offset of 8254 D counter 0 value register. */ -#define ME1400D_8254_D_CTRL_REG 0x0057 /**< Offset of 8254 D control register. */ - -#define ME1400D_8254_E_0_VAL_REG 0x0058 /**< Offset of 8254 E counter 0 value register. */ -#define ME1400D_8254_E_1_VAL_REG 0x0059 /**< Offset of 8254 E counter 0 value register. */ -#define ME1400D_8254_E_2_VAL_REG 0x005A /**< Offset of 8254 E counter 0 value register. */ -#define ME1400D_8254_E_CTRL_REG 0x005B /**< Offset of 8254 E control register. */ - -#define ME1400D_CLK_SRC_0_REG 0x005C /**< Offset of clock source register 0. */ -#define ME1400D_CLK_SRC_1_REG 0x005D /**< Offset of clock source register 1. */ -#define ME1400D_CLK_SRC_2_REG 0x005E /**< Offset of clock source register 2. */ - -/* ME4600 register offsets */ -#define ME4600_8254_0_VAL_REG 0x0000 /**< Offset of 8254 A counter 0 value register. */ -#define ME4600_8254_1_VAL_REG 0x0001 /**< Offset of 8254 A counter 0 value register. */ -#define ME4600_8254_2_VAL_REG 0x0002 /**< Offset of 8254 A counter 0 value register. */ -#define ME4600_8254_CTRL_REG 0x0003 /**< Offset of 8254 A control register. */ - -/* Command words for 8254 control register */ -#define ME8254_CTRL_SC0 0x00 /**< Counter 0 selection. */ -#define ME8254_CTRL_SC1 0x40 /**< Counter 1 selection. */ -#define ME8254_CTRL_SC2 0x80 /**< Counter 2 selection. */ - -#define ME8254_CTRL_TLO 0x00 /**< Counter latching operation. */ -#define ME8254_CTRL_LSB 0x10 /**< Only read LSB. */ -#define ME8254_CTRL_MSB 0x20 /**< Only read MSB. */ -#define ME8254_CTRL_LM 0x30 /**< First read LSB, then MSB. */ - -#define ME8254_CTRL_M0 0x00 /**< Mode 0 selection. */ -#define ME8254_CTRL_M1 0x02 /**< Mode 1 selection. */ -#define ME8254_CTRL_M2 0x04 /**< Mode 2 selection. */ -#define ME8254_CTRL_M3 0x06 /**< Mode 3 selection. */ -#define ME8254_CTRL_M4 0x08 /**< Mode 4 selection. */ -#define ME8254_CTRL_M5 0x0A /**< Mode 5 selection. */ - -#define ME8254_CTRL_BIN 0x00 /**< Binary counter. */ -#define ME8254_CTRL_BCD 0x01 /**< BCD counter. */ - -/* ME-1400 A/B clock source register bits */ -#define ME1400AB_8254_A_0_CLK_SRC_1MHZ (0 << 7) /**< 1MHz clock. */ -#define ME1400AB_8254_A_0_CLK_SRC_10MHZ (1 << 7) /**< 10MHz clock. */ -#define ME1400AB_8254_A_0_CLK_SRC_PIN (0 << 6) /**< CLK 0 to SUB-D. */ -#define ME1400AB_8254_A_0_CLK_SRC_QUARZ (1 << 6) /**< Connect CLK 0 with quarz. */ - -#define ME1400AB_8254_A_1_CLK_SRC_PIN (0 << 5) /**< CLK 1 to SUB-D. */ -#define ME1400AB_8254_A_1_CLK_SRC_PREV (1 << 5) /**< Connect OUT 0 with CLK 1. */ - -#define ME1400AB_8254_A_2_CLK_SRC_PIN (0 << 4) /**< CLK 2 to SUB-D. */ -#define ME1400AB_8254_A_2_CLK_SRC_PREV (1 << 4) /**< Connect OUT 1 with CLK 2. */ - -#define ME1400AB_8254_B_0_CLK_SRC_1MHZ (0 << 3) /**< 1MHz clock. */ -#define ME1400AB_8254_B_0_CLK_SRC_10MHZ (1 << 3) /**< 10MHz clock. */ -#define ME1400AB_8254_B_0_CLK_SRC_PIN (0 << 2) /**< CLK 0 to SUB-D. */ -#define ME1400AB_8254_B_0_CLK_SRC_QUARZ (1 << 2) /**< Connect CLK 0 with quarz. */ - -#define ME1400AB_8254_B_1_CLK_SRC_PIN (0 << 1) /**< CLK 1 to SUB-D. */ -#define ME1400AB_8254_B_1_CLK_SRC_PREV (1 << 1) /**< Connect OUT 0 with CLK 1. */ - -#define ME1400AB_8254_B_2_CLK_SRC_PIN (0 << 0) /**< CLK 2 to SUB-D. */ -#define ME1400AB_8254_B_2_CLK_SRC_PREV (1 << 0) /**< Connect OUT 1 with CLK 2. */ - -/* ME-1400 C/D clock source registers bits */ -#define ME1400CD_8254_ACE_0_CLK_SRC_MASK 0x03 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_ACE_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */ -#define ME1400CD_8254_ACE_0_CLK_SRC_1MHZ 0x01 /**< Connect CLK to 1MHz. */ -#define ME1400CD_8254_ACE_0_CLK_SRC_10MHZ 0x02 /**< Connect CLK to 10MHz. */ -#define ME1400CD_8254_ACE_0_CLK_SRC_PREV 0x03 /**< Connect CLK to previous counter output on ME-1400 D extension. */ - -#define ME1400CD_8254_ACE_1_CLK_SRC_MASK 0x04 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_ACE_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */ -#define ME1400CD_8254_ACE_1_CLK_SRC_PREV 0x04 /**< Connect CLK to previous counter output. */ - -#define ME1400CD_8254_ACE_2_CLK_SRC_MASK 0x08 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_ACE_2_CLK_SRC_PIN 0x00 /**< Connect to SUB-D. */ -#define ME1400CD_8254_ACE_2_CLK_SRC_PREV 0x08 /**< Connect CLK to previous counter output. */ - -#define ME1400CD_8254_BD_0_CLK_SRC_MASK 0x30 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_BD_0_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */ -#define ME1400CD_8254_BD_0_CLK_SRC_1MHZ 0x10 /**< Connect CLK to 1MHz. */ -#define ME1400CD_8254_BD_0_CLK_SRC_10MHZ 0x20 /**< Connect CLK to 10MHz. */ -#define ME1400CD_8254_BD_0_CLK_SRC_PREV 0x30 /**< Connect CLK to previous counter output. */ - -#define ME1400CD_8254_BD_1_CLK_SRC_MASK 0x40 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_BD_1_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */ -#define ME1400CD_8254_BD_1_CLK_SRC_PREV 0x40 /**< Connect CLK to previous counter output. */ - -#define ME1400CD_8254_BD_2_CLK_SRC_MASK 0x80 /**< Masks all CLK source bits. */ -#define ME1400CD_8254_BD_2_CLK_SRC_PIN 0x00 /**< Connect CLK to SUB-D. */ -#define ME1400CD_8254_BD_2_CLK_SRC_PREV 0x80 /**< Connect CLK to previous counter output. */ - -/* ME-8100 counter registers */ -#define ME8100_COUNTER_REG_0 0x18 //(r,w) -#define ME8100_COUNTER_REG_1 0x1A //(r,w) -#define ME8100_COUNTER_REG_2 0x1C //(r,w) -#define ME8100_COUNTER_CTRL_REG 0x1E //(r,w) - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c deleted file mode 100644 index ec9c6389752..00000000000 --- a/drivers/staging/meilhaus/me8255.c +++ /dev/null @@ -1,462 +0,0 @@ -/** - * @file me8255.c - * - * @brief 8255 subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" -#include "medebug.h" - -#include "me8255_reg.h" -#include "me8255.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static uint8_t get_mode_from_mirror(uint32_t mirror) -{ - PDEBUG("executed.\n"); - - if (mirror & ME8255_PORT_0_OUTPUT) { - if (mirror & ME8255_PORT_1_OUTPUT) { - if (mirror & ME8255_PORT_2_OUTPUT) { - return ME8255_MODE_OOO; - } else { - return ME8255_MODE_IOO; - } - } else { - if (mirror & ME8255_PORT_2_OUTPUT) { - return ME8255_MODE_OIO; - } else { - return ME8255_MODE_IIO; - } - } - } else { - if (mirror & ME8255_PORT_1_OUTPUT) { - if (mirror & ME8255_PORT_2_OUTPUT) { - return ME8255_MODE_OOI; - } else { - return ME8255_MODE_IOI; - } - } else { - if (mirror & ME8255_PORT_2_OUTPUT) { - return ME8255_MODE_OII; - } else { - return ME8255_MODE_III; - } - } - } -} - -static int me8255_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - me8255_subdevice_t *instance; - - PDEBUG("executed.\n"); - - instance = (me8255_subdevice_t *) subdevice; - - if (flags) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - spin_lock(instance->ctrl_reg_lock); - *instance->ctrl_reg_mirror &= - ~(ME8255_PORT_0_OUTPUT << instance->dio_idx); - outb(get_mode_from_mirror(*instance->ctrl_reg_mirror), - instance->ctrl_reg); - spin_unlock(instance->ctrl_reg_lock); - - outb(0, instance->port_reg); - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return ME_ERRNO_SUCCESS; -} - -static int me8255_io_single_config(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - me8255_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8255_subdevice_t *) subdevice; - - if (flags & ~ME_IO_SINGLE_CONFIG_DIO_BYTE) { - PERROR("Invalid flag specified.\n"); - return ME_ERRNO_INVALID_FLAGS; - } - - if (channel) { - PERROR("Invalid channel.\n"); - return ME_ERRNO_INVALID_CHANNEL; - } - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) { - spin_lock(instance->ctrl_reg_lock); - *instance->ctrl_reg_mirror &= - ~(ME8255_PORT_0_OUTPUT << instance->dio_idx); - outb(get_mode_from_mirror(*instance->ctrl_reg_mirror), - instance->ctrl_reg); - spin_unlock(instance->ctrl_reg_lock); - } else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) { - spin_lock(instance->ctrl_reg_lock); - *instance->ctrl_reg_mirror |= - (ME8255_PORT_0_OUTPUT << instance->dio_idx); - outb(get_mode_from_mirror(*instance->ctrl_reg_mirror), - instance->ctrl_reg); - spin_unlock(instance->ctrl_reg_lock); - } else { - PERROR("Invalid port direction.\n"); - err = ME_ERRNO_INVALID_SINGLE_CONFIG; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8255_io_single_read(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - me8255_subdevice_t *instance; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8255_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - *value = inb(instance->port_reg) & (0x1 << channel); - } else { - PERROR("Invalid bit number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - *value = inb(instance->port_reg); - } else { - PERROR("Invalid byte number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8255_io_single_write(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - me8255_subdevice_t *instance; - uint8_t byte; - int err = ME_ERRNO_SUCCESS; - - PDEBUG("executed.\n"); - - instance = (me8255_subdevice_t *) subdevice; - - ME_SUBDEVICE_ENTER; - - spin_lock(&instance->subdevice_lock); - switch (flags) { - case ME_IO_SINGLE_TYPE_DIO_BIT: - if ((channel >= 0) && (channel < 8)) { - if (*instance-> - ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT << - instance->dio_idx)) { - byte = inb(instance->port_reg); - - if (value) - byte |= 0x1 << channel; - else - byte &= ~(0x1 << channel); - - outb(byte, instance->port_reg); - } else { - PERROR("Port not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid bit number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - case ME_IO_SINGLE_NO_FLAGS: - case ME_IO_SINGLE_TYPE_DIO_BYTE: - if (channel == 0) { - if (*instance-> - ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT << - instance->dio_idx)) { - outb(value, instance->port_reg); - } else { - PERROR("Port not in output mode.\n"); - err = ME_ERRNO_PREVIOUS_CONFIG; - } - } else { - PERROR("Invalid byte number.\n"); - err = ME_ERRNO_INVALID_CHANNEL; - } - break; - - default: - PERROR("Invalid flags specified.\n"); - err = ME_ERRNO_INVALID_FLAGS; - } - spin_unlock(&instance->subdevice_lock); - - ME_SUBDEVICE_EXIT; - - return err; -} - -static int me8255_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = ME8255_NUMBER_CHANNELS; - return ME_ERRNO_SUCCESS; -} - -static int me8255_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = ME_TYPE_DIO; - *subtype = ME_SUBTYPE_SINGLE; - return ME_ERRNO_SUCCESS; -} - -static int me8255_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = ME_CAPS_DIO_DIR_BYTE; - return ME_ERRNO_SUCCESS; -} - -me8255_subdevice_t *me8255_constructor(uint32_t device_id, - uint32_t reg_base, - unsigned int me8255_idx, - unsigned int dio_idx, - int *ctrl_reg_mirror, - spinlock_t *ctrl_reg_lock) -{ - me8255_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(me8255_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for 8255 instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(me8255_subdevice_t)); - - /* Check if counter index is out of range */ - - if (dio_idx > 2) { - PERROR("DIO index is out of range.\n"); - kfree(subdevice); - return NULL; - } - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the pointer to global port settings */ - subdevice->ctrl_reg_mirror = ctrl_reg_mirror; - - /* Save type of Meilhaus device */ - subdevice->device_id = device_id; - - /* Save the indices */ - subdevice->me8255_idx = me8255_idx; - subdevice->dio_idx = dio_idx; - - /* Do device specific initialization */ - switch (device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME1400: - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - - case PCI_DEVICE_ID_MEILHAUS_ME140A: - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - /* Check if 8255 index is out of range */ - if (me8255_idx > 0) { - PERROR("8255 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - case PCI_DEVICE_ID_MEILHAUS_ME140B: /* Fall through */ - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - /* Check if 8255 index is out of range */ - if (me8255_idx > 1) { - PERROR("8255 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - /* Get the registers */ - if (me8255_idx == 0) { - subdevice->ctrl_reg = reg_base + ME1400AB_PORT_A_CTRL; - subdevice->port_reg = - reg_base + ME1400AB_PORT_A_0 + dio_idx; - } else if (me8255_idx == 1) { - subdevice->ctrl_reg = reg_base + ME1400AB_PORT_B_CTRL; - subdevice->port_reg = - reg_base + ME1400AB_PORT_B_0 + dio_idx; - } - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - /* Check if 8255 index is out of range */ - if (me8255_idx > 0) { - PERROR("8255 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - case PCI_DEVICE_ID_MEILHAUS_ME140D: /* Fall through */ - /* Check if 8255 index is out of range */ - if (me8255_idx > 1) { - PERROR("8255 index is out of range.\n"); - me_subdevice_deinit(&subdevice->base); - kfree(subdevice); - return NULL; - } - - /* Get the registers */ - if (me8255_idx == 0) { - subdevice->ctrl_reg = reg_base + ME1400CD_PORT_A_CTRL; - subdevice->port_reg = - reg_base + ME1400CD_PORT_A_0 + dio_idx; - } else if (me8255_idx == 1) { - subdevice->ctrl_reg = reg_base + ME1400CD_PORT_B_CTRL; - subdevice->port_reg = - reg_base + ME1400CD_PORT_B_0 + dio_idx; - } - - break; - - default: - PERROR("Unknown device type. dev ID: 0x%04x\n", device_id); - - me_subdevice_deinit(&subdevice->base); - - kfree(subdevice); - - return NULL; - } - - /* Overload subdevice base class methods. */ - subdevice->base.me_subdevice_io_reset_subdevice = - me8255_io_reset_subdevice; - subdevice->base.me_subdevice_io_single_config = me8255_io_single_config; - subdevice->base.me_subdevice_io_single_read = me8255_io_single_read; - subdevice->base.me_subdevice_io_single_write = me8255_io_single_write; - subdevice->base.me_subdevice_query_number_channels = - me8255_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - me8255_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - me8255_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/me8255.h b/drivers/staging/meilhaus/me8255.h deleted file mode 100644 index 338230052b3..00000000000 --- a/drivers/staging/meilhaus/me8255.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file me8255.h - * - * @brief Meilhaus PIO 8255 implementation. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME8255_H_ -#define _ME8255_H_ - -#include "mesubdevice.h" -#include "meslock.h" - -#ifdef __KERNEL__ - -/** - * @brief The 8255 subdevice class. - */ -typedef struct me8255_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - - int *ctrl_reg_mirror; /**< Pointer to mirror of the control register. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */ - - uint32_t device_id; /**< The PCI device id of the device holding the 8255 chip. */ - int me8255_idx; /**< The index of the 8255 chip on the device. */ - int dio_idx; /**< The index of the DIO port on the 8255 chip. */ - - unsigned long port_reg; /**< Register to read or write a value from or to the port respectively. */ - unsigned long ctrl_reg; /**< Register to configure the 8255 modes. */ -} me8255_subdevice_t; - -/** - * @brief The constructor to generate a 8255 instance. - * - * @param device_id The kind of Meilhaus device holding the 8255. - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param me8255_idx The index of the 8255 chip on the Meilhaus device. - * @param dio_idx The index of the counter inside a 8255 chip. - * @param ctr_reg_mirror Pointer to mirror of control register. - * @param ctrl_reg_lock Pointer to spin lock protecting the 8255 control register and #ctrl_reg_mirror from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -me8255_subdevice_t *me8255_constructor(uint32_t device_id, - uint32_t reg_base, - unsigned int me8255_idx, - unsigned int dio_idx, - int *ctrl_reg_mirror, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/me8255_reg.h b/drivers/staging/meilhaus/me8255_reg.h deleted file mode 100644 index d1dea1a447f..00000000000 --- a/drivers/staging/meilhaus/me8255_reg.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file me8255_reg.h - * - * @brief 8255 counter register definitions. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME8255_REG_H_ -#define _ME8255_REG_H_ - -#ifdef __KERNEL__ - -#define ME8255_NUMBER_CHANNELS 8 /**< The number of channels per 8255 port. */ - -#define ME1400AB_PORT_A_0 0x0000 /**< Port 0 offset. */ -#define ME1400AB_PORT_A_1 0x0001 /**< Port 1 offset. */ -#define ME1400AB_PORT_A_2 0x0002 /**< Port 2 offset. */ -#define ME1400AB_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */ - -#define ME1400AB_PORT_B_0 0x0008 /**< Port 0 offset. */ -#define ME1400AB_PORT_B_1 0x0009 /**< Port 1 offset. */ -#define ME1400AB_PORT_B_2 0x000A /**< Port 2 offset. */ -#define ME1400AB_PORT_B_CTRL 0x000B /**< Control register for 8255 B. */ - -#define ME1400CD_PORT_A_0 0x0000 /**< Port 0 offset. */ -#define ME1400CD_PORT_A_1 0x0001 /**< Port 1 offset. */ -#define ME1400CD_PORT_A_2 0x0002 /**< Port 2 offset. */ -#define ME1400CD_PORT_A_CTRL 0x0003 /**< Control register for 8255 A. */ - -#define ME1400CD_PORT_B_0 0x0040 /**< Port 0 offset. */ -#define ME1400CD_PORT_B_1 0x0041 /**< Port 1 offset. */ -#define ME1400CD_PORT_B_2 0x0042 /**< Port 2 offset. */ -#define ME1400CD_PORT_B_CTRL 0x0043 /**< Control register for 8255 B. */ - -#define ME8255_MODE_OOO 0x80 /**< Port 2 = Output, Port 1 = Output, Port 0 = Output */ -#define ME8255_MODE_IOO 0x89 /**< Port 2 = Input, Port 1 = Output, Port 0 = Output */ -#define ME8255_MODE_OIO 0x82 /**< Port 2 = Output, Port 1 = Input, Port 0 = Output */ -#define ME8255_MODE_IIO 0x8B /**< Port 2 = Input, Port 1 = Input, Port 0 = Output */ -#define ME8255_MODE_OOI 0x90 /**< Port 2 = Output, Port 1 = Output, Port 0 = Input */ -#define ME8255_MODE_IOI 0x99 /**< Port 2 = Input, Port 1 = Output, Port 0 = Input */ -#define ME8255_MODE_OII 0x92 /**< Port 2 = Output, Port 1 = Input, Port 0 = Input */ -#define ME8255_MODE_III 0x9B /**< Port 2 = Input, Port 1 = Input, Port 0 = Input */ - -#define ME8255_PORT_0_OUTPUT 0x1 /**< If set in mirror then port 0 is in output mode. */ -#define ME8255_PORT_1_OUTPUT 0x2 /**< If set in mirror then port 1 is in output mode. */ -#define ME8255_PORT_2_OUTPUT 0x4 /**< If set in mirror then port 2 is in output mode. */ - -#endif -#endif diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h deleted file mode 100644 index 516658522ef..00000000000 --- a/drivers/staging/meilhaus/mecirc_buf.h +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file mecirc_buf.h - * - * @brief Meilhaus circular buffer implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MECIRC_BUF_H_ -#define _MECIRC_BUF_H_ - -# ifdef __KERNEL__ - -# ifdef BOSCH - -typedef struct me_circ_buf { - unsigned int mask; -// unsigned int count; - uint32_t *buf; - int volatile head; - int volatile tail; -} me_circ_buf_t; - -static inline int me_circ_buf_values(me_circ_buf_t * buf) -{ -// return ((buf->head - buf->tail) & (buf->count - 1)); - return ((buf->head - buf->tail) & (buf->mask)); -} - -static inline int me_circ_buf_space(me_circ_buf_t * buf) -{ -// return ((buf->tail - (buf->head + 1)) & (buf->count - 1)); - return ((buf->tail - (buf->head + 1)) & (buf->mask)); -} - -static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf) -{ - int end; - int n; -// end = buf->count - buf->tail; -// n = (buf->head + end) & (buf->count - 1); - end = buf->mask + 1 - buf->tail; - n = (buf->head + end) & (buf->mask); - return (n < end) ? n : end; -} - -static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf) -{ - int end; - int n; - -// end = buf->count - 1 - buf->head; -// n = (end + buf->tail) & (buf->count - 1); - end = buf->mask - buf->head; - n = (end + buf->tail) & (buf->mask); - return (n <= end) ? n : (end + 1); -} - -#define _CBUFF_32b_t - -# else //~BOSCH -/// @note buf->mask = buf->count-1 = ME4600_AI_CIRC_BUF_COUNT-1 - -# ifdef _CBUFF_32b_t - //32 bit -typedef struct me_circ_buf_32b { - int volatile head; - int volatile tail; - unsigned int mask; //buffor size-1 must be 2^n-1 to work - uint32_t *buf; -} me_circ_buf_t; -# else - //16 bit -typedef struct me_circ_buf_16b { - int volatile head; - int volatile tail; - unsigned int mask; //buffor size-1 must be 2^n-1 to work - uint16_t *buf; -} me_circ_buf_t; -# endif //_CBUFF_32b_t - -/** How many values is in buffer */ -static inline int me_circ_buf_values(me_circ_buf_t * buf) -{ - return ((buf->head - buf->tail) & (buf->mask)); -} - -/** How many space left */ -static inline int me_circ_buf_space(me_circ_buf_t * buf) -{ - return ((buf->tail - (buf->head + 1)) & (buf->mask)); -} - -/** How many values can be read from buffor in one chunck. */ -static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf) -{ - return (buf->tail <= - buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail + - 1); -} - -/** How many values can be write to buffer in one chunck. */ -static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf) -{ - return (buf->tail <= - buf->head) ? (buf->mask - buf->head + 1) : (buf->tail - - buf->head - 1); -} - -# endif //BOSCH -# endif //__KERNEL__ -#endif //_MECIRC_BUF_H_ diff --git a/drivers/staging/meilhaus/mecommon.h b/drivers/staging/meilhaus/mecommon.h deleted file mode 100644 index ef47c384e01..00000000000 --- a/drivers/staging/meilhaus/mecommon.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File :mecommon.h - * Author :GG (Guenter Gebhardt) - * Author :KG (Krzysztof Gantzke) - */ - -#ifndef _MECOMMON_H_ -#define _MECOMMON_H_ - -/*================================================================== - The version of this release - ================================================================*/ - -#ifndef ME_VERSION_DRIVER -/* Unknown version */ -# define ME_VERSION_DRIVER 0xFFFFFFFF -#endif - -#ifndef LIBMEDRIVER_VERSION -/* Unknown version */ -# define LIBMEDRIVER_VERSION 0xFFFFFFFF -#endif - -#endif diff --git a/drivers/staging/meilhaus/medebug.h b/drivers/staging/meilhaus/medebug.h deleted file mode 100644 index dcfb97c26fd..00000000000 --- a/drivers/staging/meilhaus/medebug.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file medebug.h - * - * @brief Debugging defines. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -#ifndef _MEDEBUG_H_ -#define _MEDEBUG_H_ - -#ifdef __KERNEL__ - -#include - -//Messages control. - -#ifdef MEDEBUG_TEST_ALL /* Switch to enable all info messages. */ -# ifndef MEDEBUG_TEST -# define MEDEBUG_TEST -# endif -# ifndef MEDEBUG_TEST_INFO -# define MEDEBUG_TEST_INFO -# endif -# ifndef MEDEBUG_DEBUG_REG -# define MEDEBUG_DEBUG_REG /* Switch to enable registry access debuging messages. */ -# endif -# ifndef MEDEBUG_DEBUG_LOCKS -# define MEDEBUG_DEBUG_LOCKS /* Switch to enable locking messages. */ -# endif -#endif - -#ifdef MEDEBUG_TEST_INFO /* Switch to enable info and test messages. */ -# ifndef MEDEBUG_INFO -# define MEDEBUG_INFO /* Switch to enable info messages. */ -# endif -# ifndef MEDEBUG_TEST -# define MEDEBUG_TEST -# endif -#endif - -#ifdef MEDEBUG_TEST /* Switch to enable debug test messages. */ -# ifndef MEDEBUG_DEBUG -# define MEDEBUG_DEBUG /* Switch to enable debug messages. */ -# endif -# ifndef MEDEBUG_ERROR -# define MEDEBUG_ERROR /* Switch to enable error messages. */ -# endif -#endif - -#ifdef MEDEBUG_ERROR /* Switch to enable error messages. */ -# ifndef MEDEBUG_ERROR_CRITICAL /* Also critical error messages. */ -# define MEDEBUG_ERROR_CRITICAL /* Switch to enable high importance error messages. */ -# endif -#endif - -#undef PDEBUG /* Only to be sure. */ -#undef PINFO /* Only to be sure. */ -#undef PERROR /* Only to be sure. */ -#undef PERROR_CRITICAL /* Only to be sure. */ -#undef PDEBUG_REG /* Only to be sure. */ -#undef PDEBUG_LOCKS /* Only to be sure. */ -#undef PSECURITY /* Only to be sure. */ -#undef PLOG /* Only to be sure. */ - -#ifdef MEDEBUG_DEBUG -# define PDEBUG(fmt, args...) \ - printk(KERN_DEBUG"ME_DRV D: <%s> " fmt, __func__, ##args) -#else -# define PDEBUG(fmt, args...) -#endif - -#ifdef MEDEBUG_DEBUG_LOCKS -# define PDEBUG_LOCKS(fmt, args...) \ - printk(KERN_DEBUG"ME_DRV L: <%s> " fmt, __func__, ##args) -#else -# define PDEBUG_LOCKS(fmt, args...) -#endif - -#ifdef MEDEBUG_DEBUG_REG -# define PDEBUG_REG(fmt, args...) \ - printk(KERN_DEBUG"ME_DRV R: <%s:%d> REG:" fmt, __func__, __LINE__, ##args) -#else -# define PDEBUG_REG(fmt, args...) -#endif - -#ifdef MEDEBUG_INFO -# define PINFO(fmt, args...) \ - printk(KERN_INFO"ME_DRV I: " fmt, ##args) -#else -# define PINFO(fmt, args...) -#endif - -#ifdef MEDEBUG_ERROR -# define PERROR(fmt, args...) \ - printk(KERN_ERR"ME_DRV E: <%s:%i> " fmt, __FILE__, __LINE__, ##args) -#else -# define PERROR(fmt, args...) -#endif - -#ifdef MEDEBUG_ERROR_CRITICAL -# define PERROR_CRITICAL(fmt, args...) \ - printk(KERN_CRIT"ME_DRV C: <%s:%i> " fmt, __FILE__, __LINE__, ##args) -#else -# define PERROR_CRITICAL(fmt, args...) -#endif - -//This debug is only to detect logical errors! -# define PSECURITY(fmt, args...) \ - printk(KERN_CRIT"ME_DRV SECURITY: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args) -//This debug is to keep track in customers' system -# define PLOG(fmt, args...) \ - printk(KERN_INFO"ME_DRV: " fmt, ##args) - -//This debug is to check new parts during development -#ifdef MEDEBUG_DEVELOP -# define PDEVELOP(fmt, args...) \ - printk(KERN_CRIT"ME_DRV: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args) -#else -# define PDEVELOP(fmt, args...) -#endif - -#endif //__KERNEL__ -#endif //_MEDEBUG_H_ diff --git a/drivers/staging/meilhaus/medefines.h b/drivers/staging/meilhaus/medefines.h deleted file mode 100644 index 6158ef5b80e..00000000000 --- a/drivers/staging/meilhaus/medefines.h +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : medefines.h - * Author : GG (Guenter Gebhardt) - * Author : KG (Krzysztof Gantzke) - */ - -#ifndef _MEDEFINES_H_ -#define _MEDEFINES_H_ - -/*================================================================== - General - ================================================================*/ - -#define ME_VALUE_NOT_USED 0x0 -#define ME_VALUE_INVALID ~0x0 - -/*================================================================== - Defines common to access functions - ================================================================*/ - -#define ME_LOCK_RELEASE 0x00010001 -#define ME_LOCK_SET 0x00010002 -#define ME_LOCK_CHECK 0x00010003 - -/*================================================================== - Defines meOpen function - ================================================================*/ - -#define ME_OPEN_NO_FLAGS 0x0 - -/*================================================================== - Defines meClose function - ================================================================*/ - -#define ME_CLOSE_NO_FLAGS 0x0 - -/*================================================================== - Defines meLockDriver function - ================================================================*/ - -#define ME_LOCK_DRIVER_NO_FLAGS 0x0 - -/*================================================================== - Defines meLockDevice function - ================================================================*/ - -#define ME_LOCK_DEVICE_NO_FLAGS 0x0 - -/*================================================================== - Defines meLockSubdevice function - ================================================================*/ - -#define ME_LOCK_SUBDEVICE_NO_FLAGS 0x0 - - -/*================================================================== - Defines common to error functions - ================================================================*/ - -#define ME_ERROR_MSG_MAX_COUNT 256 - -#define ME_SWITCH_DISABLE 0x00020001 -#define ME_SWITCH_ENABLE 0x00020002 - -/*================================================================== - Defines common to io functions - ================================================================*/ - -#define ME_REF_DIO_FIFO_LOW 0x00030001 -#define ME_REF_DIO_FIFO_HIGH 0x00030002 - -#define ME_REF_CTR_PREVIOUS 0x00040001 -#define ME_REF_CTR_INTERNAL_1MHZ 0x00040002 -#define ME_REF_CTR_INTERNAL_10MHZ 0x00040003 -#define ME_REF_CTR_EXTERNAL 0x00040004 - -#define ME_REF_AI_GROUND 0x00050001 -#define ME_REF_AI_DIFFERENTIAL 0x00050002 - -#define ME_REF_AO_GROUND 0x00060001 - -#define ME_TRIG_CHAN_DEFAULT 0x00070001 -#define ME_TRIG_CHAN_SYNCHRONOUS 0x00070002 - -#define ME_TRIG_TYPE_NONE 0x00000000 -#define ME_TRIG_TYPE_SW 0x00080001 -#define ME_TRIG_TYPE_THRESHOLD 0x00080002 -#define ME_TRIG_TYPE_WINDOW 0x00080003 -#define ME_TRIG_TYPE_EDGE 0x00080004 -#define ME_TRIG_TYPE_SLOPE 0x00080005 -#define ME_TRIG_TYPE_EXT_DIGITAL 0x00080006 -#define ME_TRIG_TYPE_EXT_ANALOG 0x00080007 -#define ME_TRIG_TYPE_PATTERN 0x00080008 -#define ME_TRIG_TYPE_TIMER 0x00080009 -#define ME_TRIG_TYPE_COUNT 0x0008000A -#define ME_TRIG_TYPE_FOLLOW 0x0008000B - -#define ME_TRIG_EDGE_NONE 0x00000000 -#define ME_TRIG_EDGE_ABOVE 0x00090001 -#define ME_TRIG_EDGE_BELOW 0x00090002 -#define ME_TRIG_EDGE_ENTRY 0x00090003 -#define ME_TRIG_EDGE_EXIT 0x00090004 -#define ME_TRIG_EDGE_RISING 0x00090005 -#define ME_TRIG_EDGE_FALLING 0x00090006 -#define ME_TRIG_EDGE_ANY 0x00090007 - -#define ME_TIMER_ACQ_START 0x000A0001 -#define ME_TIMER_SCAN_START 0x000A0002 -#define ME_TIMER_CONV_START 0x000A0003 - -/*================================================================== - Defines for meIOFrequencyToTicks function - ================================================================*/ - -#define ME_IO_FREQUENCY_TO_TICKS_NO_FLAGS 0x0 - -/*================================================================== - Defines for meIOIrqStart function - ================================================================*/ - -#define ME_IRQ_SOURCE_DIO_PATTERN 0x000B0001 -#define ME_IRQ_SOURCE_DIO_MASK 0x000B0002 -#define ME_IRQ_SOURCE_DIO_LINE 0x000B0003 -#define ME_IRQ_SOURCE_DIO_OVER_TEMP 0x000B0004 - -#define ME_IRQ_EDGE_NOT_USED 0x00000000 -#define ME_IRQ_EDGE_RISING 0x000C0001 -#define ME_IRQ_EDGE_FALLING 0x000C0002 -#define ME_IRQ_EDGE_ANY 0x000C0003 - -/*================================================================== - Defines for meIOIrqStart function - ================================================================*/ - -#define ME_IO_IRQ_START_NO_FLAGS 0x000000 -#define ME_IO_IRQ_START_DIO_BIT 0x000001 -#define ME_IO_IRQ_START_DIO_BYTE 0x000002 -#define ME_IO_IRQ_START_DIO_WORD 0x000004 -#define ME_IO_IRQ_START_DIO_DWORD 0x000008 -#define ME_IO_IRQ_START_PATTERN_FILTERING 0x000010 -#define ME_IO_IRQ_START_EXTENDED_STATUS 0x000020 - -/*================================================================== - Defines for meIOIrqWait function - ================================================================*/ - -#define ME_IO_IRQ_WAIT_NO_FLAGS 0x000000 -#define ME_IO_IRQ_WAIT_NORMAL_STATUS 0x000001 -#define ME_IO_IRQ_WAIT_EXTENDED_STATUS 0x000002 - -/*================================================================== - Defines for meIOIrqStop function - ================================================================*/ - -#define ME_IO_IRQ_STOP_NO_FLAGS 0x000000 - -/*================================================================== - Defines for meIOIrqSetCallback function - ================================================================*/ - -#define ME_IO_IRQ_SET_CALLBACK_NO_FLAGS 0x0 - -/*================================================================== - Defines for meIOResetDevice function - ================================================================*/ - -#define ME_IO_RESET_DEVICE_NO_FLAGS 0x0 - -/*================================================================== - Defines for meIOResetSubdevice function - ================================================================*/ - -#define ME_IO_RESET_SUBDEVICE_NO_FLAGS 0x0 - -/*================================================================== - Defines for meIOSingleConfig function - ================================================================*/ - -#define ME_SINGLE_CONFIG_DIO_INPUT 0x000D0001 -#define ME_SINGLE_CONFIG_DIO_OUTPUT 0x000D0002 -#define ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE 0x000D0003 -#define ME_SINGLE_CONFIG_DIO_SINK 0x000D0004 -#define ME_SINGLE_CONFIG_DIO_SOURCE 0x000D0005 -#define ME_SINGLE_CONFIG_DIO_MUX32M 0x000D0006 -#define ME_SINGLE_CONFIG_DIO_DEMUX32 0x000D0007 -#define ME_SINGLE_CONFIG_DIO_BIT_PATTERN 0x000D0008 - -#define ME_SINGLE_CONFIG_CTR_8254_MODE_0 0x000E0001 -#define ME_SINGLE_CONFIG_CTR_8254_MODE_1 0x000E0002 -#define ME_SINGLE_CONFIG_CTR_8254_MODE_2 0x000E0003 -#define ME_SINGLE_CONFIG_CTR_8254_MODE_3 0x000E0004 -#define ME_SINGLE_CONFIG_CTR_8254_MODE_4 0x000E0005 -#define ME_SINGLE_CONFIG_CTR_8254_MODE_5 0x000E0006 - -#define ME_IO_SINGLE_CONFIG_NO_FLAGS 0x00 -#define ME_IO_SINGLE_CONFIG_DIO_BIT 0x01 -#define ME_IO_SINGLE_CONFIG_DIO_BYTE 0x02 -#define ME_IO_SINGLE_CONFIG_DIO_WORD 0x04 -#define ME_IO_SINGLE_CONFIG_DIO_DWORD 0x08 -#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_ON 0x10 -#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_OFF 0x20 -#define ME_IO_SINGLE_CONFIG_AI_RMS 0x40 -#define ME_IO_SINGLE_CONFIG_CONTINUE 0x80 - -/*================================================================== - Defines for meIOSingle function - ================================================================*/ - -#define ME_IO_SINGLE_NO_FLAGS 0x0 -#define ME_IO_SINGLE_NONBLOCKING 0x20 - -#define ME_DIR_INPUT 0x000F0001 -#define ME_DIR_OUTPUT 0x000F0002 - -#define ME_IO_SINGLE_TYPE_NO_FLAGS 0x00 -#define ME_IO_SINGLE_TYPE_DIO_BIT 0x01 -#define ME_IO_SINGLE_TYPE_DIO_BYTE 0x02 -#define ME_IO_SINGLE_TYPE_DIO_WORD 0x04 -#define ME_IO_SINGLE_TYPE_DIO_DWORD 0x08 -#define ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS 0x10 -#define ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING 0x20 - -/*================================================================== - Defines for meIOStreamConfig function - ================================================================*/ - -#define ME_IO_STREAM_CONFIG_NO_FLAGS 0x0 -#define ME_IO_STREAM_CONFIG_BIT_PATTERN 0x1 -#define ME_IO_STREAM_CONFIG_WRAPAROUND 0x2 -#define ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD 0x4 -#define ME_IO_STREAM_CONFIG_HARDWARE_ONLY 0x8 - -#define ME_IO_STREAM_CONFIG_TYPE_NO_FLAGS 0x0 - -#define ME_IO_STREAM_TRIGGER_TYPE_NO_FLAGS 0x0 - -/*================================================================== - Defines for meIOStreamRead function - ================================================================*/ - -#define ME_READ_MODE_BLOCKING 0x00100001 -#define ME_READ_MODE_NONBLOCKING 0x00100002 - -#define ME_IO_STREAM_READ_NO_FLAGS 0x0 -#define ME_IO_STREAM_READ_FRAMES 0x1 - -/*================================================================== - Defines for meIOStreamWrite function - ================================================================*/ - -#define ME_WRITE_MODE_BLOCKING 0x00110001 -#define ME_WRITE_MODE_NONBLOCKING 0x00110002 -#define ME_WRITE_MODE_PRELOAD 0x00110003 - -#define ME_IO_STREAM_WRITE_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for meIOStreamStart function - ================================================================*/ - -#define ME_IO_STREAM_START_NO_FLAGS 0x00000000 - -#define ME_START_MODE_BLOCKING 0x00120001 -#define ME_START_MODE_NONBLOCKING 0x00120002 - -#define ME_IO_STREAM_START_TYPE_NO_FLAGS 0x0 -#define ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS 0x1 - -/*================================================================== - Defines for meIOStreamStop function - ================================================================*/ - -#define ME_IO_STREAM_STOP_NO_FLAGS 0x00000000 -#define ME_IO_STREAM_STOP_PRESERVE_BUFFERS 0x00000001 - -#define ME_STOP_MODE_IMMEDIATE 0x00130001 -#define ME_STOP_MODE_LAST_VALUE 0x00130002 - -#define ME_IO_STREAM_STOP_TYPE_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for meIOStreamStatus function - ================================================================*/ - -#define ME_WAIT_NONE 0x00140001 -#define ME_WAIT_IDLE 0x00140002 - -#define ME_STATUS_INVALID 0x00000000 -#define ME_STATUS_IDLE 0x00150001 -#define ME_STATUS_BUSY 0x00150002 -#define ME_STATUS_ERROR 0x00150003 - -#define ME_IO_STREAM_STATUS_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for meIOStreamSetCallbacks function - ================================================================*/ - -#define ME_IO_STREAM_SET_CALLBACKS_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for meIOStreamNewValues function - ================================================================*/ - -#define ME_IO_STREAM_NEW_VALUES_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for meIOTimeToTicks function - ================================================================*/ - -#define ME_IO_STREAM_TIME_TO_TICKS_NO_FLAGS 0x00000000 - -/*================================================================== - Defines for module types - ================================================================*/ - -#define ME_MODULE_TYPE_MULTISIG_NONE 0x00000000 -#define ME_MODULE_TYPE_MULTISIG_DIFF16_10V 0x00160001 -#define ME_MODULE_TYPE_MULTISIG_DIFF16_20V 0x00160002 -#define ME_MODULE_TYPE_MULTISIG_DIFF16_50V 0x00160003 -#define ME_MODULE_TYPE_MULTISIG_CURRENT16_0_20MA 0x00160004 -#define ME_MODULE_TYPE_MULTISIG_RTD8_PT100 0x00160005 -#define ME_MODULE_TYPE_MULTISIG_RTD8_PT500 0x00160006 -#define ME_MODULE_TYPE_MULTISIG_RTD8_PT1000 0x00160007 -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_B 0x00160008 -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_E 0x00160009 -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_J 0x0016000A -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_K 0x0016000B -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_N 0x0016000C -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_R 0x0016000D -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_S 0x0016000E -#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_T 0x0016000F -#define ME_MODULE_TYPE_MULTISIG_TE8_TEMP_SENSOR 0x00160010 - -/*================================================================== - Defines for meQuerySubdeviceCaps function - ================================================================*/ - -#define ME_CAPS_NONE 0x00000000 - -#define ME_CAPS_DIO_DIR_BIT 0x00000001 -#define ME_CAPS_DIO_DIR_BYTE 0x00000002 -#define ME_CAPS_DIO_DIR_WORD 0x00000004 -#define ME_CAPS_DIO_DIR_DWORD 0x00000008 -#define ME_CAPS_DIO_SINK_SOURCE 0x00000010 -#define ME_CAPS_DIO_BIT_PATTERN_IRQ 0x00000020 -#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING 0x00000040 -#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING 0x00000080 -#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY 0x00000100 -#define ME_CAPS_DIO_OVER_TEMP_IRQ 0x00000200 - -#define ME_CAPS_CTR_CLK_PREVIOUS 0x00000001 -#define ME_CAPS_CTR_CLK_INTERNAL_1MHZ 0x00000002 -#define ME_CAPS_CTR_CLK_INTERNAL_10MHZ 0x00000004 -#define ME_CAPS_CTR_CLK_EXTERNAL 0x00000008 - -#define ME_CAPS_AI_TRIG_SYNCHRONOUS 0x00000001 -/// @note Backward compatibility for me1600 in old style. -#define ME_CAPS_AI_TRIG_SIMULTANEOUS ME_CAPS_AI_TRIG_SYNCHRONOUS -#define ME_CAPS_AI_FIFO 0x00000002 -#define ME_CAPS_AI_FIFO_THRESHOLD 0x00000004 - -#define ME_CAPS_AO_TRIG_SYNCHRONOUS 0x00000001 -/// @note Backward compatibility for me1600 in old style. -#define ME_CAPS_AO_TRIG_SIMULTANEOUS ME_CAPS_AO_TRIG_SYNCHRONOUS -#define ME_CAPS_AO_FIFO 0x00000002 -#define ME_CAPS_AO_FIFO_THRESHOLD 0x00000004 - -#define ME_CAPS_EXT_IRQ_EDGE_RISING 0x00000001 -#define ME_CAPS_EXT_IRQ_EDGE_FALLING 0x00000002 -#define ME_CAPS_EXT_IRQ_EDGE_ANY 0x00000004 - -/*================================================================== - Defines for meQuerySubdeviceCapsArgs function - ================================================================*/ - -#define ME_CAP_AI_FIFO_SIZE 0x001D0000 -#define ME_CAP_AI_BUFFER_SIZE 0x001D0001 - -#define ME_CAP_AO_FIFO_SIZE 0x001F0000 -#define ME_CAP_AO_BUFFER_SIZE 0x001F0001 - -#define ME_CAP_CTR_WIDTH 0x00200000 - -/*================================================================== - Defines common to query functions - ================================================================*/ - -#define ME_UNIT_INVALID 0x00000000 -#define ME_UNIT_VOLT 0x00170001 -#define ME_UNIT_AMPERE 0x00170002 -#define ME_UNIT_ANY 0x00170003 - -#define ME_TYPE_INVALID 0x00000000 -#define ME_TYPE_AO 0x00180001 -#define ME_TYPE_AI 0x00180002 -#define ME_TYPE_DIO 0x00180003 -#define ME_TYPE_DO 0x00180004 -#define ME_TYPE_DI 0x00180005 -#define ME_TYPE_CTR 0x00180006 -#define ME_TYPE_EXT_IRQ 0x00180007 - -#define ME_SUBTYPE_INVALID 0x00000000 -#define ME_SUBTYPE_SINGLE 0x00190001 -#define ME_SUBTYPE_STREAMING 0x00190002 -#define ME_SUBTYPE_CTR_8254 0x00190003 -#define ME_SUBTYPE_ANY 0x00190004 - -#define ME_DEVICE_DRIVER_NAME_MAX_COUNT 64 -#define ME_DEVICE_NAME_MAX_COUNT 64 - -#define ME_DEVICE_DESCRIPTION_MAX_COUNT 256 - -#define ME_BUS_TYPE_INVALID 0x00000000 -#define ME_BUS_TYPE_PCI 0x001A0001 -#define ME_BUS_TYPE_USB 0x001A0002 - -#define ME_PLUGGED_INVALID 0x00000000 -#define ME_PLUGGED_IN 0x001B0001 -#define ME_PLUGGED_OUT 0x001B0002 - -#define ME_EXTENSION_TYPE_INVALID 0x00000000 -#define ME_EXTENSION_TYPE_NONE 0x001C0001 -#define ME_EXTENSION_TYPE_MUX32M 0x001C0002 -#define ME_EXTENSION_TYPE_DEMUX32 0x001C0003 -#define ME_EXTENSION_TYPE_MUX32S 0x001C0004 - -#define ME_ACCESS_TYPE_INVALID 0x00000000 -#define ME_ACCESS_TYPE_LOCAL 0x001D0001 -#define ME_ACCESS_TYPE_REMOTE 0x001D0002 - -/// @note Add by KG - -/*================================================================== - Defines for meUtilityPWM - ================================================================*/ -#define ME_PWM_START_CONNECT_INTERNAL 0x00200001 - -/* Flags for SingleConfig channels configure */ -#define ME_SINGLE_CHANNEL_NOT_CONFIGURED 0x00 -#define ME_SINGLE_CHANNEL_CONFIGURED 0x01 - -/* Define if configuration should be downloaded to driver */ -#define ME_CONFIG_LOAD_NO_FLAGS 0x0 -#define ME_CONFIG_LOAD_TO_DRIVER 0x1 - -#endif diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c deleted file mode 100644 index 75aaec0f681..00000000000 --- a/drivers/staging/meilhaus/medevice.c +++ /dev/null @@ -1,1740 +0,0 @@ -/** - * @file medevice.c - * - * @brief Meilhaus device base class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "mecommon.h" -#include "meinternal.h" -#include "medefines.h" -#include "meerror.h" - -#include "medebug.h" -#include "medevice.h" - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -static int me_device_io_irq_start(struct me_device *device, - struct file *filep, - int subdevice, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_irq_start(s, - filep, - channel, - irq_source, - irq_edge, irq_arg, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_irq_wait(struct me_device *device, - struct file *filep, - int subdevice, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_irq_wait(s, - filep, - channel, - irq_count, - value, time_out, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_irq_stop(struct me_device *device, - struct file *filep, - int subdevice, int channel, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_irq_stop(s, filep, channel, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_reset_device(struct me_device *device, - struct file *filep, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - int i, n; - - PDEBUG("executed.\n"); - - /* Get the number of subdevices. */ - n = me_slist_get_number_subdevices(&device->slist); - - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - - /* Reset every subdevice in list. */ - for (i = 0; i < n; i++) { - s = me_slist_get_subdevice(&device->slist, i); - err = s->me_subdevice_io_reset_subdevice(s, filep, flags); - - if (err) { - PERROR("Cannot reset subdevice.\n"); - break; - } - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_reset_subdevice(struct me_device *device, - struct file *filep, - int subdevice, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_reset_subdevice(s, filep, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_single_config(struct me_device *device, - struct file *filep, - int subdevice, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_single_config(s, - filep, - channel, - single_config, - ref, - trig_chan, - trig_type, - trig_edge, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_single_read(struct me_device *device, - struct file *filep, - int subdevice, - int channel, - int *value, int time_out, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_single_read(s, - filep, - channel, - value, time_out, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_single_write(struct me_device *device, - struct file *filep, - int subdevice, - int channel, - int value, int time_out, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_single_write(s, - filep, - channel, - value, time_out, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_config(struct me_device *device, - struct file *filep, - int subdevice, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_config(s, - filep, - config_list, - count, - trigger, - fifo_irq_threshold, - flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_new_values(struct me_device *device, - struct file *filep, - int subdevice, - int time_out, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_new_values(s, - filep, - time_out, - count, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_read(struct me_device *device, - struct file *filep, - int subdevice, - int read_mode, - int *values, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_read(s, - filep, - read_mode, - values, count, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_start(struct me_device *device, - struct file *filep, - int subdevice, - int start_mode, int time_out, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_start(s, - filep, - start_mode, - time_out, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_status(struct me_device *device, - struct file *filep, - int subdevice, - int wait, - int *status, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_status(s, - filep, - wait, - status, count, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_stop(struct me_device *device, - struct file *filep, - int subdevice, int stop_mode, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_stop(s, - filep, stop_mode, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_io_stream_write(struct me_device *device, - struct file *filep, - int subdevice, - int write_mode, - int *values, int *count, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_io_stream_write(s, - filep, - write_mode, - values, count, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_lock_device(struct me_device *device, - struct file *filep, int lock, int flags) -{ - PDEBUG("executed.\n"); - - return me_dlock_lock(&device->dlock, - filep, lock, flags, &device->slist); -} - -static int me_device_lock_subdevice(struct me_device *device, - struct file *filep, - int subdevice, int lock, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Enter device. - err = me_dlock_enter(&device->dlock, filep); - - if (err) { - PERROR("Cannot enter device.\n"); - return err; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_lock_subdevice(s, filep, lock, flags); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - // Exit device. - me_dlock_exit(&device->dlock, filep); - - return err; -} - -static int me_device_query_description_device(struct me_device *device, - char **description) -{ - PDEBUG("executed.\n"); - *description = device->device_description; - return ME_ERRNO_SUCCESS; -} - -static int me_device_query_info_device(struct me_device *device, - int *vendor_id, - int *device_id, - int *serial_no, - int *bus_type, - int *bus_no, - int *dev_no, int *func_no, int *plugged) -{ - PDEBUG("executed.\n"); - - if (device->bus_type == ME_BUS_TYPE_PCI) { - *vendor_id = device->info.pci.vendor_id; - *device_id = device->info.pci.device_id; - *serial_no = device->info.pci.serial_no; - *bus_type = ME_BUS_TYPE_PCI; - *bus_no = device->info.pci.pci_bus_no; - *dev_no = device->info.pci.pci_dev_no; - *func_no = device->info.pci.pci_func_no; - *plugged = ME_PLUGGED_IN; - } else { - *plugged = ME_PLUGGED_OUT; - } - return ME_ERRNO_SUCCESS; -} - -static int me_device_query_name_device(struct me_device *device, char **name) -{ - PDEBUG("executed.\n"); - *name = device->device_name; - return ME_ERRNO_SUCCESS; -} - -static int me_device_query_name_device_driver(struct me_device *device, - char **name) -{ - PDEBUG("executed.\n"); - *name = device->driver_name; - return ME_ERRNO_SUCCESS; -} - -static int me_device_query_number_subdevices(struct me_device *device, - int *number) -{ - PDEBUG("executed.\n"); - return me_slist_query_number_subdevices(&device->slist, number); -} - -static int me_device_query_number_channels(struct me_device *device, - int subdevice, int *number) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_number_channels(s, number); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_number_ranges(struct me_device *device, - int subdevice, int unit, int *count) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_number_ranges(s, unit, count); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_range_by_min_max(struct me_device *device, - int subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_range_by_min_max(s, - unit, - min, - max, - maxdata, range); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_range_info(struct me_device *device, - int subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_range_info(s, - range, - unit, min, max, maxdata); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_subdevice_by_type(struct me_device *device, - int start_subdevice, - int type, - int subtype, int *subdevice) -{ - PDEBUG("executed.\n"); - - return me_slist_get_subdevice_by_type(&device->slist, - start_subdevice, - type, subtype, subdevice); -} - -static int me_device_query_subdevice_type(struct me_device *device, - int subdevice, - int *type, int *subtype) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_subdevice_type(s, type, subtype); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_subdevice_caps(struct me_device *device, - int subdevice, int *caps) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_subdevice_caps(s, caps); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_subdevice_caps_args(struct me_device *device, - int subdevice, - int cap, int *args, int count) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_subdevice_caps_args(s, - cap, - args, count); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_timer(struct me_device *device, - int subdevice, - int timer, - int *base_frequency, - uint64_t *min_ticks, uint64_t *max_ticks) -{ - int err = ME_ERRNO_SUCCESS; - me_subdevice_t *s; - - PDEBUG("executed.\n"); - - // Check subdevice index. - - if (subdevice >= me_slist_get_number_subdevices(&device->slist)) { - PERROR("Invalid subdevice.\n"); - return ME_ERRNO_INVALID_SUBDEVICE; - } - // Get subdevice instance. - s = me_slist_get_subdevice(&device->slist, subdevice); - - if (s) { - // Call subdevice method. - err = s->me_subdevice_query_timer(s, - timer, - base_frequency, - min_ticks, max_ticks); - } else { - // Something really bad happened. - PERROR("Cannot get subdevice instance.\n"); - err = ME_ERRNO_INTERNAL; - } - - return err; -} - -static int me_device_query_version_device_driver(struct me_device *device, - int *version) -/** @todo Versions shold be read from driver. I must overwrite this function in each module. Here should be returned an error! -*/ -{ - PDEBUG("executed.\n"); - *version = ME_VERSION_DRIVER; - return ME_ERRNO_SUCCESS; -} - -static int me_device_config_load(struct me_device *device, struct file *filep, - me_cfg_device_entry_t *config) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_SUCCESS; //If no need for config return success. -// return ME_ERRNO_NOT_SUPPORTED; -} - -static void me_device_destructor(me_device_t *me_device) -{ - PDEBUG("executed.\n"); - me_device_deinit(me_device); - kfree(me_device); -} - -/* //me_device_usb_init -int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface) -{ - PDEBUG("executed.\n"); - return -1; -} -*/ - -static int get_device_descriptions(uint16_t device_id, - char **device_name, - char **device_description, - char **driver_name) -/** @todo This is wrong concept! Static table has too strong limitations! -* 'device_name' and 'driver_name' should be calculated from 'device_id' -* 'device_description' should be read from device or moved to user space and handled by library! -*/ -{ - PDEBUG("executed.\n"); - - switch (device_id) { - case PCI_DEVICE_ID_MEILHAUS_ME1000: - case PCI_DEVICE_ID_MEILHAUS_ME1000_A: - case PCI_DEVICE_ID_MEILHAUS_ME1000_B: - *device_name = ME1000_NAME_DEVICE_ME1000; - *device_description = ME1000_DESCRIPTION_DEVICE_ME1000; - *driver_name = ME1000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1400: - *device_name = ME1400_NAME_DEVICE_ME1400; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140A: - *device_name = ME1400_NAME_DEVICE_ME1400A; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400A; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140B: - *device_name = ME1400_NAME_DEVICE_ME1400B; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400B; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - *device_name = ME1400_NAME_DEVICE_ME1400E; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400E; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - *device_name = ME1400_NAME_DEVICE_ME1400EA; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EA; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - *device_name = ME1400_NAME_DEVICE_ME1400EB; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400EB; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - *device_name = ME1400_NAME_DEVICE_ME1400C; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400C; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140D: - *device_name = ME1400_NAME_DEVICE_ME1400D; - *device_description = ME1400_DESCRIPTION_DEVICE_ME1400D; - *driver_name = ME1400_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_4U: - *device_name = ME1600_NAME_DEVICE_ME16004U; - *device_description = ME1600_DESCRIPTION_DEVICE_ME16004U; - *driver_name = ME1600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_8U: - *device_name = ME1600_NAME_DEVICE_ME16008U; - *device_description = ME1600_DESCRIPTION_DEVICE_ME16008U; - *driver_name = ME1600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_12U: - *device_name = ME1600_NAME_DEVICE_ME160012U; - *device_description = ME1600_DESCRIPTION_DEVICE_ME160012U; - *driver_name = ME1600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U: - *device_name = ME1600_NAME_DEVICE_ME160016U; - *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U; - *driver_name = ME1600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I: - *device_name = ME1600_NAME_DEVICE_ME160016U8I; - *device_description = ME1600_DESCRIPTION_DEVICE_ME160016U8I; - *driver_name = ME1600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - *device_name = ME4600_NAME_DEVICE_ME4610; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4610; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4650: - *device_name = ME4600_NAME_DEVICE_ME4650; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4650; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660: - *device_name = ME4600_NAME_DEVICE_ME4660; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4660; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - *device_name = ME4600_NAME_DEVICE_ME4660I; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4660I; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660S: - *device_name = ME4600_NAME_DEVICE_ME4660S; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4660S; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660IS: - *device_name = ME4600_NAME_DEVICE_ME4660IS; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4660IS; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670: - *device_name = ME4600_NAME_DEVICE_ME4670; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4670; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - *device_name = ME4600_NAME_DEVICE_ME4670I; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4670I; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - *device_name = ME4600_NAME_DEVICE_ME4670S; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4670S; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - *device_name = ME4600_NAME_DEVICE_ME4670IS; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4670IS; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680: - *device_name = ME4600_NAME_DEVICE_ME4680; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4680; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - *device_name = ME4600_NAME_DEVICE_ME4680I; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4680I; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - *device_name = ME4600_NAME_DEVICE_ME4680S; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4680S; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - *device_name = ME4600_NAME_DEVICE_ME4680IS; - *device_description = ME4600_DESCRIPTION_DEVICE_ME4680IS; - *driver_name = ME4600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6004: - *device_name = ME6000_NAME_DEVICE_ME60004; - *device_description = ME6000_DESCRIPTION_DEVICE_ME60004; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6008: - *device_name = ME6000_NAME_DEVICE_ME60008; - *device_description = ME6000_DESCRIPTION_DEVICE_ME60008; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME600F: - *device_name = ME6000_NAME_DEVICE_ME600016; - *device_description = ME6000_DESCRIPTION_DEVICE_ME600016; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6014: - *device_name = ME6000_NAME_DEVICE_ME6000I4; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6018: - *device_name = ME6000_NAME_DEVICE_ME6000I8; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME601F: - *device_name = ME6000_NAME_DEVICE_ME6000I16; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6034: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE4; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6038: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE8; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME603F: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE16; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6104: - *device_name = ME6000_NAME_DEVICE_ME61004; - *device_description = ME6000_DESCRIPTION_DEVICE_ME61004; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6108: - *device_name = ME6000_NAME_DEVICE_ME61008; - *device_description = ME6000_DESCRIPTION_DEVICE_ME61008; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME610F: - *device_name = ME6000_NAME_DEVICE_ME610016; - *device_description = ME6000_DESCRIPTION_DEVICE_ME610016; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6114: - *device_name = ME6000_NAME_DEVICE_ME6100I4; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6118: - *device_name = ME6000_NAME_DEVICE_ME6100I8; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME611F: - *device_name = ME6000_NAME_DEVICE_ME6100I16; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6134: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE4; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6138: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE8; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME613F: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE16; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6044: - *device_name = ME6000_NAME_DEVICE_ME60004DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME60004DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6048: - *device_name = ME6000_NAME_DEVICE_ME60008DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME60008DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME604F: - *device_name = ME6000_NAME_DEVICE_ME600016DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME600016DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6054: - *device_name = ME6000_NAME_DEVICE_ME6000I4DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6058: - *device_name = ME6000_NAME_DEVICE_ME6000I8DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME605F: - *device_name = ME6000_NAME_DEVICE_ME6000I16DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6074: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE4DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6078: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE8DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME607F: - *device_name = ME6000_NAME_DEVICE_ME6000ISLE16DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6144: - *device_name = ME6000_NAME_DEVICE_ME61004DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME61004DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6148: - *device_name = ME6000_NAME_DEVICE_ME61008DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME61008DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME614F: - *device_name = ME6000_NAME_DEVICE_ME610016DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME610016DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6154: - *device_name = ME6000_NAME_DEVICE_ME6100I4DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6158: - *device_name = ME6000_NAME_DEVICE_ME6100I8DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME615F: - *device_name = ME6000_NAME_DEVICE_ME6100I16DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6174: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE4DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6178: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE8DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME617F: - *device_name = ME6000_NAME_DEVICE_ME6100ISLE16DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6259: - *device_name = ME6000_NAME_DEVICE_ME6200I9DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6359: - *device_name = ME6000_NAME_DEVICE_ME6300I9DIO; - *device_description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO; - *driver_name = ME6000_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0630: - *device_name = ME0600_NAME_DEVICE_ME0630; - *device_description = ME0600_DESCRIPTION_DEVICE_ME0630; - *driver_name = ME0600_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - *device_name = ME8100_NAME_DEVICE_ME8100A; - *device_description = ME8100_DESCRIPTION_DEVICE_ME8100A; - *driver_name = ME8100_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - *device_name = ME8100_NAME_DEVICE_ME8100B; - *device_description = ME8100_DESCRIPTION_DEVICE_ME8100B; - *driver_name = ME8100_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8200_A: - *device_name = ME8200_NAME_DEVICE_ME8200A; - *device_description = ME8200_DESCRIPTION_DEVICE_ME8200A; - *driver_name = ME8200_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8200_B: - *device_name = ME8200_NAME_DEVICE_ME8200B; - *device_description = ME8200_DESCRIPTION_DEVICE_ME8200B; - *driver_name = ME8200_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0940: - *device_name = ME0900_NAME_DEVICE_ME0940; - *device_description = ME0900_DESCRIPTION_DEVICE_ME0940; - *driver_name = ME0900_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0950: - *device_name = ME0900_NAME_DEVICE_ME0950; - *device_description = ME0900_DESCRIPTION_DEVICE_ME0950; - *driver_name = ME0900_NAME_DRIVER; - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0960: - *device_name = ME0900_NAME_DEVICE_ME0960; - *device_description = ME0900_DESCRIPTION_DEVICE_ME0960; - *driver_name = ME0900_NAME_DRIVER; - break; -/* - case USB_DEVICE_ID_MEPHISTO_S1: - *device_name = MEPHISTO_S1_NAME_DEVICE; - *device_description = MEPHISTO_S1_DESCRIPTION_DEVICE; - *driver_name = MEPHISTO_S1_NAME_DRIVER; - break; -*/ - default: - *device_name = EMPTY_NAME_DEVICE; - *device_description = EMPTY_DESCRIPTION_DEVICE; - *driver_name = EMPTY_NAME_DRIVER; - - PERROR("Invalid device id.\n"); - - return 1; - } - - return 0; -} - -int me_device_pci_init(me_device_t *me_device, struct pci_dev *pci_device) -{ - int err; - int i; - - PDEBUG("executed.\n"); - - // Initialize device list head. - INIT_LIST_HEAD(&me_device->list); - - // Initialize device description strings. - err = get_device_descriptions(pci_device->device, - &me_device->device_name, - &me_device->device_description, - &me_device->driver_name); - - if (err) { - PERROR("Cannot initialize device description strings.\n"); - return 1; - } - // Enable the pci device. - err = pci_enable_device(pci_device); - - if (err < 0) { - PERROR("Cannot enable PCI device.\n"); - return 1; - } - // Request the PCI register regions. - err = pci_request_regions(pci_device, me_device->device_name); - - if (err < 0) { - PERROR("Cannot request PCI regions.\n"); - goto ERROR_0; - } - // The bus carrying the device is a PCI bus. - me_device->bus_type = ME_BUS_TYPE_PCI; - - // Store the PCI information for later usage. - me_device->info.pci.pci_device = pci_device; - - // Get PCI register bases and sizes. - for (i = 0; i < 6; i++) { - me_device->info.pci.reg_bases[i] = - pci_resource_start(pci_device, i); - me_device->info.pci.reg_sizes[i] = - pci_resource_len(pci_device, i); - } - - // Get the PCI location. - me_device->info.pci.pci_bus_no = pci_device->bus->number; - me_device->info.pci.pci_dev_no = PCI_SLOT(pci_device->devfn); - me_device->info.pci.pci_func_no = PCI_FUNC(pci_device->devfn); - - // Get Meilhaus specific device information. - me_device->info.pci.vendor_id = pci_device->vendor; - me_device->info.pci.device_id = pci_device->device; - pci_read_config_byte(pci_device, 0x08, - &me_device->info.pci.hw_revision); - pci_read_config_dword(pci_device, 0x2C, &me_device->info.pci.serial_no); - - // Get the interrupt request number. - me_device->irq = pci_device->irq; - - // Initialize device lock instance. - err = me_dlock_init(&me_device->dlock); - - if (err) { - PERROR("Cannot initialize device lock instance.\n"); - goto ERROR_1; - } - // Initialize subdevice list instance. - me_slist_init(&me_device->slist); - - if (err) { - PERROR("Cannot initialize subdevice list instance.\n"); - goto ERROR_2; - } - // Initialize method pointers. - me_device->me_device_io_irq_start = me_device_io_irq_start; - me_device->me_device_io_irq_wait = me_device_io_irq_wait; - me_device->me_device_io_irq_stop = me_device_io_irq_stop; - me_device->me_device_io_reset_device = me_device_io_reset_device; - me_device->me_device_io_reset_subdevice = me_device_io_reset_subdevice; - me_device->me_device_io_single_config = me_device_io_single_config; - me_device->me_device_io_single_read = me_device_io_single_read; - me_device->me_device_io_single_write = me_device_io_single_write; - me_device->me_device_io_stream_config = me_device_io_stream_config; - me_device->me_device_io_stream_new_values = - me_device_io_stream_new_values; - me_device->me_device_io_stream_read = me_device_io_stream_read; - me_device->me_device_io_stream_start = me_device_io_stream_start; - me_device->me_device_io_stream_status = me_device_io_stream_status; - me_device->me_device_io_stream_stop = me_device_io_stream_stop; - me_device->me_device_io_stream_write = me_device_io_stream_write; - me_device->me_device_lock_device = me_device_lock_device; - me_device->me_device_lock_subdevice = me_device_lock_subdevice; - me_device->me_device_query_description_device = - me_device_query_description_device; - me_device->me_device_query_info_device = me_device_query_info_device; - me_device->me_device_query_name_device = me_device_query_name_device; - me_device->me_device_query_name_device_driver = - me_device_query_name_device_driver; - me_device->me_device_query_number_subdevices = - me_device_query_number_subdevices; - me_device->me_device_query_number_channels = - me_device_query_number_channels; - me_device->me_device_query_number_ranges = - me_device_query_number_ranges; - me_device->me_device_query_range_by_min_max = - me_device_query_range_by_min_max; - me_device->me_device_query_range_info = me_device_query_range_info; - me_device->me_device_query_subdevice_by_type = - me_device_query_subdevice_by_type; - me_device->me_device_query_subdevice_type = - me_device_query_subdevice_type; - me_device->me_device_query_subdevice_caps = - me_device_query_subdevice_caps; - me_device->me_device_query_subdevice_caps_args = - me_device_query_subdevice_caps_args; - me_device->me_device_query_timer = me_device_query_timer; - me_device->me_device_query_version_device_driver = - me_device_query_version_device_driver; - me_device->me_device_config_load = me_device_config_load; - me_device->me_device_destructor = me_device_destructor; - - return 0; - - ERROR_0: - me_dlock_deinit(&me_device->dlock); - - ERROR_1: - pci_release_regions(pci_device); - - ERROR_2: - pci_disable_device(pci_device); - - return 1; -} - -void me_device_deinit(me_device_t *me_device) -{ - PDEBUG("executed.\n"); - - me_slist_deinit(&me_device->slist); - me_dlock_deinit(&me_device->dlock); - - if (me_device->bus_type == ME_BUS_TYPE_PCI) { - pci_release_regions(me_device->info.pci.pci_device); - pci_disable_device(me_device->info.pci.pci_device); - } -/* - else - { - // Must be an USB device. - } -*/ -} diff --git a/drivers/staging/meilhaus/medevice.h b/drivers/staging/meilhaus/medevice.h deleted file mode 100644 index 25da82883e1..00000000000 --- a/drivers/staging/meilhaus/medevice.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : medevice.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEDEVICE_H_ -#define _MEDEVICE_H_ - -#ifndef KBUILD_MODNAME -# define KBUILD_MODNAME KBUILD_STR(memain) -#endif - -#include -//#include -#include -#include - -#include "metypes.h" -#include "meslist.h" -#include "medlock.h" - -#ifdef __KERNEL__ - -/** - * @brief Defines a pointer type to a PCI constructor function. - */ -typedef struct me_device *(*me_pci_constructor_t) (struct pci_dev *); - -/** - * @brief Defines a pointer type to a ME-4000 PCI constructor function. - */ -#ifdef BOSCH -typedef struct me_device *(*me_bosch_constructor_t) (struct pci_dev *, - int me_bosch_fw); -#endif - -/** - * @brief Defines a pointer type to a USB constructor function. - */ -//typedef struct me_device *(*me_usb_constructor_t)(struct usb_interface *); - -/** - * @brief Defines a pointer type to the dummy constructor function. - */ -typedef struct me_device *(*me_dummy_constructor_t) (unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, - int dev_no, int func_no); - -//extern me_usb_constructor_t mephisto_s1_constructor __attribute__ ((weak)); - -/** - * @brief Holds the PCI device information. - */ -typedef struct me_pci_info { - struct pci_dev *pci_device; /**< Kernel PCI device structure. */ - uint32_t reg_bases[6]; /**< The base adresses of the PCI bars. */ - uint32_t reg_sizes[6]; /**< The sizes of the PCI bars. */ - - uint32_t pci_bus_no; /**< PCI bus number. */ - uint32_t pci_dev_no; /**< PCI device number. */ - uint32_t pci_func_no; /**< PCI function number. */ - - uint16_t vendor_id; /**< Meilhaus PCI vendor id. */ - uint16_t device_id; /**< Meilhaus device id. */ - uint8_t hw_revision; /**< Hardware revision of the device. */ - uint32_t serial_no; /**< Serial number of the device. */ -} me_pci_info_t; - -/** - * @brief Holds the USB device information. - */ -//typedef struct me_usb_info { -//} me_usb_info_t; - -/** - * @brief The Meilhaus device base class structure. - */ -typedef struct me_device { - /* Attributes */ - struct list_head list; /**< Enables the device to be added to a dynamic list. */ -// int magic; /**< The magic number of the structure. */ - - int bus_type; /**< The descriminator for the union. */ - union { - me_pci_info_t pci; /**< PCI specific device information. */ -// me_usb_info_t usb; /**< USB specific device information. */ - } info; /**< Holds the device information. */ - - int irq; /**< The irq assigned to this device. */ - - me_dlock_t dlock; /**< The device locking structure. */ - me_slist_t slist; /**< The container holding all subdevices belonging to this device. */ - - char *device_name; /**< The name of the Meilhaus device. */ - char *device_description; /**< The description of the Meilhaus device. */ - char *driver_name; /**< The name of the device driver module supporting the device family. */ - - /* Methods */ - int (*me_device_io_irq_start) (struct me_device * device, - struct file * filep, - int subdevice, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags); - - int (*me_device_io_irq_wait) (struct me_device * device, - struct file * filep, - int subdevice, - int channel, - int *irq_count, - int *value, int time_out, int flags); - - int (*me_device_io_irq_stop) (struct me_device * device, - struct file * filep, - int subdevice, int channel, int flags); - - int (*me_device_io_reset_device) (struct me_device * device, - struct file * filep, int flags); - - int (*me_device_io_reset_subdevice) (struct me_device * device, - struct file * filep, - int subdevice, int flags); - - int (*me_device_io_single_config) (struct me_device * device, - struct file * filep, - int subdevice, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, - int trig_edge, int flags); - - int (*me_device_io_single_read) (struct me_device * device, - struct file * filep, - int subdevice, - int channel, - int *value, int time_out, int flags); - - int (*me_device_io_single_write) (struct me_device * device, - struct file * filep, - int subdevice, - int channel, - int value, int time_out, int flags); - - int (*me_device_io_stream_config) (struct me_device * device, - struct file * filep, - int subdevice, - meIOStreamConfig_t * config_list, - int count, - meIOStreamTrigger_t * trigger, - int fifo_irq_threshold, int flags); - - int (*me_device_io_stream_new_values) (struct me_device * device, - struct file * filep, - int subdevice, - int time_out, - int *count, int flags); - - int (*me_device_io_stream_read) (struct me_device * device, - struct file * filep, - int subdevice, - int read_mode, - int *values, int *count, int flags); - - int (*me_device_io_stream_start) (struct me_device * device, - struct file * filep, - int subdevice, - int start_mode, - int time_out, int flags); - - int (*me_device_io_stream_status) (struct me_device * device, - struct file * filep, - int subdevice, - int wait, - int *status, int *count, int flags); - - int (*me_device_io_stream_stop) (struct me_device * device, - struct file * filep, - int subdevice, - int stop_mode, int flags); - - int (*me_device_io_stream_write) (struct me_device * device, - struct file * filep, - int subdevice, - int write_mode, - int *values, int *count, int flags); - - int (*me_device_lock_device) (struct me_device * device, - struct file * filep, int lock, int flags); - - int (*me_device_lock_subdevice) (struct me_device * device, - struct file * filep, - int subdevice, int lock, int flags); - - int (*me_device_query_description_device) (struct me_device * device, - char **description); - - int (*me_device_query_info_device) (struct me_device * device, - int *vendor_id, - int *device_id, - int *serial_no, - int *bus_type, - int *bus_no, - int *dev_no, - int *func_no, int *plugged); - - int (*me_device_query_name_device) (struct me_device * device, - char **name); - - int (*me_device_query_name_device_driver) (struct me_device * device, - char **name); - - int (*me_device_query_number_subdevices) (struct me_device * device, - int *number); - - int (*me_device_query_number_channels) (struct me_device * device, - int subdevice, int *number); - - int (*me_device_query_number_ranges) (struct me_device * device, - int subdevice, - int unit, int *count); - - int (*me_device_query_range_by_min_max) (struct me_device * device, - int subdevice, - int unit, - int *min, - int *max, - int *maxdata, int *range); - - int (*me_device_query_range_info) (struct me_device * device, - int subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata); - - int (*me_device_query_subdevice_by_type) (struct me_device * device, - int start_subdevice, - int type, - int subtype, int *subdevice); - - int (*me_device_query_subdevice_type) (struct me_device * device, - int subdevice, - int *type, int *subtype); - - int (*me_device_query_subdevice_caps) (struct me_device * device, - int subdevice, int *caps); - - int (*me_device_query_subdevice_caps_args) (struct me_device * device, - int subdevice, - int cap, - int *args, int count); - - int (*me_device_query_timer) (struct me_device * device, - int subdevice, - int timer, - int *base_frequency, - uint64_t * min_ticks, - uint64_t * max_ticks); - - int (*me_device_query_version_device_driver) (struct me_device * device, - int *version); - - int (*me_device_config_load) (struct me_device * device, - struct file * filep, - me_cfg_device_entry_t * config); - - void (*me_device_destructor) (struct me_device * device); -} me_device_t; - -/** - * @brief Initializes a PCI device base class structure. - * - * @param pci_device The PCI device context as handed over by kernel. - * - * @return 0 on success. - */ -int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device); - -/** - * @brief Initializes a USB device base class structure. - * - * @param usb_interface The USB device interface as handed over by kernel. - * - * @return 0 on success. - */ -//int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface); - -/** - * @brief Deinitializes a device base class structure and frees any previously - * requested resources related with this structure. It also frees any subdevice - * instance hold by the subdevice list. - * - * @param me_device The device class to deinitialize. - */ -void me_device_deinit(me_device_t * me_device); - -#endif -#endif diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c deleted file mode 100644 index b6a4065d2da..00000000000 --- a/drivers/staging/meilhaus/medlist.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file me_dlist.c - * - * @brief Implements the device list class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "meerror.h" -#include "medefines.h" - -#include "medlist.h" -#include "medebug.h" - -int me_dlist_query_number_devices(struct me_dlist *dlist, int *number) -{ - PDEBUG_LOCKS("called.\n"); - *number = dlist->n; - return ME_ERRNO_SUCCESS; -} - -unsigned int me_dlist_get_number_devices(struct me_dlist *dlist) -{ - PDEBUG_LOCKS("called.\n"); - return dlist->n; -} - -me_device_t *me_dlist_get_device(struct me_dlist * dlist, unsigned int index) -{ - - struct list_head *pos; - me_device_t *device = NULL; - unsigned int i = 0; - - PDEBUG_LOCKS("called.\n"); - - if (index >= dlist->n) { - PERROR("Index out of range.\n"); - return NULL; - } - - list_for_each(pos, &dlist->head) { - if (i == index) { - device = list_entry(pos, me_device_t, list); - break; - } - - ++i; - } - - return device; -} - -void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t *device) -{ - PDEBUG_LOCKS("called.\n"); - - list_add_tail(&device->list, &dlist->head); - ++dlist->n; -} - -me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist) -{ - - struct list_head *last; - me_device_t *device; - - PDEBUG_LOCKS("called.\n"); - - if (list_empty(&dlist->head)) - return NULL; - - last = dlist->head.prev; - - device = list_entry(last, me_device_t, list); - - list_del(last); - - --dlist->n; - - return device; -} - -int me_dlist_init(me_dlist_t *dlist) -{ - PDEBUG_LOCKS("called.\n"); - - INIT_LIST_HEAD(&dlist->head); - dlist->n = 0; - return 0; -} - -void me_dlist_deinit(me_dlist_t *dlist) -{ - - struct list_head *s; - me_device_t *device; - - PDEBUG_LOCKS("called.\n"); - - while (!list_empty(&dlist->head)) { - s = dlist->head.next; - list_del(s); - device = list_entry(s, me_device_t, list); - device->me_device_destructor(device); - } - - dlist->n = 0; -} diff --git a/drivers/staging/meilhaus/medlist.h b/drivers/staging/meilhaus/medlist.h deleted file mode 100644 index 091c11e48ed..00000000000 --- a/drivers/staging/meilhaus/medlist.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file me_dlist.h - * - * @brief Provides the device list class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME_DLIST_H_ -#define _ME_DLIST_H_ - -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The device list container. - */ -typedef struct me_dlist { - struct list_head head; /**< The head of the internal list. */ - unsigned int n; /**< The number of devices in the list. */ -} me_dlist_t; - -/** - * @brief Queries the number of devices currently inside the list. - * - * @param dlist The device list to query. - * @param[out] number The number of devices. - * - * @return ME-iDS error code. - */ -int me_dlist_query_number_devices(struct me_dlist *dlist, int *number); - -/** - * @brief Returns the number of devices currently inside the list. - * - * @param dlist The device list to query. - * - * @return The number of devices in the list. - */ -unsigned int me_dlist_get_number_devices(struct me_dlist *dlist); - -/** - * @brief Get a device by index. - * - * @param dlist The device list to query. - * @param index The index of the device to get in the list. - * - * @return The device at index if available.\n - * NULL if the index is out of range. - */ -me_device_t *me_dlist_get_device(struct me_dlist *dlist, unsigned int index); - -/** - * @brief Adds a device to the tail of the list. - * - * @param dlist The device list to add a device to. - * @param device The device to add to the list. - */ -void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device); - -/** - * @brief Removes a device from the tail of the list. - * - * @param dlist The device list. - * - * @return Pointer to the removed subdeivce.\n - * NULL in cases where the list was empty. - */ -me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist); - -/** - * @brief Initializes a device list structure. - * - * @param lock The device list structure to initialize. - * @return 0 on success. - */ -int me_dlist_init(me_dlist_t * dlist); - -/** - * @brief Deinitializes a device list structure and destructs every device in it. - * - * @param dlist The device list structure to deinitialize. - * @return 0 on success. - */ -void me_dlist_deinit(me_dlist_t * dlist); - -#endif -#endif diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c deleted file mode 100644 index 8ded397214f..00000000000 --- a/drivers/staging/meilhaus/medlock.c +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file medlock.c - * - * @brief Implements the device lock class. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include "medefines.h" -#include "meerror.h" - -#include "medebug.h" -#include "meslist.h" -#include "mesubdevice.h" -#include "medlock.h" - -int me_dlock_enter(struct me_dlock *dlock, struct file *filep) -{ - PDEBUG_LOCKS("executed.\n"); - - spin_lock(&dlock->spin_lock); - - if ((dlock->filep) != NULL && (dlock->filep != filep)) { - PERROR("Device is locked by another process.\n"); - spin_unlock(&dlock->spin_lock); - return ME_ERRNO_LOCKED; - } - - dlock->count++; - - spin_unlock(&dlock->spin_lock); - - return ME_ERRNO_SUCCESS; -} - -int me_dlock_exit(struct me_dlock *dlock, struct file *filep) -{ - PDEBUG_LOCKS("executed.\n"); - - spin_lock(&dlock->spin_lock); - dlock->count--; - spin_unlock(&dlock->spin_lock); - - return ME_ERRNO_SUCCESS; -} - -int me_dlock_lock(struct me_dlock *dlock, - struct file *filep, int lock, int flags, me_slist_t *slist) -{ - int err = ME_ERRNO_SUCCESS; - int i; - me_subdevice_t *subdevice; - - PDEBUG_LOCKS("executed.\n"); - - spin_lock(&dlock->spin_lock); - - switch (lock) { - - case ME_LOCK_RELEASE: - if ((dlock->filep == filep) || (dlock->filep == NULL)) { - dlock->filep = NULL; - - /* Unlock all possibly locked subdevices. */ - - for (i = 0; i < me_slist_get_number_subdevices(slist); - i++) { - subdevice = me_slist_get_subdevice(slist, i); - - if (subdevice) - err = - subdevice-> - me_subdevice_lock_subdevice - (subdevice, filep, ME_LOCK_RELEASE, - flags); - else - err = ME_ERRNO_INTERNAL; - } - } - - break; - - case ME_LOCK_SET: - if (dlock->count) { - PERROR("Device is used by another process.\n"); - err = ME_ERRNO_USED; - } else if ((dlock->filep != NULL) && (dlock->filep != filep)) { - PERROR("Device is locked by another process.\n"); - err = ME_ERRNO_LOCKED; - } else if (dlock->filep == NULL) { - /* Check any subdevice is locked by another process. */ - - for (i = 0; i < me_slist_get_number_subdevices(slist); - i++) { - subdevice = me_slist_get_subdevice(slist, i); - - if (subdevice) { - if ((err = - subdevice-> - me_subdevice_lock_subdevice - (subdevice, filep, ME_LOCK_CHECK, - flags))) { - PERROR - ("A subdevice is locked by another process.\n"); - break; - } - } else { - err = ME_ERRNO_INTERNAL; - } - } - - /* If no subdevices are locked by other processes, - we can take ownership of the device. Otherwise we jump ahead. */ - if (!err) - dlock->filep = filep; - } - - break; - - case ME_LOCK_CHECK: - if (dlock->count) { - err = ME_ERRNO_USED; - } else if ((dlock->filep != NULL) && (dlock->filep != filep)) { - err = ME_ERRNO_LOCKED; - } else if (dlock->filep == NULL) { - for (i = 0; i < me_slist_get_number_subdevices(slist); - i++) { - subdevice = me_slist_get_subdevice(slist, i); - - if (subdevice) { - if ((err = - subdevice-> - me_subdevice_lock_subdevice - (subdevice, filep, ME_LOCK_CHECK, - flags))) { - PERROR - ("A subdevice is locked by another process.\n"); - break; - } - } else { - err = ME_ERRNO_INTERNAL; - } - } - } - - break; - - default: - PERROR("Invalid lock.\n"); - - err = ME_ERRNO_INVALID_LOCK; - - break; - } - - spin_unlock(&dlock->spin_lock); - - return err; -} - -void me_dlock_deinit(struct me_dlock *dlock) -{ - PDEBUG_LOCKS("executed.\n"); -} - -int me_dlock_init(me_dlock_t *dlock) -{ - PDEBUG_LOCKS("executed.\n"); - - dlock->filep = NULL; - dlock->count = 0; - spin_lock_init(&dlock->spin_lock); - - return 0; -} diff --git a/drivers/staging/meilhaus/medlock.h b/drivers/staging/meilhaus/medlock.h deleted file mode 100644 index 4d6ddc8e58a..00000000000 --- a/drivers/staging/meilhaus/medlock.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file medlock.h - * - * @brief Provides the device lock class. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _MEDLOCK_H_ -#define _MEDLOCK_H_ - -#include - -#ifdef __KERNEL__ - -/** - * @brief The device lock class. - */ -typedef struct me_dlock { - struct file *filep; /**< Pointer to file structure holding the device. */ - int count; /**< Number of tasks which are inside the device. */ - spinlock_t spin_lock; /**< Spin lock protecting the attributes from concurrent access. */ -} me_dlock_t; - -/** - * @brief Tries to enter a device. - * - * @param dlock The device lock instance. - * @param filep The file structure identifying the calling process. - * - * @return 0 on success. - */ -int me_dlock_enter(struct me_dlock *dlock, struct file *filep); - -/** - * @brief Exits a device. - * - * @param dlock The device lock instance. - * @param filep The file structure identifying the calling process. - * - * @return 0 on success. - */ -int me_dlock_exit(struct me_dlock *dlock, struct file *filep); - -/** - * @brief Tries to perform a locking action on a device. - * - * @param dlock The device lock instance. - * @param filep The file structure identifying the calling process. - * @param The action to be done. - * @param flags Flags from user space. - * @param slist The subdevice list of the device. - * - * @return 0 on success. - */ -int me_dlock_lock(struct me_dlock *dlock, - struct file *filep, int lock, int flags, me_slist_t * slist); - -/** - * @brief Initializes a lock structure. - * - * @param dlock The lock structure to initialize. - * @return 0 on success. - */ -int me_dlock_init(me_dlock_t * dlock); - -/** - * @brief Deinitializes a lock structure. - * - * @param dlock The lock structure to deinitialize. - * @return 0 on success. - */ -void me_dlock_deinit(me_dlock_t * dlock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/medriver.h b/drivers/staging/meilhaus/medriver.h deleted file mode 100644 index 02e2408ce5f..00000000000 --- a/drivers/staging/meilhaus/medriver.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : medriver.h - * Author : GG (Guenter Gebhardt) - * Author: Krzysztof Gantzke - */ - -#ifndef _MEDRIVER_H_ -#define _MEDRIVER_H_ - -#include "metypes.h" -#include "meerror.h" -#include "medefines.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /*=========================================================================== - Functions to access the driver system - =========================================================================*/ - - int meOpen(int iFlags); - int meClose(int iFlags); - - int meLockDriver(int iLock, int iFlags); - int meLockDevice(int iDevice, int iLock, int iFlags); - int meLockSubdevice(int iDevice, int iSubdevice, int iLock, int iFlags); - - /*=========================================================================== - Error handling functions - =========================================================================*/ - - int meErrorGetLastMessage(char *pcErrorMsg, int iCount); - int meErrorGetMessage(int iErrorCode, char *pcErrorMsg, int iCount); - int meErrorSetDefaultProc(int iSwitch); - int meErrorSetUserProc(meErrorCB_t pErrorProc); - - - /*=========================================================================== - Functions to perform I/O on a device - =========================================================================*/ - - int meIOIrqSetCallback( - int iDevice, - int iSubdevice, - meIOIrqCB_t pCallback, - void *pCallbackContext, - int iFlags); - int meIOIrqStart( - int iDevice, - int iSubdevice, - int iChannel, - int iIrqSource, - int iIrqEdge, - int iIrqArg, - int iFlags); - int meIOIrqStop( - int iDevice, - int iSubdevice, - int iChannel, - int iFlags); - int meIOIrqWait( - int iDevice, - int iSubdevice, - int iChannel, - int *piIrqCount, - int *piValue, - int iTimeOut, - int iFlags); - - int meIOResetDevice(int iDevice, int iFlags); - int meIOResetSubdevice(int iDevice, int iSubdevice, int iFlags); - - int meIOStreamFrequencyToTicks( - int iDevice, - int iSubdevice, - int iTimer, - double *pdFrequency, - int *piTicksLow, - int *piTicksHigh, - int iFlags); - - int meIOSingleConfig( - int iDevice, - int iSubdevice, - int iChannel, - int iSingleConfig, - int iRef, - int iTrigChan, - int iTrigType, - int iTrigEdge, - int iFlags); - int meIOSingle(meIOSingle_t *pSingleList, int iCount, int iFlags); - - int meIOStreamConfig( - int iDevice, - int iSubdevice, - meIOStreamConfig_t *pConfigList, - int iCount, - meIOStreamTrigger_t *pTrigger, - int iFifoIrqThreshold, - int iFlags); - int meIOStreamNewValues( - int iDevice, - int iSubdevice, - int iTimeOut, - int *piCount, - int iFlags); - int meIOStreamRead( - int iDevice, - int iSubdevice, - int iReadMode, - int *piValues, - int *piCount, - int iFlags); - int meIOStreamWrite( - int iDevice, - int iSubdevice, - int iWriteMode, - int *piValues, - int *piCount, - int iFlags); - int meIOStreamStart(meIOStreamStart_t *pStartList, int iCount, int iFlags); - int meIOStreamStop(meIOStreamStop_t *pStopList, int iCount, int iFlags); - int meIOStreamStatus( - int iDevice, - int iSubdevice, - int iWait, - int *piStatus, - int *piCount, - int iFlags); - int meIOStreamSetCallbacks( - int iDevice, - int iSubdevice, - meIOStreamCB_t pStartCB, - void *pStartCBContext, - meIOStreamCB_t pNewValuesCB, - void *pNewValuesCBContext, - meIOStreamCB_t pEndCB, - void *pEndCBContext, - int iFlags); - int meIOStreamTimeToTicks( - int iDevice, - int iSubdevice, - int iTimer, - double *pdTime, - int *piTicksLow, - int *piTicksHigh, - int iFlags); - - - /*=========================================================================== - Functions to query the driver system - =========================================================================*/ - - int meQueryDescriptionDevice(int iDevice, char *pcDescription, int iCount); - - int meQueryInfoDevice( - int iDevice, - int *piVendorId, - int *piDeviceId, - int *piSerialNo, - int *piBusType, - int *piBusNo, - int *piDevNo, - int *piFuncNo, - int *piPlugged); - - int meQueryNameDevice(int iDevice, char *pcName, int iCount); - int meQueryNameDeviceDriver(int iDevice, char *pcName, int iCount); - - int meQueryNumberDevices(int *piNumber); - int meQueryNumberSubdevices(int iDevice, int *piNumber); - int meQueryNumberChannels(int iDevice, int iSubdevice, int *piNumber); - int meQueryNumberRanges( - int iDevice, - int iSubdevice, - int iUnit, - int *piNumber); - - int meQueryRangeByMinMax( - int iDevice, - int iSubdevice, - int iUnit, - double *pdMin, - double *pdMax, - int *piMaxData, - int *piRange); - int meQueryRangeInfo( - int iDevice, - int iSubdevice, - int iRange, - int *piUnit, - double *pdMin, - double *pdMax, - int *piMaxData); - - int meQuerySubdeviceByType( - int iDevice, - int iStartSubdevice, - int iType, - int iSubtype, - int *piSubdevice); - int meQuerySubdeviceType( - int iDevice, - int iSubdevice, - int *piType, - int *piSubtype); - int meQuerySubdeviceCaps( - int iDevice, - int iSubdevice, - int *piCaps); - int meQuerySubdeviceCapsArgs( - int iDevice, - int iSubdevice, - int iCap, - int *piArgs, - int iCount); - - int meQueryVersionLibrary(int *piVersion); - int meQueryVersionMainDriver(int *piVersion); - int meQueryVersionDeviceDriver(int iDevice, int *piVersion); - - - /*=========================================================================== - Common utility functions - =========================================================================*/ - - int meUtilityExtractValues( - int iChannel, - int *piAIBuffer, - int iAIBufferCount, - meIOStreamConfig_t *pConfigList, - int iConfigListCount, - int *piChanBuffer, - int *piChanBufferCount); - int meUtilityDigitalToPhysical( - double dMin, - double dMax, - int iMaxData, - int iData, - int iModuleType, - double dRefValue, - double *pdPhysical); - int meUtilityDigitalToPhysicalV( - double dMin, - double dMax, - int iMaxData, - int *piDataBuffer, - int iCount, - int iModuleType, - double dRefValue, - double *pdPhysicalBuffer); - int meUtilityPhysicalToDigital( - double dMin, - double dMax, - int iMaxData, - double dPhysical, - int *piData); - int meUtilityPWMStart( - int iDevice, - int iSubdevice1, - int iSubdevice2, - int iSubdevice3, - int iRef, - int iPrescaler, - int iDutyCycle, - int iFlag); - int meUtilityPWMStop(int iDevice, - int iSubdevice1); - int meUtilityPWMRestart( - int iDevice, - int iSubdevice1, - int iRef, - int iPrescaler); - - - /*=========================================================================== - Load configuration from file into driver system - =========================================================================*/ - - int meConfigLoad(char *pcConfigFile); - - - /*=========================================================================== - Functions to query a remote driver system - =========================================================================*/ - - int meRQueryDescriptionDevice( - char *location, - int iDevice, - char *pcDescription, - int iCount); - - int meRQueryInfoDevice( - char *location, - int iDevice, - int *piVendorId, - int *piDeviceId, - int *piSerialNo, - int *piBusType, - int *piBusNo, - int *piDevNo, - int *piFuncNo, - int *piPlugged); - - int meRQueryNameDevice( - char *location, - int iDevice, - char *pcName, - int iCount); - - int meRQueryNumberDevices(char *location, int *piNumber); - int meRQueryNumberSubdevices(char *location, int iDevice, int *piNumber); - int meRQueryNumberChannels( - char *location, - int iDevice, - int iSubdevice, - int *piNumber); - int meRQueryNumberRanges( - char *location, - int iDevice, - int iSubdevice, - int iUnit, - int *piNumber); - - int meRQueryRangeInfo( - char *location, - int iDevice, - int iSubdevice, - int iRange, - int *piUnit, - double *pdMin, - double *pdMax, - int *piMaxData); - - int meRQuerySubdeviceType( - char *location, - int iDevice, - int iSubdevice, - int *piType, - int *piSubtype); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c deleted file mode 100644 index 2423745f957..00000000000 --- a/drivers/staging/meilhaus/medummy.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* Device driver for Meilhaus ME-DUMMY devices. - * =========================================== - * - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * User application could also include the kernel header files. But the - * real kernel functions are protected by #ifdef __KERNEL__. - */ -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * This must be defined before module.h is included. Not needed, when - * it is a built in driver. - */ -#ifndef MODULE -# define MODULE -#endif - -#include -#include - -#include "meerror.h" -#include "meinternal.h" - -#include "meids.h" -#include "mecommon.h" -#include "medevice.h" -#include "medebug.h" - -#include "medummy.h" - -static int medummy_io_irq_start(me_device_t *device, - struct file *filep, - int subdevice, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_irq_wait(me_device_t *device, - struct file *filep, - int subdevice, - int channel, - int *irq_count, - int *value, int timeout, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_irq_stop(me_device_t *device, - struct file *filep, - int subdevice, int channel, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_reset_device(me_device_t *device, - struct file *filep, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_reset_subdevice(me_device_t *device, - struct file *filep, - int subdevice, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_single_config(me_device_t *device, - struct file *filep, - int subdevice, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, int trig_edge, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_single_read(me_device_t *device, - struct file *filep, - int subdevice, - int channel, - int *value, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_single_write(me_device_t *device, - struct file *filep, - int subdevice, - int channel, - int value, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_config(me_device_t *device, - struct file *filep, - int subdevice, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_new_values(me_device_t *device, - struct file *filep, - int subdevice, - int timeout, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_read(me_device_t *device, - struct file *filep, - int subdevice, - int read_mode, - int *values, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_start(me_device_t *device, - struct file *filep, - int subdevice, - int start_mode, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_status(me_device_t *device, - struct file *filep, - int subdevice, - int wait, - int *status, int *values, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_stop(me_device_t *device, - struct file *filep, - int subdevice, int stop_mode, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_io_stream_write(me_device_t *device, - struct file *filep, - int subdevice, - int write_mode, - int *values, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_lock_device(me_device_t *device, - struct file *filep, int lock, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_lock_subdevice(me_device_t *device, - struct file *filep, - int subdevice, int lock, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_description_device(me_device_t *device, - char **description) -{ - medummy_device_t *instance = (medummy_device_t *) device; - - PDEBUG("executed.\n"); - -// if (instance->magic != MEDUMMY_MAGIC_NUMBER) -// { -// PERROR("Wrong magic number.\n"); -// return ME_ERRNO_INTERNAL; -// } - - switch (instance->device_id) { - - case PCI_DEVICE_ID_MEILHAUS_ME1000: - - case PCI_DEVICE_ID_MEILHAUS_ME1000_A: - - case PCI_DEVICE_ID_MEILHAUS_ME1000_B: - *description = ME1000_DESCRIPTION_DEVICE_ME1000; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1400: - *description = ME1400_DESCRIPTION_DEVICE_ME1400; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140A: - *description = ME1400_DESCRIPTION_DEVICE_ME1400A; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140B: - *description = ME1400_DESCRIPTION_DEVICE_ME1400B; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - *description = ME1400_DESCRIPTION_DEVICE_ME1400E; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - *description = ME1400_DESCRIPTION_DEVICE_ME1400EA; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - *description = ME1400_DESCRIPTION_DEVICE_ME1400EB; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - *description = ME1400_DESCRIPTION_DEVICE_ME1400C; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140D: - *description = ME1400_DESCRIPTION_DEVICE_ME1400D; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_4U: - *description = ME1600_DESCRIPTION_DEVICE_ME16004U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_8U: - *description = ME1600_DESCRIPTION_DEVICE_ME16008U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_12U: - *description = ME1600_DESCRIPTION_DEVICE_ME160012U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U: - *description = ME1600_DESCRIPTION_DEVICE_ME160016U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I: - *description = ME1600_DESCRIPTION_DEVICE_ME160016U8I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - *description = ME4600_DESCRIPTION_DEVICE_ME4610; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4650: - *description = ME4600_DESCRIPTION_DEVICE_ME4650; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660: - *description = ME4600_DESCRIPTION_DEVICE_ME4660; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - *description = ME4600_DESCRIPTION_DEVICE_ME4660I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660S: - *description = ME4600_DESCRIPTION_DEVICE_ME4660S; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660IS: - *description = ME4600_DESCRIPTION_DEVICE_ME4660IS; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670: - *description = ME4600_DESCRIPTION_DEVICE_ME4670; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - *description = ME4600_DESCRIPTION_DEVICE_ME4670I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - *description = ME4600_DESCRIPTION_DEVICE_ME4670S; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - *description = ME4600_DESCRIPTION_DEVICE_ME4670IS; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680: - *description = ME4600_DESCRIPTION_DEVICE_ME4680; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - *description = ME4600_DESCRIPTION_DEVICE_ME4680I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - *description = ME4600_DESCRIPTION_DEVICE_ME4680S; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - *description = ME4600_DESCRIPTION_DEVICE_ME4680IS; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6004: - *description = ME6000_DESCRIPTION_DEVICE_ME60004; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6008: - *description = ME6000_DESCRIPTION_DEVICE_ME60008; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME600F: - *description = ME6000_DESCRIPTION_DEVICE_ME600016; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6014: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6018: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME601F: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6034: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6038: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME603F: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6104: - *description = ME6000_DESCRIPTION_DEVICE_ME61004; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6108: - *description = ME6000_DESCRIPTION_DEVICE_ME61008; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME610F: - *description = ME6000_DESCRIPTION_DEVICE_ME610016; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6114: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6118: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME611F: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6134: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6138: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME613F: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6044: - *description = ME6000_DESCRIPTION_DEVICE_ME60004DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6048: - *description = ME6000_DESCRIPTION_DEVICE_ME60008DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME604F: - *description = ME6000_DESCRIPTION_DEVICE_ME600016DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6054: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6058: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME605F: - *description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6074: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6078: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME607F: - *description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6144: - *description = ME6000_DESCRIPTION_DEVICE_ME61004DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6148: - *description = ME6000_DESCRIPTION_DEVICE_ME61008DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME614F: - *description = ME6000_DESCRIPTION_DEVICE_ME610016DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6154: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6158: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME615F: - *description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6174: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6178: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME617F: - *description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6259: - *description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6359: - *description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0630: - *description = ME0600_DESCRIPTION_DEVICE_ME0630; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - *description = ME8100_DESCRIPTION_DEVICE_ME8100A; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - *description = ME8100_DESCRIPTION_DEVICE_ME8100B; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0940: - *description = ME0900_DESCRIPTION_DEVICE_ME0940; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0950: - *description = ME0900_DESCRIPTION_DEVICE_ME0950; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0960: - *description = ME0900_DESCRIPTION_DEVICE_ME0960; - - break; -/* - case USB_DEVICE_ID_MEPHISTO_S1: - *description = MEPHISTO_S1_DESCRIPTION_DEVICE; - - break; -*/ - default: - *description = EMPTY_DESCRIPTION_DEVICE; - PERROR("Invalid device id in device info.\n"); - - return ME_ERRNO_INTERNAL; - } - - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_info_device(me_device_t *device, - int *vendor_id, - int *device_id, - int *serial_no, - int *bus_type, - int *bus_no, - int *dev_no, int *func_no, int *plugged) -{ - medummy_device_t *instance = (medummy_device_t *) device; - - PDEBUG("executed.\n"); - -// if (instance->magic != MEDUMMY_MAGIC_NUMBER) -// { -// PERROR("Wrong magic number.\n"); -// return ME_ERRNO_INTERNAL; -// } - - *vendor_id = instance->vendor_id; - *device_id = instance->device_id; - *serial_no = instance->serial_no; - *bus_type = instance->bus_type; - *bus_no = instance->bus_no; - *dev_no = instance->dev_no; - *func_no = instance->func_no; - *plugged = ME_PLUGGED_OUT; - - return ME_ERRNO_SUCCESS; -} - -static int medummy_query_name_device_driver(me_device_t *device, char **name) -{ - PDEBUG("executed.\n"); - *name = MEDUMMY_NAME_DRIVER; - return ME_ERRNO_SUCCESS; -} - -static int medummy_query_name_device(me_device_t *device, char **name) -{ - medummy_device_t *instance = (medummy_device_t *) device; - - PDEBUG("executed.\n"); - -// // // if (instance->magic != MEDUMMY_MAGIC_NUMBER) -// // // { -// // // PERROR("Wrong magic number.\n"); -// // // return ME_ERRNO_INTERNAL; -// // // } - - switch (instance->device_id) { - - case PCI_DEVICE_ID_MEILHAUS_ME1000: - - case PCI_DEVICE_ID_MEILHAUS_ME1000_A: - - case PCI_DEVICE_ID_MEILHAUS_ME1000_B: - *name = ME1000_NAME_DEVICE_ME1000; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1400: - *name = ME1400_NAME_DEVICE_ME1400; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140A: - *name = ME1400_NAME_DEVICE_ME1400A; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140B: - *name = ME1400_NAME_DEVICE_ME1400B; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14E0: - *name = ME1400_NAME_DEVICE_ME1400E; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EA: - *name = ME1400_NAME_DEVICE_ME1400EA; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME14EB: - *name = ME1400_NAME_DEVICE_ME1400EB; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140C: - *name = ME1400_NAME_DEVICE_ME1400C; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME140D: - *name = ME1400_NAME_DEVICE_ME1400D; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_4U: - *name = ME1600_NAME_DEVICE_ME16004U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_8U: - *name = ME1600_NAME_DEVICE_ME16008U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_12U: - *name = ME1600_NAME_DEVICE_ME160012U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U: - *name = ME1600_NAME_DEVICE_ME160016U; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I: - *name = ME1600_NAME_DEVICE_ME160016U8I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4610: - *name = ME4600_NAME_DEVICE_ME4610; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4650: - *name = ME4600_NAME_DEVICE_ME4650; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660: - *name = ME4600_NAME_DEVICE_ME4660; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4660I: - *name = ME4600_NAME_DEVICE_ME4660I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670: - *name = ME4600_NAME_DEVICE_ME4670; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670I: - *name = ME4600_NAME_DEVICE_ME4670I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670S: - *name = ME4600_NAME_DEVICE_ME4670S; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4670IS: - *name = ME4600_NAME_DEVICE_ME4670IS; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680: - *name = ME4600_NAME_DEVICE_ME4680; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680I: - *name = ME4600_NAME_DEVICE_ME4680I; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680S: - *name = ME4600_NAME_DEVICE_ME4680S; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME4680IS: - *name = ME4600_NAME_DEVICE_ME4680IS; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6004: - *name = ME6000_NAME_DEVICE_ME60004; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6008: - *name = ME6000_NAME_DEVICE_ME60008; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME600F: - *name = ME6000_NAME_DEVICE_ME600016; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6014: - *name = ME6000_NAME_DEVICE_ME6000I4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6018: - *name = ME6000_NAME_DEVICE_ME6000I8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME601F: - *name = ME6000_NAME_DEVICE_ME6000I16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6034: - *name = ME6000_NAME_DEVICE_ME6000ISLE4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6038: - *name = ME6000_NAME_DEVICE_ME6000ISLE8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME603F: - *name = ME6000_NAME_DEVICE_ME6000ISLE16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6104: - *name = ME6000_NAME_DEVICE_ME61004; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6108: - *name = ME6000_NAME_DEVICE_ME61008; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME610F: - *name = ME6000_NAME_DEVICE_ME610016; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6114: - *name = ME6000_NAME_DEVICE_ME6100I4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6118: - *name = ME6000_NAME_DEVICE_ME6100I8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME611F: - *name = ME6000_NAME_DEVICE_ME6100I16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6134: - *name = ME6000_NAME_DEVICE_ME6100ISLE4; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6138: - *name = ME6000_NAME_DEVICE_ME6100ISLE8; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME613F: - *name = ME6000_NAME_DEVICE_ME6100ISLE16; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6044: - *name = ME6000_NAME_DEVICE_ME60004DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6048: - *name = ME6000_NAME_DEVICE_ME60008DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME604F: - *name = ME6000_NAME_DEVICE_ME600016DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6054: - *name = ME6000_NAME_DEVICE_ME6000I4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6058: - *name = ME6000_NAME_DEVICE_ME6000I8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME605F: - *name = ME6000_NAME_DEVICE_ME6000I16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6074: - *name = ME6000_NAME_DEVICE_ME6000ISLE4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6078: - *name = ME6000_NAME_DEVICE_ME6000ISLE8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME607F: - *name = ME6000_NAME_DEVICE_ME6000ISLE16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6144: - *name = ME6000_NAME_DEVICE_ME61004DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6148: - *name = ME6000_NAME_DEVICE_ME61008DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME614F: - *name = ME6000_NAME_DEVICE_ME610016DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6154: - *name = ME6000_NAME_DEVICE_ME6100I4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6158: - *name = ME6000_NAME_DEVICE_ME6100I8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME615F: - *name = ME6000_NAME_DEVICE_ME6100I16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6174: - *name = ME6000_NAME_DEVICE_ME6100ISLE4DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME6178: - *name = ME6000_NAME_DEVICE_ME6100ISLE8DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME617F: - *name = ME6000_NAME_DEVICE_ME6100ISLE16DIO; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0630: - *name = ME0600_NAME_DEVICE_ME0630; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_A: - *name = ME8100_NAME_DEVICE_ME8100A; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME8100_B: - *name = ME8100_NAME_DEVICE_ME8100B; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0940: - *name = ME0900_NAME_DEVICE_ME0940; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0950: - *name = ME0900_NAME_DEVICE_ME0950; - - break; - - case PCI_DEVICE_ID_MEILHAUS_ME0960: - *name = ME0900_NAME_DEVICE_ME0960; - - break; -/* - case USB_DEVICE_ID_MEPHISTO_S1: - *name = MEPHISTO_S1_NAME_DEVICE; - - break; -*/ - default: - *name = EMPTY_NAME_DEVICE; - PERROR("Invalid PCI device id.\n"); - - return ME_ERRNO_INTERNAL; - } - - return ME_ERRNO_SUCCESS; -} - -static int medummy_query_number_subdevices(me_device_t *device, int *number) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_number_channels(me_device_t *device, - int subdevice, int *number) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_number_ranges(me_device_t *device, - int subdevice, int unit, int *count) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_subdevice_type(me_device_t *device, - int subdevice, int *type, int *subtype) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_subdevice_caps(me_device_t *device, - int subdevice, int *caps) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_subdevice_caps_args(me_device_t *device, - int subdevice, - int cap, int *args, int count) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int medummy_query_subdevice_by_type(me_device_t *device, - int start_subdevice, - int type, - int subtype, int *subdevice) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_range_by_min_max(me_device_t *device, - int subdevice, - int unit, - int *min, - int *max, int *maxdata, int *range) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_range_info(me_device_t *device, - int subdevice, - int range, - int *unit, int *min, int *max, int *maxdata) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -int medummy_query_timer(me_device_t *device, - int subdevice, - int timer, - int *base_frequency, - uint64_t *min_ticks, uint64_t *max_ticks) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_DEVICE_UNPLUGGED; -} - -static int medummy_query_version_device_driver(me_device_t *device, - int *version) -{ - PDEBUG("executed.\n"); - - *version = ME_VERSION_DRIVER; - return ME_ERRNO_SUCCESS; -} - -static void medummy_destructor(me_device_t *device) -{ - PDEBUG("executed.\n"); - kfree(device); -} - -static int init_device_info(unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, - int dev_no, - int func_no, medummy_device_t *instance) -{ - PDEBUG("executed.\n"); - -// instance->magic = MEDUMMY_MAGIC_NUMBER; - instance->vendor_id = vendor_id; - instance->device_id = device_id; - instance->serial_no = serial_no; - instance->bus_type = bus_type; - instance->bus_no = bus_no; - instance->dev_no = dev_no; - instance->func_no = func_no; - - return 0; -} - -static int medummy_config_load(me_device_t *device, struct file *filep, - me_cfg_device_entry_t *config) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_SUCCESS; -} - -static int init_device_instance(me_device_t *device) -{ - PDEBUG("executed.\n"); - - INIT_LIST_HEAD(&device->list); - - device->me_device_io_irq_start = medummy_io_irq_start; - device->me_device_io_irq_wait = medummy_io_irq_wait; - device->me_device_io_irq_stop = medummy_io_irq_stop; - device->me_device_io_reset_device = medummy_io_reset_device; - device->me_device_io_reset_subdevice = medummy_io_reset_subdevice; - device->me_device_io_single_config = medummy_io_single_config; - device->me_device_io_single_read = medummy_io_single_read; - device->me_device_io_single_write = medummy_io_single_write; - device->me_device_io_stream_config = medummy_io_stream_config; - device->me_device_io_stream_new_values = medummy_io_stream_new_values; - device->me_device_io_stream_read = medummy_io_stream_read; - device->me_device_io_stream_start = medummy_io_stream_start; - device->me_device_io_stream_status = medummy_io_stream_status; - device->me_device_io_stream_stop = medummy_io_stream_stop; - device->me_device_io_stream_write = medummy_io_stream_write; - - device->me_device_lock_device = medummy_lock_device; - device->me_device_lock_subdevice = medummy_lock_subdevice; - - device->me_device_query_description_device = - medummy_query_description_device; - device->me_device_query_info_device = medummy_query_info_device; - device->me_device_query_name_device_driver = - medummy_query_name_device_driver; - device->me_device_query_name_device = medummy_query_name_device; - - device->me_device_query_number_subdevices = - medummy_query_number_subdevices; - device->me_device_query_number_channels = medummy_query_number_channels; - device->me_device_query_number_ranges = medummy_query_number_ranges; - - device->me_device_query_range_by_min_max = - medummy_query_range_by_min_max; - device->me_device_query_range_info = medummy_query_range_info; - - device->me_device_query_subdevice_type = medummy_query_subdevice_type; - device->me_device_query_subdevice_by_type = - medummy_query_subdevice_by_type; - device->me_device_query_subdevice_caps = medummy_query_subdevice_caps; - device->me_device_query_subdevice_caps_args = - medummy_query_subdevice_caps_args; - - device->me_device_query_timer = medummy_query_timer; - - device->me_device_query_version_device_driver = - medummy_query_version_device_driver; - - device->me_device_destructor = medummy_destructor; - device->me_device_config_load = medummy_config_load; - return 0; -} - -me_device_t *medummy_constructor(unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, int dev_no, int func_no) -{ - int result = 0; - medummy_device_t *instance; - - PDEBUG("executed.\n"); - - /* Allocate structure for device attributes */ - instance = kmalloc(sizeof(medummy_device_t), GFP_KERNEL); - - if (!instance) { - PERROR("Can't get memory for device instance.\n"); - return NULL; - } - - memset(instance, 0, sizeof(medummy_device_t)); - - /* Initialize device info */ - result = init_device_info(vendor_id, - device_id, - serial_no, - bus_type, bus_no, dev_no, func_no, instance); - - if (result) { - PERROR("Cannot init baord info.\n"); - kfree(instance); - return NULL; - } - - /* Initialize device instance */ - result = init_device_instance((me_device_t *) instance); - - if (result) { - PERROR("Cannot init baord info.\n"); - kfree(instance); - return NULL; - } - - return (me_device_t *) instance; -} -EXPORT_SYMBOL(medummy_constructor); - -// Init and exit of module. - -static int __init dummy_init(void) -{ - PDEBUG("executed.\n"); - return 0; -} - -static void __exit dummy_exit(void) -{ - PDEBUG("executed.\n"); -} - -module_init(dummy_init); - -module_exit(dummy_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR("Guenter Gebhardt "); -MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices"); -MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/medummy.h b/drivers/staging/meilhaus/medummy.h deleted file mode 100644 index 717000ff6c1..00000000000 --- a/drivers/staging/meilhaus/medummy.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : medummy.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEDUMMY_H_ -#define _MEDUMMY_H_ - -#include "metypes.h" -#include "medefines.h" -#include "medevice.h" - -#ifdef __KERNEL__ - -#define MEDUMMY_MAGIC_NUMBER 0xDDDD - -typedef struct medummy_device { - me_device_t base; /**< The Meilhaus device base class. */ -// int magic; /**< The magic number of the structure */ - unsigned short vendor_id; /**< Vendor ID */ - unsigned short device_id; /**< Device ID */ - unsigned int serial_no; /**< Serial number of the device */ - int bus_type; /**< Bus type */ - int bus_no; /**< Bus number */ - int dev_no; /**< Device number */ - int func_no; /**< Function number */ -} medummy_device_t; - -me_device_t *medummy_constructor(unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, - int dev_no, - int func_no) __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/meerror.h b/drivers/staging/meilhaus/meerror.h deleted file mode 100644 index 9eda4bf907b..00000000000 --- a/drivers/staging/meilhaus/meerror.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : meerror.h - * Author : GG (Guenter Gebhardt) - * Author : KG (Krzysztof Gantzke) - */ - -#ifndef _MEERROR_H_ -#define _MEERROR_H_ - -extern char *meErrorMsgTable[]; - -#define ME_ERRNO_SUCCESS 0 -#define ME_ERRNO_INVALID_DEVICE 1 -#define ME_ERRNO_INVALID_SUBDEVICE 2 -#define ME_ERRNO_INVALID_CHANNEL 3 -#define ME_ERRNO_INVALID_SINGLE_CONFIG 4 -#define ME_ERRNO_INVALID_REF 5 -#define ME_ERRNO_INVALID_TRIG_CHAN 6 -#define ME_ERRNO_INVALID_TRIG_TYPE 7 -#define ME_ERRNO_INVALID_TRIG_EDGE 8 -#define ME_ERRNO_INVALID_TIMEOUT 9 -#define ME_ERRNO_INVALID_FLAGS 10 -#define ME_ERRNO_OPEN 11 -#define ME_ERRNO_CLOSE 12 -#define ME_ERRNO_NOT_OPEN 13 -#define ME_ERRNO_INVALID_DIR 14 -#define ME_ERRNO_PREVIOUS_CONFIG 15 -#define ME_ERRNO_NOT_SUPPORTED 16 -#define ME_ERRNO_SUBDEVICE_TYPE 17 -#define ME_ERRNO_USER_BUFFER_SIZE 18 -#define ME_ERRNO_LOCKED 19 -#define ME_ERRNO_NOMORE_SUBDEVICE_TYPE 20 -#define ME_ERRNO_TIMEOUT 21 -#define ME_ERRNO_SIGNAL 22 -#define ME_ERRNO_INVALID_IRQ_SOURCE 23 -#define ME_ERRNO_THREAD_RUNNING 24 -#define ME_ERRNO_START_THREAD 25 -#define ME_ERRNO_CANCEL_THREAD 26 -#define ME_ERRNO_NO_CALLBACK 27 -#define ME_ERRNO_USED 28 -#define ME_ERRNO_INVALID_UNIT 29 -#define ME_ERRNO_INVALID_MIN_MAX 30 -#define ME_ERRNO_NO_RANGE 31 -#define ME_ERRNO_INVALID_RANGE 32 -#define ME_ERRNO_SUBDEVICE_BUSY 33 -#define ME_ERRNO_INVALID_LOCK 34 -#define ME_ERRNO_INVALID_SWITCH 35 -#define ME_ERRNO_INVALID_ERROR_MSG_COUNT 36 -#define ME_ERRNO_INVALID_STREAM_CONFIG 37 -#define ME_ERRNO_INVALID_CONFIG_LIST_COUNT 38 -#define ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE 39 -#define ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE 40 -#define ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN 41 -#define ME_ERRNO_INVALID_ACQ_START_TIMEOUT 42 -#define ME_ERRNO_INVALID_ACQ_START_ARG 43 -#define ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE 44 -#define ME_ERRNO_INVALID_SCAN_START_ARG 45 -#define ME_ERRNO_INVALID_CONV_START_TRIG_TYPE 46 -#define ME_ERRNO_INVALID_CONV_START_ARG 47 -#define ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE 48 -#define ME_ERRNO_INVALID_SCAN_STOP_ARG 49 -#define ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE 50 -#define ME_ERRNO_INVALID_ACQ_STOP_ARG 51 -#define ME_ERRNO_SUBDEVICE_NOT_RUNNING 52 -#define ME_ERRNO_INVALID_READ_MODE 53 -#define ME_ERRNO_INVALID_VALUE_COUNT 54 -#define ME_ERRNO_INVALID_WRITE_MODE 55 -#define ME_ERRNO_INVALID_TIMER 56 -#define ME_ERRNO_DEVICE_UNPLUGGED 57 -#define ME_ERRNO_USED_INTERNAL 58 -#define ME_ERRNO_INVALID_DUTY_CYCLE 59 -#define ME_ERRNO_INVALID_WAIT 60 -#define ME_ERRNO_CONNECT_REMOTE 61 -#define ME_ERRNO_COMMUNICATION 62 -#define ME_ERRNO_INVALID_SINGLE_LIST 63 -#define ME_ERRNO_INVALID_MODULE_TYPE 64 -#define ME_ERRNO_INVALID_START_MODE 65 -#define ME_ERRNO_INVALID_STOP_MODE 66 -#define ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD 67 -#define ME_ERRNO_INVALID_POINTER 68 -#define ME_ERRNO_CREATE_EVENT 69 -#define ME_ERRNO_LACK_OF_RESOURCES 70 -#define ME_ERRNO_CANCELLED 71 -#define ME_ERRNO_RING_BUFFER_OVERFLOW 72 -#define ME_ERRNO_RING_BUFFER_UNDEFFLOW 73 -#define ME_ERRNO_INVALID_IRQ_EDGE 74 -#define ME_ERRNO_INVALID_IRQ_ARG 75 -#define ME_ERRNO_INVALID_CAP 76 -#define ME_ERRNO_INVALID_CAP_ARG_COUNT 77 -#define ME_ERRNO_INTERNAL 78 - -/** New error for range check */ -#define ME_ERRNO_VALUE_OUT_OF_RANGE 79 -#define ME_ERRNO_FIFO_BUFFER_OVERFLOW 80 -#define ME_ERRNO_FIFO_BUFFER_UNDEFFLOW 81 - -#define ME_ERRNO_INVALID_ERROR_NUMBER 82 -#endif diff --git a/drivers/staging/meilhaus/mefirmware.c b/drivers/staging/meilhaus/mefirmware.c deleted file mode 100644 index c07d202e8cb..00000000000 --- a/drivers/staging/meilhaus/mefirmware.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file mefirmware.c - * - * @brief Implements the firmware handling. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/*************************************************************************** - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) * - * Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de * - * * - * 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, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef KBUILD_MODNAME -# define KBUILD_MODNAME KBUILD_STR(mefirmware) -#endif - -#include -#include - -#include - -#include "meplx_reg.h" -#include "medebug.h" - -#include "mefirmware.h" - -int me_xilinx_download(unsigned long register_base_control, - unsigned long register_base_data, - struct device *dev, const char *firmware_name) -{ - int err = ME_ERRNO_FIRMWARE; - uint32_t value = 0; - int idx = 0; - - const struct firmware *fw; - - PDEBUG("executed.\n"); - - if (!firmware_name) { - PERROR("Request for firmware failed. No name provided. \n"); - return err; - } - - PINFO("Request '%s' firmware.\n", firmware_name); - err = request_firmware(&fw, firmware_name, dev); - - if (err) { - PERROR("Request for firmware failed.\n"); - return err; - } - // Set PLX local interrupt 2 polarity to high. - // Interrupt is thrown by init pin of xilinx. - outl(PLX_INTCSR_LOCAL_INT2_POL, register_base_control + PLX_INTCSR); - - // Set /CS and /WRITE of the Xilinx - value = inl(register_base_control + PLX_ICR); - value |= ME_FIRMWARE_CS_WRITE; - outl(value, register_base_control + PLX_ICR); - - // Init Xilinx with CS1 - inl(register_base_data + ME_XILINX_CS1_REG); - - // Wait for init to complete - udelay(20); - - // Checkl /INIT pin - if (! - (inl(register_base_control + PLX_INTCSR) & - PLX_INTCSR_LOCAL_INT2_STATE)) { - PERROR("Can't init Xilinx.\n"); - release_firmware(fw); - return -EIO; - } - // Reset /CS and /WRITE of the Xilinx - value = inl(register_base_control + PLX_ICR); - value &= ~ME_FIRMWARE_CS_WRITE; - outl(value, register_base_control + PLX_ICR); - - // Download Xilinx firmware - udelay(10); - - for (idx = 0; idx < fw->size; idx++) { - outl(fw->data[idx], register_base_data); -#ifdef ME6000_v2_4 -/// This checking only for board's version 2.4 - // Check if BUSY flag is set (low = ready, high = busy) - if (inl(register_base_control + PLX_ICR) & - ME_FIRMWARE_BUSY_FLAG) { - PERROR("Xilinx is still busy (idx = %d)\n", idx); - release_firmware(fw); - return -EIO; - } -#endif //ME6000_v2_4 - } - PDEBUG("Download finished. %d bytes written to PLX.\n", idx); - - // If done flag is high download was successful - if (inl(register_base_control + PLX_ICR) & ME_FIRMWARE_DONE_FLAG) { - PDEBUG("SUCCESS. Done flag is set.\n"); - } else { - PERROR("FAILURE. DONE flag is not set.\n"); - release_firmware(fw); - return -EIO; - } - - // Set /CS and /WRITE - value = inl(register_base_control + PLX_ICR); - value |= ME_FIRMWARE_CS_WRITE; - outl(value, register_base_control + PLX_ICR); - - PDEBUG("Enable interrupts on the PCI interface.\n"); - outl(ME_PLX_PCI_ACTIVATE, register_base_control + PLX_INTCSR); - release_firmware(fw); - - return 0; -} diff --git a/drivers/staging/meilhaus/mefirmware.h b/drivers/staging/meilhaus/mefirmware.h deleted file mode 100644 index a2685080c97..00000000000 --- a/drivers/staging/meilhaus/mefirmware.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file mefirmware.h - * - * @brief Definitions of the firmware handling functions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/*************************************************************************** - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) * - * Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de * - * * - * 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, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef _MEFIRMWARE_H -# define _MEFIRMWARE_H - -# ifdef __KERNEL__ - -#define ME_ERRNO_FIRMWARE -1 - -/** -* Registry -*/ -#define ME_XILINX_CS1_REG 0x00C8 - -/** -* Flags (bits) -*/ - -#define ME_FIRMWARE_BUSY_FLAG 0x00000020 -#define ME_FIRMWARE_DONE_FLAG 0x00000004 -#define ME_FIRMWARE_CS_WRITE 0x00000100 - -#define ME_PLX_PCI_ACTIVATE 0x43 - -int me_xilinx_download(unsigned long register_base_control, - unsigned long register_base_data, - struct device *dev, const char *firmware_name); - -# endif //__KERNEL__ - -#endif //_MEFIRMWARE_H diff --git a/drivers/staging/meilhaus/meids.h b/drivers/staging/meilhaus/meids.h deleted file mode 100644 index b3e757cbdda..00000000000 --- a/drivers/staging/meilhaus/meids.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : meids.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEIDS_H_ -#define _MEIDS_H_ - -#ifdef __KERNEL__ - -/*============================================================================= - Driver names - ===========================================================================*/ - -#define MEMAIN_NAME "memain" -#define ME1000_NAME "me1000" -#define ME1400_NAME "me1400" -#define ME1600_NAME "me1600" -#define ME4600_NAME "me4600" -#define ME6000_NAME "me6000" -#define ME0600_NAME "me0600" //"me630" -#define ME8100_NAME "me8100" -#define ME8200_NAME "me8200" -#define ME0900_NAME "me0900" //"me9x" -//#define MEPHISTO_S1_NAME "mephisto_s1" -#define MEDUMMY_NAME "medummy" - -#endif -#endif diff --git a/drivers/staging/meilhaus/meinternal.h b/drivers/staging/meilhaus/meinternal.h deleted file mode 100644 index 8d126b4905a..00000000000 --- a/drivers/staging/meilhaus/meinternal.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : meinternal.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEINTERNAL_H_ -#define _MEINTERNAL_H_ - -/*============================================================================= - PCI Vendor IDs - ===========================================================================*/ - -#define PCI_VENDOR_ID_MEILHAUS 0x1402 - -/*============================================================================= - PCI Device IDs - ===========================================================================*/ - -#define PCI_DEVICE_ID_MEILHAUS_ME1000 0x1000 -#define PCI_DEVICE_ID_MEILHAUS_ME1000_A 0x100A -#define PCI_DEVICE_ID_MEILHAUS_ME1000_B 0x100B - -#define PCI_DEVICE_ID_MEILHAUS_ME1400 0x1400 -#define PCI_DEVICE_ID_MEILHAUS_ME140A 0x140A -#define PCI_DEVICE_ID_MEILHAUS_ME140B 0x140B -#define PCI_DEVICE_ID_MEILHAUS_ME14E0 0x14E0 -#define PCI_DEVICE_ID_MEILHAUS_ME14EA 0x14EA -#define PCI_DEVICE_ID_MEILHAUS_ME14EB 0x14EB -#define PCI_DEVICE_ID_MEILHAUS_ME140C 0X140C -#define PCI_DEVICE_ID_MEILHAUS_ME140D 0X140D - -#define PCI_DEVICE_ID_MEILHAUS_ME1600_4U 0x1604 // 4 voltage outputs -#define PCI_DEVICE_ID_MEILHAUS_ME1600_8U 0x1608 // 8 voltage outputs -#define PCI_DEVICE_ID_MEILHAUS_ME1600_12U 0x160C // 12 voltage outputs -#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U 0x160F // 16 voltage outputs -#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I 0x168F // 16 voltage/8 current o. - -#define PCI_DEVICE_ID_MEILHAUS_ME4610 0x4610 // Jekyll - -#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version - -#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 // Isolated version with Sample and Hold - -#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 // Isolated version with Sample and Hold - -#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 // Standard version -#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 // Isolated version -#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 // Standard version with Sample and Hold -#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 // Isolated version with Sample and Hold - -/* ME6000 standard version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6004 0x6004 -#define PCI_DEVICE_ID_MEILHAUS_ME6008 0x6008 -#define PCI_DEVICE_ID_MEILHAUS_ME600F 0x600F - -/* ME6000 isolated version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6014 0x6014 -#define PCI_DEVICE_ID_MEILHAUS_ME6018 0x6018 -#define PCI_DEVICE_ID_MEILHAUS_ME601F 0x601F - -/* ME6000 isle version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6034 0x6034 -#define PCI_DEVICE_ID_MEILHAUS_ME6038 0x6038 -#define PCI_DEVICE_ID_MEILHAUS_ME603F 0x603F - -/* ME6000 standard version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6044 0x6044 -#define PCI_DEVICE_ID_MEILHAUS_ME6048 0x6048 -#define PCI_DEVICE_ID_MEILHAUS_ME604F 0x604F - -/* ME6000 isolated version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6054 0x6054 -#define PCI_DEVICE_ID_MEILHAUS_ME6058 0x6058 -#define PCI_DEVICE_ID_MEILHAUS_ME605F 0x605F - -/* ME6000 isle version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6074 0x6074 -#define PCI_DEVICE_ID_MEILHAUS_ME6078 0x6078 -#define PCI_DEVICE_ID_MEILHAUS_ME607F 0x607F - -/* ME6100 standard version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6104 0x6104 -#define PCI_DEVICE_ID_MEILHAUS_ME6108 0x6108 -#define PCI_DEVICE_ID_MEILHAUS_ME610F 0x610F - -/* ME6100 isolated version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6114 0x6114 -#define PCI_DEVICE_ID_MEILHAUS_ME6118 0x6118 -#define PCI_DEVICE_ID_MEILHAUS_ME611F 0x611F - -/* ME6100 isle version */ -#define PCI_DEVICE_ID_MEILHAUS_ME6134 0x6134 -#define PCI_DEVICE_ID_MEILHAUS_ME6138 0x6138 -#define PCI_DEVICE_ID_MEILHAUS_ME613F 0x613F - -/* ME6100 standard version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6144 0x6144 -#define PCI_DEVICE_ID_MEILHAUS_ME6148 0x6148 -#define PCI_DEVICE_ID_MEILHAUS_ME614F 0x614F - -/* ME6100 isolated version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6154 0x6154 -#define PCI_DEVICE_ID_MEILHAUS_ME6158 0x6158 -#define PCI_DEVICE_ID_MEILHAUS_ME615F 0x615F - -/* ME6100 isle version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6174 0x6174 -#define PCI_DEVICE_ID_MEILHAUS_ME6178 0x6178 -#define PCI_DEVICE_ID_MEILHAUS_ME617F 0x617F - -/* ME6200 isolated version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6259 0x6259 - -/* ME6300 isolated version with DIO */ -#define PCI_DEVICE_ID_MEILHAUS_ME6359 0x6359 - -/* ME0630 */ -#define PCI_DEVICE_ID_MEILHAUS_ME0630 0x0630 - -/* ME8100 */ -#define PCI_DEVICE_ID_MEILHAUS_ME8100_A 0x810A -#define PCI_DEVICE_ID_MEILHAUS_ME8100_B 0x810B - -/* ME8200 */ -#define PCI_DEVICE_ID_MEILHAUS_ME8200_A 0x820A -#define PCI_DEVICE_ID_MEILHAUS_ME8200_B 0x820B - -/* ME0900 */ -#define PCI_DEVICE_ID_MEILHAUS_ME0940 0x0940 -#define PCI_DEVICE_ID_MEILHAUS_ME0950 0x0950 -#define PCI_DEVICE_ID_MEILHAUS_ME0960 0x0960 - - -/*============================================================================= - USB Vendor IDs - ===========================================================================*/ - -//#define USB_VENDOR_ID_MEPHISTO_S1 0x0403 - - -/*============================================================================= - USB Device IDs - ===========================================================================*/ - -//#define USB_DEVICE_ID_MEPHISTO_S1 0xDCD0 - - -/* ME-1000 defines */ -#define ME1000_NAME_DRIVER "ME-1000" - -#define ME1000_NAME_DEVICE_ME1000 "ME-1000" - -#define ME1000_DESCRIPTION_DEVICE_ME1000 "ME-1000 device, 128 digital i/o lines." - -/* ME-1400 defines */ -#define ME1400_NAME_DRIVER "ME-1400" - -#define ME1400_NAME_DEVICE_ME1400 "ME-1400" -#define ME1400_NAME_DEVICE_ME1400E "ME-1400E" -#define ME1400_NAME_DEVICE_ME1400A "ME-1400A" -#define ME1400_NAME_DEVICE_ME1400EA "ME-1400EA" -#define ME1400_NAME_DEVICE_ME1400B "ME-1400B" -#define ME1400_NAME_DEVICE_ME1400EB "ME-1400EB" -#define ME1400_NAME_DEVICE_ME1400C "ME-1400C" -#define ME1400_NAME_DEVICE_ME1400D "ME-1400D" - -#define ME1400_DESCRIPTION_DEVICE_ME1400 "ME-1400 device, 24 digital i/o lines." -#define ME1400_DESCRIPTION_DEVICE_ME1400E "ME-1400E device, 24 digital i/o lines." -#define ME1400_DESCRIPTION_DEVICE_ME1400A "ME-1400A device, 24 digital i/o lines, 3 counters." -#define ME1400_DESCRIPTION_DEVICE_ME1400EA "ME-1400EA device, 24 digital i/o lines, 3 counters." -#define ME1400_DESCRIPTION_DEVICE_ME1400B "ME-1400B device, 48 digital i/o lines, 6 counters." -#define ME1400_DESCRIPTION_DEVICE_ME1400EB "ME-1400EB device, 48 digital i/o lines, 6 counters." -#define ME1400_DESCRIPTION_DEVICE_ME1400C "ME-1400C device, 24 digital i/o lines, 15 counters." -#define ME1400_DESCRIPTION_DEVICE_ME1400D "ME-1400D device, 48 digital i/o lines, 30 counters." - -/* ME-1600 defines */ -#define ME1600_NAME_DRIVER "ME-1600" - -#define ME1600_NAME_DEVICE_ME16004U "ME-1600/4U" -#define ME1600_NAME_DEVICE_ME16008U "ME-1600/8U" -#define ME1600_NAME_DEVICE_ME160012U "ME-1600/12U" -#define ME1600_NAME_DEVICE_ME160016U "ME-1600/16U" -#define ME1600_NAME_DEVICE_ME160016U8I "ME-1600/16U8I" - -#define ME1600_DESCRIPTION_DEVICE_ME16004U "ME-1600/4U device, 4 voltage outputs." -#define ME1600_DESCRIPTION_DEVICE_ME16008U "ME-1600/8U device, 8 voltage outputs." -#define ME1600_DESCRIPTION_DEVICE_ME160012U "ME-1600/12U device, 12 voltage outputs." -#define ME1600_DESCRIPTION_DEVICE_ME160016U "ME-1600/16U device, 16 voltage outputs." -#define ME1600_DESCRIPTION_DEVICE_ME160016U8I "ME-1600/16U8I device, 16 voltage, 8 current outputs." - -/* ME-4000 defines */ -#define ME4600_NAME_DRIVER "ME-4600" - -#define ME4600_NAME_DEVICE_ME4610 "ME-4610" -#define ME4600_NAME_DEVICE_ME4650 "ME-4650" -#define ME4600_NAME_DEVICE_ME4660 "ME-4660" -#define ME4600_NAME_DEVICE_ME4660I "ME-4660I" -#define ME4600_NAME_DEVICE_ME4660S "ME-4660S" -#define ME4600_NAME_DEVICE_ME4660IS "ME-4660IS" -#define ME4600_NAME_DEVICE_ME4670 "ME-4670" -#define ME4600_NAME_DEVICE_ME4670I "ME-4670I" -#define ME4600_NAME_DEVICE_ME4670S "ME-4670S" -#define ME4600_NAME_DEVICE_ME4670IS "ME-4670IS" -#define ME4600_NAME_DEVICE_ME4680 "ME-4680" -#define ME4600_NAME_DEVICE_ME4680I "ME-4680I" -#define ME4600_NAME_DEVICE_ME4680S "ME-4680S" -#define ME4600_NAME_DEVICE_ME4680IS "ME-4680IS" - -#define ME4600_DESCRIPTION_DEVICE_ME4610 "ME-4610 device, 16 streaming analog inputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4650 "ME-4650 device, 16 streaming analog inputs, 32 digital i/o lines, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4660 "ME-4660 device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4660I "ME-4660I opto isolated device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4660S "ME-4660 device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4660IS "ME-4660I opto isolated device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4670 "ME-4670 device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4670I "ME-4670I opto isolated device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4670S "ME-4670S device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4670IS "ME-4670IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4680 "ME-4680 device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4680I "ME-4680I opto isolated device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4680S "ME-4680S device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." -#define ME4600_DESCRIPTION_DEVICE_ME4680IS "ME-4680IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt." - -/* ME-6000 defines */ -#define ME6000_NAME_DRIVER "ME-6000" - -#define ME6000_NAME_DEVICE_ME60004 "ME-6000/4" -#define ME6000_NAME_DEVICE_ME60008 "ME-6000/8" -#define ME6000_NAME_DEVICE_ME600016 "ME-6000/16" -#define ME6000_NAME_DEVICE_ME6000I4 "ME-6000I/4" -#define ME6000_NAME_DEVICE_ME6000I8 "ME-6000I/8" -#define ME6000_NAME_DEVICE_ME6000I16 "ME-6000I/16" -#define ME6000_NAME_DEVICE_ME6000ISLE4 "ME-6000ISLE/4" -#define ME6000_NAME_DEVICE_ME6000ISLE8 "ME-6000ISLE/8" -#define ME6000_NAME_DEVICE_ME6000ISLE16 "ME-6000ISLE/16" -#define ME6000_NAME_DEVICE_ME61004 "ME-6100/4" -#define ME6000_NAME_DEVICE_ME61008 "ME-6100/8" -#define ME6000_NAME_DEVICE_ME610016 "ME-6100/16" -#define ME6000_NAME_DEVICE_ME6100I4 "ME-6100I/4" -#define ME6000_NAME_DEVICE_ME6100I8 "ME-6100I/8" -#define ME6000_NAME_DEVICE_ME6100I16 "ME-6100I/16" -#define ME6000_NAME_DEVICE_ME6100ISLE4 "ME-6100ISLE/4" -#define ME6000_NAME_DEVICE_ME6100ISLE8 "ME-6100ISLE/8" -#define ME6000_NAME_DEVICE_ME6100ISLE16 "ME-6100ISLE/16" -#define ME6000_NAME_DEVICE_ME60004DIO "ME-6000/4/DIO" -#define ME6000_NAME_DEVICE_ME60008DIO "ME-6000/8/DIO" -#define ME6000_NAME_DEVICE_ME600016DIO "ME-6000/16/DIO" -#define ME6000_NAME_DEVICE_ME6000I4DIO "ME-6000I/4/DIO" -#define ME6000_NAME_DEVICE_ME6000I8DIO "ME-6000I/8/DIO" -#define ME6000_NAME_DEVICE_ME6000I16DIO "ME-6000I/16/DIO" -#define ME6000_NAME_DEVICE_ME6000ISLE4DIO "ME-6000ISLE/4/DIO" -#define ME6000_NAME_DEVICE_ME6000ISLE8DIO "ME-6000ISLE/8/DIO" -#define ME6000_NAME_DEVICE_ME6000ISLE16DIO "ME-6000ISLE/16/DIO" -#define ME6000_NAME_DEVICE_ME61004DIO "ME-6100/4/DIO" -#define ME6000_NAME_DEVICE_ME61008DIO "ME-6100/8/DIO" -#define ME6000_NAME_DEVICE_ME610016DIO "ME-6100/16/DIO" -#define ME6000_NAME_DEVICE_ME6100I4DIO "ME-6100I/4/DIO" -#define ME6000_NAME_DEVICE_ME6100I8DIO "ME-6100I/8/DIO" -#define ME6000_NAME_DEVICE_ME6100I16DIO "ME-6100I/16/DIO" -#define ME6000_NAME_DEVICE_ME6100ISLE4DIO "ME-6100ISLE/4/DIO" -#define ME6000_NAME_DEVICE_ME6100ISLE8DIO "ME-6100ISLE/8/DIO" -#define ME6000_NAME_DEVICE_ME6100ISLE16DIO "ME-6100ISLE/16/DIO" -#define ME6000_NAME_DEVICE_ME6200I9DIO "ME-6200I/9/DIO" -#define ME6000_NAME_DEVICE_ME6300I9DIO "ME-6300I/9/DIO" - -#define ME6000_DESCRIPTION_DEVICE_ME60004 "ME-6000/4 device, 4 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME60008 "ME-6000/8 device, 8 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME600016 "ME-6000/16 device, 16 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000I4 "ME-6000I/4 isolated device, 4 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000I8 "ME-6000I/8 isolated device, 8 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000I16 "ME-6000I/16 isolated device, 16 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4 "ME-6000ISLE/4 isle device, 4 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8 "ME-6000ISLE/8 isle device, 8 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16 "ME-6000ISLE/16 isle device, 16 single analog outputs" -#define ME6000_DESCRIPTION_DEVICE_ME61004 "ME-6100/4 device, 4 streaming analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME61008 "ME-6100/8 device, 4 streaming, 4 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME610016 "ME-6100/16 device, 4 streaming, 12 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100I4 "ME-6100I/4 isolated device, 4 streaming analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100I8 "ME-6100I/8 isolated device, 4 streaming, 4 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100I16 "ME-6100I/16 isolated device, 4 streaming, 12 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4 "ME-6100ISLE/4 isle device, 4 streaming analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8 "ME-6100ISLE/8 isle device, 4 streaming, 4 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16 "ME-6100ISLE/16 isle device, 4 streaming, 12 single analog outputs." -#define ME6000_DESCRIPTION_DEVICE_ME60004DIO "ME-6000/4/DIO device, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME60008DIO "ME-6000/8/DIO device, 8 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME600016DIO "ME-6000/16/DIO device, 8 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000I4DIO "ME-6000I/4/DIO isolated device, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000I8DIO "ME-6000I/8/DIO isolated device, 8 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000I16DIO "ME-6000I/16/DIO isolated device, 16 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO "ME-6000ISLE/4/DIO isle device, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO "ME-6000ISLE/8/DIO isle device, 8 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO "ME-6000ISLE/16/DIO isle device, 16 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME61004DIO "ME-6100/4/DIO device, 4 streaming analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME61008DIO "ME-6100/8/DIO device, 4 streaming, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME610016DIO "ME-6100/16/DIO device, 4 streaming, 12 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100I4DIO "ME-6100I/4/DIO isolated device, 4 streaming analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100I8DIO "ME-6100I/8/DIO isolated device, 4 streaming, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100I16DIO "ME-6100I/16/DIO isolated device, 4 streaming, 12 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO "ME-6100ISLE/4/DIO isle device, 4 streaming analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO "ME-6100ISLE/8/DIO isle device, 4 streaming, 4 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO "ME-6100ISLE/16/DIO isle device, 4 streaming, 12 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6200I9DIO "ME-6200I/9/DIO isolated device, 9 single analog outputs, 16 digital i/o lines." -#define ME6000_DESCRIPTION_DEVICE_ME6300I9DIO "ME-6300I/9/DIO isolated device, 4 streaming, 5 single analog outputs, 16 digital i/o lines." - -/* ME-630 defines */ -#define ME0600_NAME_DRIVER "ME-0600" - -#define ME0600_NAME_DEVICE_ME0630 "ME-630" - -#define ME0600_DESCRIPTION_DEVICE_ME0630 "ME-630 device, up to 16 relay, 8 digital ttl input lines, 8 isolated digital input lines, 16 digital i/o lines, 2 external interrupts." - -/* ME-8100 defines */ -#define ME8100_NAME_DRIVER "ME-8100" - -#define ME8100_NAME_DEVICE_ME8100A "ME-8100A" -#define ME8100_NAME_DEVICE_ME8100B "ME-8100B" - -#define ME8100_DESCRIPTION_DEVICE_ME8100A "ME-8100A opto isolated device, 16 digital input lines, 16 digital output lines." -#define ME8100_DESCRIPTION_DEVICE_ME8100B "ME-8100B opto isolated device, 32 digital input lines, 32 digital output lines, 3 counters." - -/* ME-8200 defines */ -#define ME8200_NAME_DRIVER "ME-8200" - -#define ME8200_NAME_DEVICE_ME8200A "ME-8200A" -#define ME8200_NAME_DEVICE_ME8200B "ME-8200B" - -#define ME8200_DESCRIPTION_DEVICE_ME8200A "ME-8200A opto isolated device, 8 digital output lines, 8 digital input lines, 16 digital i/o lines." -#define ME8200_DESCRIPTION_DEVICE_ME8200B "ME-8200B opto isolated device, 16 digital output lines, 16 digital input lines, 16 digital i/o lines." - -/* ME-0900 defines */ -#define ME0900_NAME_DRIVER "ME-0900" - -#define ME0900_NAME_DEVICE_ME0940 "ME-94" -#define ME0900_NAME_DEVICE_ME0950 "ME-95" -#define ME0900_NAME_DEVICE_ME0960 "ME-96" - -#define ME0900_DESCRIPTION_DEVICE_ME0940 "ME-94 device, 16 digital input lines, 2 external interrupt lines." -#define ME0900_DESCRIPTION_DEVICE_ME0950 "ME-95 device, 16 digital output lines." -#define ME0900_DESCRIPTION_DEVICE_ME0960 "ME-96 device, 8 digital input lines, 8 digital output lines, 2 external interrupt lines." - -/* ME-DUMMY defines */ -#define MEDUMMY_NAME_DRIVER "ME-Dummy" - -/* MEPHISTO_S1 defines */ -/* -#define MEPHISTO_S1_NAME_DRIVER "MEphisto Scope 1" -#define MEPHISTO_S1_NAME_DEVICE "MEphisto Scope 1" -#define MEPHISTO_S1_DESCRIPTION_DEVICE "MEphisto Scope 1 device, 2 analog inputs, 24 digital i/o." -*/ -/* Error defines */ -#define EMPTY_NAME_DRIVER "ME-???" -#define EMPTY_NAME_DEVICE "ME-???" -#define EMPTY_DESCRIPTION_DEVICE "ME-??? unknown device" - -#endif diff --git a/drivers/staging/meilhaus/meioctl.h b/drivers/staging/meilhaus/meioctl.h deleted file mode 100644 index 6dc719fba57..00000000000 --- a/drivers/staging/meilhaus/meioctl.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : meioctl.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEIOCTL_H_ -#define _MEIOCTL_H_ - - -/*============================================================================= - Types for the input/output ioctls - ===========================================================================*/ - -typedef struct me_io_irq_start { - int device; - int subdevice; - int channel; - int irq_source; - int irq_edge; - int irq_arg; - int flags; - int errno; -} me_io_irq_start_t; - - -typedef struct me_io_irq_wait { - int device; - int subdevice; - int channel; - int irq_count; - int value; - int time_out; - int flags; - int errno; -} me_io_irq_wait_t; - - -typedef struct me_io_irq_stop { - int device; - int subdevice; - int channel; - int flags; - int errno; -} me_io_irq_stop_t; - - -typedef struct me_io_reset_device { - int device; - int flags; - int errno; -} me_io_reset_device_t; - - -typedef struct me_io_reset_subdevice { - int device; - int subdevice; - int flags; - int errno; -} me_io_reset_subdevice_t; - - -typedef struct me_io_single_config { - int device; - int subdevice; - int channel; - int single_config; - int ref; - int trig_chan; - int trig_type; - int trig_edge; - int flags; - int errno; -} me_io_single_config_t; - - -typedef struct me_io_single { - meIOSingle_t *single_list; - int count; - int flags; - int errno; -} me_io_single_t; - - -typedef struct me_io_stream_config { - int device; - int subdevice; - meIOStreamConfig_t *config_list; - int count; - meIOStreamTrigger_t trigger; - int fifo_irq_threshold; - int flags; - int errno; -} me_io_stream_config_t; - - -typedef struct me_io_stream_new_values { - int device; - int subdevice; - int time_out; - int count; - int flags; - int errno; -} me_io_stream_new_values_t; - - -typedef struct me_io_stream_read { - int device; - int subdevice; - int read_mode; - int *values; - int count; - int flags; - int errno; -} me_io_stream_read_t; - - -typedef struct me_io_stream_start { - meIOStreamStart_t *start_list; - int count; - int flags; - int errno; -} me_io_stream_start_t; - - -typedef struct me_io_stream_status { - int device; - int subdevice; - int wait; - int status; - int count; - int flags; - int errno; -} me_io_stream_status_t; - - -typedef struct me_io_stream_stop { - meIOStreamStop_t *stop_list; - int count; - int flags; - int errno; -} me_io_stream_stop_t; - - -typedef struct me_io_stream_write { - int device; - int subdevice; - int write_mode; - int *values; - int count; - int flags; - int errno; -} me_io_stream_write_t; - - -/*============================================================================= - Types for the lock ioctls - ===========================================================================*/ - -typedef struct me_lock_device { - int device; - int lock; - int flags; - int errno; -} me_lock_device_t; - - -typedef struct me_lock_driver { - int flags; - int lock; - int errno; -} me_lock_driver_t; - - -typedef struct me_lock_subdevice { - int device; - int subdevice; - int lock; - int flags; - int errno; -} me_lock_subdevice_t; - - -/*============================================================================= - Types for the query ioctls - ===========================================================================*/ - -typedef struct me_query_info_device { - int device; - int vendor_id; - int device_id; - int serial_no; - int bus_type; - int bus_no; - int dev_no; - int func_no; - int plugged; - int errno; -} me_query_info_device_t; - - -typedef struct me_query_description_device { - int device; - char *name; - int count; - int errno; -} me_query_description_device_t; - - -typedef struct me_query_name_device { - int device; - char *name; - int count; - int errno; -} me_query_name_device_t; - - -typedef struct me_query_name_device_driver { - int device; - char *name; - int count; - int errno; -} me_query_name_device_driver_t; - - -typedef struct me_query_version_main_driver { - int version; - int errno; -} me_query_version_main_driver_t; - - -typedef struct me_query_version_device_driver { - int device; - int version; - int errno; -} me_query_version_device_driver_t; - - -typedef struct me_query_number_devices { - int number; - int errno; -} me_query_number_devices_t; - - -typedef struct me_query_number_subdevices { - int device; - int number; - int errno; -} me_query_number_subdevices_t; - - -typedef struct me_query_number_channels { - int device; - int subdevice; - int number; - int errno; -} me_query_number_channels_t; - - -typedef struct me_query_number_ranges { - int device; - int subdevice; - int channel; - int unit; - int number; - int errno; -} me_query_number_ranges_t; - - -typedef struct me_query_subdevice_by_type { - int device; - int start_subdevice; - int type; - int subtype; - int subdevice; - int errno; -} me_query_subdevice_by_type_t; - - -typedef struct me_query_subdevice_type { - int device; - int subdevice; - int type; - int subtype; - int errno; -} me_query_subdevice_type_t; - - -typedef struct me_query_subdevice_caps { - int device; - int subdevice; - int caps; - int errno; -} me_query_subdevice_caps_t; - - -typedef struct me_query_subdevice_caps_args { - int device; - int subdevice; - int cap; - int args[8]; - int count; - int errno; -} me_query_subdevice_caps_args_t; - - -typedef struct me_query_timer { - int device; - int subdevice; - int timer; - int base_frequency; - long long min_ticks; - long long max_ticks; - int errno; -} me_query_timer_t; - - -typedef struct me_query_range_by_min_max { - int device; - int subdevice; - int channel; - int unit; - int min; - int max; - int max_data; - int range; - int errno; -} me_query_range_by_min_max_t; - - -typedef struct me_query_range_info { - int device; - int subdevice; - int channel; - int unit; - int range; - int min; - int max; - int max_data; - int errno; -} me_query_range_info_t; - - -/*============================================================================= - Types for the configuration ioctls - ===========================================================================*/ - -typedef struct me_cfg_tcpip_location { - int access_type; - char *remote_host; - int remote_device_number; -} me_cfg_tcpip_location_t; - - -typedef union me_cfg_tcpip { - int access_type; - me_cfg_tcpip_location_t location; -} me_cfg_tcpip_t; - - -typedef struct me_cfg_pci_hw_location { - unsigned int bus_type; - unsigned int bus_no; - unsigned int device_no; - unsigned int function_no; -} me_cfg_pci_hw_location_t; - -/* -typedef struct me_cfg_usb_hw_location { - unsigned int bus_type; - unsigned int root_hub_no; -} me_cfg_usb_hw_location_t; -*/ - -typedef union me_cfg_hw_location { - unsigned int bus_type; - me_cfg_pci_hw_location_t pci; -// me_cfg_usb_hw_location_t usb; -} me_cfg_hw_location_t; - - -typedef struct me_cfg_device_info { - unsigned int vendor_id; - unsigned int device_id; - unsigned int serial_no; - me_cfg_hw_location_t hw_location; -} me_cfg_device_info_t; - - -typedef struct me_cfg_subdevice_info { - int type; - int sub_type; - unsigned int number_channels; -} me_cfg_subdevice_info_t; - - -typedef struct me_cfg_range_entry { - int unit; - double min; - double max; - unsigned int max_data; -} me_cfg_range_entry_t; - - -typedef struct me_cfg_mux32m_device { - int type; - int timed; - unsigned int ai_channel; - unsigned int dio_device; - unsigned int dio_subdevice; - unsigned int timer_device; - unsigned int timer_subdevice; - unsigned int mux32s_count; -} me_cfg_mux32m_device_t; - - -typedef struct me_cfg_demux32_device { - int type; - int timed; - unsigned int ao_channel; - unsigned int dio_device; - unsigned int dio_subdevice; - unsigned int timer_device; - unsigned int timer_subdevice; -} me_cfg_demux32_device_t; - - -typedef union me_cfg_external_device { - int type; - me_cfg_mux32m_device_t mux32m; - me_cfg_demux32_device_t demux32; -} me_cfg_external_device_t; - - -typedef struct me_cfg_subdevice_entry { - me_cfg_subdevice_info_t info; - me_cfg_range_entry_t *range_list; - unsigned int count; - int locked; - me_cfg_external_device_t external_device; -} me_cfg_subdevice_entry_t; - - -typedef struct me_cfg_device_entry { - me_cfg_tcpip_t tcpip; - me_cfg_device_info_t info; - me_cfg_subdevice_entry_t *subdevice_list; - unsigned int count; -} me_cfg_device_entry_t; - - -typedef struct me_config_load { - me_cfg_device_entry_t *device_list; - unsigned int count; - int errno; -} me_config_load_t; - - -/*============================================================================= - The ioctls of the board - ===========================================================================*/ - -#define MEMAIN_MAGIC 'y' - -#define ME_IO_IRQ_ENABLE _IOR (MEMAIN_MAGIC, 1, me_io_irq_start_t) -#define ME_IO_IRQ_WAIT _IOR (MEMAIN_MAGIC, 2, me_io_irq_wait_t) -#define ME_IO_IRQ_DISABLE _IOR (MEMAIN_MAGIC, 3, me_io_irq_stop_t) - -#define ME_IO_RESET_DEVICE _IOW (MEMAIN_MAGIC, 4, me_io_reset_device_t) -#define ME_IO_RESET_SUBDEVICE _IOW (MEMAIN_MAGIC, 5, me_io_reset_subdevice_t) - -#define ME_IO_SINGLE _IOWR(MEMAIN_MAGIC, 6, me_io_single_t) -#define ME_IO_SINGLE_CONFIG _IOW (MEMAIN_MAGIC, 7, me_io_single_config_t) - -#define ME_IO_STREAM_CONFIG _IOW (MEMAIN_MAGIC, 8, me_io_stream_config_t) -#define ME_IO_STREAM_NEW_VALUES _IOR (MEMAIN_MAGIC, 9, me_io_stream_new_values_t) -#define ME_IO_STREAM_READ _IOR (MEMAIN_MAGIC, 10, me_io_stream_read_t) -#define ME_IO_STREAM_START _IOW (MEMAIN_MAGIC, 11, me_io_stream_start_t) -#define ME_IO_STREAM_STATUS _IOR (MEMAIN_MAGIC, 12, me_io_stream_status_t) -#define ME_IO_STREAM_STOP _IOW (MEMAIN_MAGIC, 13, me_io_stream_stop_t) -#define ME_IO_STREAM_WRITE _IOW (MEMAIN_MAGIC, 14, me_io_stream_write_t) - -#define ME_LOCK_DRIVER _IOW (MEMAIN_MAGIC, 15, me_lock_driver_t) -#define ME_LOCK_DEVICE _IOW (MEMAIN_MAGIC, 16, me_lock_device_t) -#define ME_LOCK_SUBDEVICE _IOW (MEMAIN_MAGIC, 17, me_lock_subdevice_t) - -#define ME_QUERY_DESCRIPTION_DEVICE _IOR (MEMAIN_MAGIC, 18, me_query_description_device_t) - -#define ME_QUERY_INFO_DEVICE _IOR (MEMAIN_MAGIC, 19, me_query_info_device_t) - -#define ME_QUERY_NAME_DEVICE _IOR (MEMAIN_MAGIC, 20, me_query_name_device_t) -#define ME_QUERY_NAME_DEVICE_DRIVER _IOR (MEMAIN_MAGIC, 21, me_query_name_device_driver_t) - -#define ME_QUERY_NUMBER_DEVICES _IOR (MEMAIN_MAGIC, 22, me_query_number_devices_t) -#define ME_QUERY_NUMBER_SUBDEVICES _IOR (MEMAIN_MAGIC, 23, me_query_number_subdevices_t) -#define ME_QUERY_NUMBER_CHANNELS _IOR (MEMAIN_MAGIC, 24, me_query_number_channels_t) -#define ME_QUERY_NUMBER_RANGES _IOR (MEMAIN_MAGIC, 25, me_query_number_ranges_t) - -#define ME_QUERY_RANGE_BY_MIN_MAX _IOR (MEMAIN_MAGIC, 26, me_query_range_by_min_max_t) -#define ME_QUERY_RANGE_INFO _IOR (MEMAIN_MAGIC, 27, me_query_range_info_t) - -#define ME_QUERY_SUBDEVICE_BY_TYPE _IOR (MEMAIN_MAGIC, 28, me_query_subdevice_by_type_t) -#define ME_QUERY_SUBDEVICE_TYPE _IOR (MEMAIN_MAGIC, 29, me_query_subdevice_type_t) -#define ME_QUERY_SUBDEVICE_CAPS _IOR (MEMAIN_MAGIC, 29, me_query_subdevice_caps_t) -#define ME_QUERY_SUBDEVICE_CAPS_ARGS _IOR (MEMAIN_MAGIC, 30, me_query_subdevice_caps_args_t) - -#define ME_QUERY_TIMER _IOR (MEMAIN_MAGIC, 31, me_query_timer_t) - -#define ME_QUERY_VERSION_DEVICE_DRIVER _IOR (MEMAIN_MAGIC, 32, me_query_version_device_driver_t) -#define ME_QUERY_VERSION_MAIN_DRIVER _IOR (MEMAIN_MAGIC, 33, me_query_version_main_driver_t) - -#define ME_CONFIG_LOAD _IOWR(MEMAIN_MAGIC, 34, me_config_load_t) - -#endif diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c deleted file mode 100644 index c4908549192..00000000000 --- a/drivers/staging/meilhaus/memain.c +++ /dev/null @@ -1,2084 +0,0 @@ -/** - * @file memain.c - * - * @brief Main Meilhaus device driver. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - * @author Krzysztof Gantzke (k.gantzke@meilhaus.de) - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include -#include -//#include -#include -#include -#include -#include - -#include "medefines.h" -#include "metypes.h" -#include "meerror.h" - -#include "medebug.h" -#include "memain.h" -#include "medevice.h" -#include "meioctl.h" -#include "mecommon.h" - -/* Module parameters -*/ - -#ifdef BOSCH -static unsigned int me_bosch_fw = 0; -EXPORT_SYMBOL(me_bosch_fw); - -# ifdef module_param -module_param(me_bosch_fw, int, S_IRUGO); -# else -MODULE_PARM(me_bosch_fw, "i"); -# endif - -MODULE_PARM_DESC(me_bosch_fw, - "Flags which signals the ME-4600 driver to load the bosch firmware (default = 0)."); -#endif //BOSCH - -/* Global Driver Lock -*/ - -static struct file *me_filep = NULL; -static int me_count = 0; -static DEFINE_SPINLOCK(me_lock); -static DECLARE_RWSEM(me_rwsem); - -/* Board instances are kept in a global list */ -LIST_HEAD(me_device_list); - -/* Prototypes -*/ - -static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id); -static void me_remove_pci(struct pci_dev *dev); -static int insert_to_device_list(me_device_t *n_device); -static int replace_with_dummy(int vendor_id, int device_id, int serial_no); -static void clear_device_list(void); -static int me_open(struct inode *inode_ptr, struct file *filep); -static int me_release(struct inode *, struct file *); -static int me_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -//static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id); -//static void me_disconnect_usb(struct usb_interface *interface); - -/* File operations provided by the module -*/ - -static const struct file_operations me_file_operations = { - .owner = THIS_MODULE, - .ioctl = me_ioctl, - .open = me_open, - .release = me_release, -}; - -static const struct pci_device_id me_pci_table[] = { - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1400) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140B) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14E0) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EA) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EB) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140C) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140D) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_4U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_8U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_12U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4610) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6004) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6008) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME600F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6014) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6018) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME601F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6034) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6038) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME603F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6104) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6108) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME610F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6114) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6118) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME611F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6134) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6138) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME613F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6044) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6048) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME604F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6054) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6058) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME605F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6074) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6078) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME607F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6144) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6148) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME614F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6154) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6158) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME615F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6174) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6178) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME617F) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6259) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6359) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0630) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_A) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_B) }, - - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0940) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0950) }, - { PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0960) }, - - { } -}; -MODULE_DEVICE_TABLE(pci, me_pci_table); - -static struct pci_driver me_pci_driver = { - .name = MEMAIN_NAME, - .id_table = me_pci_table, - .probe = me_probe_pci, - .remove = __devexit_p(me_remove_pci), -}; - -/* -static struct usb_device_id me_usb_table[] = { - { USB_DEVICE(USB_VENDOR_ID_MEPHISTO_S1, USB_DEVICE_ID_MEPHISTO_S1) }, - { 0 } -}; -MODULE_DEVICE_TABLE (usb, me_usb_table); - -static struct usb_driver me_usb_driver = -{ - .name = MEMAIN_NAME, - .id_table = me_usb_table, - .probe = me_probe_usb, - .disconnect = me_disconnect_usb -}; -*/ - -#ifdef ME_LOCK_MULTIPLEX_TEMPLATE -ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_device", - me_lock_device_t, - me_lock_device, - me_device_lock_device, - (device, filep, karg.lock, karg.flags)) - - ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_subdevice", - me_lock_subdevice_t, - me_lock_subdevice, - me_device_lock_subdevice, - (device, filep, karg.subdevice, karg.lock, - karg.flags)) -#else -#error macro ME_LOCK_MULTIPLEX_TEMPLATE not defined -#endif - -#ifdef ME_IO_MULTIPLEX_TEMPLATE -ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_start", - me_io_irq_start_t, - me_io_irq_start, - me_device_io_irq_start, - (device, - filep, - karg.subdevice, - karg.channel, - karg.irq_source, - karg.irq_edge, karg.irq_arg, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_wait", - me_io_irq_wait_t, - me_io_irq_wait, - me_device_io_irq_wait, - (device, - filep, - karg.subdevice, - karg.channel, - &karg.irq_count, &karg.value, karg.time_out, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_stop", - me_io_irq_stop_t, - me_io_irq_stop, - me_device_io_irq_stop, - (device, - filep, karg.subdevice, karg.channel, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_device", - me_io_reset_device_t, - me_io_reset_device, - me_device_io_reset_device, (device, filep, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_subdevice", - me_io_reset_subdevice_t, - me_io_reset_subdevice, - me_device_io_reset_subdevice, - (device, filep, karg.subdevice, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_single_config", - me_io_single_config_t, - me_io_single_config, - me_device_io_single_config, - (device, - filep, - karg.subdevice, - karg.channel, - karg.single_config, - karg.ref, - karg.trig_chan, - karg.trig_type, karg.trig_edge, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_new_values", - me_io_stream_new_values_t, - me_io_stream_new_values, - me_device_io_stream_new_values, - (device, - filep, - karg.subdevice, karg.time_out, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_read", - me_io_stream_read_t, - me_io_stream_read, - me_device_io_stream_read, - (device, - filep, - karg.subdevice, - karg.read_mode, karg.values, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_status", - me_io_stream_status_t, - me_io_stream_status, - me_device_io_stream_status, - (device, - filep, - karg.subdevice, - karg.wait, &karg.status, &karg.count, karg.flags)) - - ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_write", - me_io_stream_write_t, - me_io_stream_write, - me_device_io_stream_write, - (device, - filep, - karg.subdevice, - karg.write_mode, karg.values, &karg.count, karg.flags)) -#else -#error macro ME_IO_MULTIPLEX_TEMPLATE not defined -#endif - -#ifdef ME_QUERY_MULTIPLEX_STR_TEMPLATE -ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device", - me_query_name_device_t, - me_query_name_device, - me_device_query_name_device, (device, &msg)) - - ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device_driver", - me_query_name_device_driver_t, - me_query_name_device_driver, - me_device_query_name_device_driver, - (device, &msg)) - - ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_description_device", - me_query_description_device_t, - me_query_description_device, - me_device_query_description_device, - (device, &msg)) -#else -#error macro ME_QUERY_MULTIPLEX_STR_TEMPLATE not defined -#endif - -#ifdef ME_QUERY_MULTIPLEX_TEMPLATE -ME_QUERY_MULTIPLEX_TEMPLATE("me_query_info_device", - me_query_info_device_t, - me_query_info_device, - me_device_query_info_device, - (device, - &karg.vendor_id, - &karg.device_id, - &karg.serial_no, - &karg.bus_type, - &karg.bus_no, - &karg.dev_no, &karg.func_no, &karg.plugged)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_subdevices", - me_query_number_subdevices_t, - me_query_number_subdevices, - me_device_query_number_subdevices, - (device, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_channels", - me_query_number_channels_t, - me_query_number_channels, - me_device_query_number_channels, - (device, karg.subdevice, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_by_type", - me_query_subdevice_by_type_t, - me_query_subdevice_by_type, - me_device_query_subdevice_by_type, - (device, - karg.start_subdevice, - karg.type, karg.subtype, &karg.subdevice)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_type", - me_query_subdevice_type_t, - me_query_subdevice_type, - me_device_query_subdevice_type, - (device, karg.subdevice, &karg.type, &karg.subtype)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps", - me_query_subdevice_caps_t, - me_query_subdevice_caps, - me_device_query_subdevice_caps, - (device, karg.subdevice, &karg.caps)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps_args", - me_query_subdevice_caps_args_t, - me_query_subdevice_caps_args, - me_device_query_subdevice_caps_args, - (device, karg.subdevice, karg.cap, karg.args, - karg.count)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_ranges", - me_query_number_ranges_t, - me_query_number_ranges, - me_device_query_number_ranges, - (device, karg.subdevice, karg.unit, &karg.number)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_by_min_max", - me_query_range_by_min_max_t, - me_query_range_by_min_max, - me_device_query_range_by_min_max, - (device, - karg.subdevice, - karg.unit, - &karg.min, &karg.max, &karg.max_data, &karg.range)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_info", - me_query_range_info_t, - me_query_range_info, - me_device_query_range_info, - (device, - karg.subdevice, - karg.range, - &karg.unit, &karg.min, &karg.max, &karg.max_data)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_timer", - me_query_timer_t, - me_query_timer, - me_device_query_timer, - (device, - karg.subdevice, - karg.timer, - &karg.base_frequency, - &karg.min_ticks, &karg.max_ticks)) - - ME_QUERY_MULTIPLEX_TEMPLATE("me_query_version_device_driver", - me_query_version_device_driver_t, - me_query_version_device_driver, - me_device_query_version_device_driver, - (device, &karg.version)) -#else -#error macro ME_QUERY_MULTIPLEX_TEMPLATE not defined -#endif - -/** ******************************************************************************** **/ - -static me_device_t *get_dummy_instance(unsigned short vendor_id, - unsigned short device_id, - unsigned int serial_no, - int bus_type, - int bus_no, int dev_no, int func_no) -{ - int err; - me_dummy_constructor_t constructor = NULL; - me_device_t *instance; - - PDEBUG("executed.\n"); - - if ((constructor = symbol_get(medummy_constructor)) == NULL) { - err = request_module(MEDUMMY_NAME); - - if (err) { - PERROR("Error while request for module %s.\n", - MEDUMMY_NAME); - return NULL; - } - - if ((constructor = symbol_get(medummy_constructor)) == NULL) { - PERROR("Can't get %s driver module constructor.\n", - MEDUMMY_NAME); - return NULL; - } - } - - if ((instance = (*constructor) (vendor_id, - device_id, - serial_no, - bus_type, - bus_no, dev_no, func_no)) == NULL) - symbol_put(medummy_constructor); - - return instance; -} - -static int __devinit me_probe_pci(struct pci_dev *dev, - const struct pci_device_id *id) -{ - int err; - me_pci_constructor_t constructor = NULL; -#ifdef BOSCH - me_bosch_constructor_t constructor_bosch = NULL; -#endif - me_device_t *n_device = NULL; - uint32_t device; - - char constructor_name[24] = "me0000_pci_constructor"; - char module_name[7] = "me0000"; - - PDEBUG("executed.\n"); - device = dev->device; - if ((device & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver. - device &= 0xF0FF; - } - - constructor_name[2] += (char)((device >> 12) & 0x000F); - constructor_name[3] += (char)((device >> 8) & 0x000F); - PDEBUG("constructor_name: %s\n", constructor_name); - module_name[2] += (char)((device >> 12) & 0x000F); - module_name[3] += (char)((device >> 8) & 0x000F); - PDEBUG("module_name: %s\n", module_name); - - if ((constructor = - (me_pci_constructor_t) symbol_get(constructor_name)) == NULL) { - if (request_module("%s", module_name)) { - PERROR("Error while request for module %s.\n", - module_name); - return -ENODEV; - } - - if ((constructor = - (me_pci_constructor_t) symbol_get(constructor_name)) == - NULL) { - PERROR("Can't get %s driver module constructor.\n", - module_name); - return -ENODEV; - } - } -#ifdef BOSCH - if ((device & 0xF000) == 0x4000) { // Bosch build has differnt constructor for me4600. - if ((n_device = - (*constructor_bosch) (dev, me_bosch_fw)) == NULL) { - symbol_put(constructor_name); - PERROR - ("Can't get device instance of %s driver module.\n", - module_name); - return -ENODEV; - } - } else { -#endif - if ((n_device = (*constructor) (dev)) == NULL) { - symbol_put(constructor_name); - PERROR - ("Can't get device instance of %s driver module.\n", - module_name); - return -ENODEV; - } -#ifdef BOSCH - } -#endif - - insert_to_device_list(n_device); - err = - n_device->me_device_io_reset_device(n_device, NULL, - ME_IO_RESET_DEVICE_NO_FLAGS); - if (err) { - PERROR("Error while reseting device.\n"); - } else { - PDEBUG("Reseting device was sucessful.\n"); - } - return ME_ERRNO_SUCCESS; -} - -static void release_instance(me_device_t *device) -{ - int vendor_id; - int device_id; - int serial_no; - int bus_type; - int bus_no; - int dev_no; - int func_no; - int plugged; - - uint32_t dev_id; - - char constructor_name[24] = "me0000_pci_constructor"; - - PDEBUG("executed.\n"); - - device->me_device_query_info_device(device, - &vendor_id, - &device_id, - &serial_no, - &bus_type, - &bus_no, - &dev_no, &func_no, &plugged); - - dev_id = device_id; - device->me_device_destructor(device); - - if (plugged != ME_PLUGGED_IN) { - PDEBUG("release: medummy_constructor\n"); - - symbol_put("medummy_constructor"); - } else { - if ((dev_id & 0xF000) == 0x6000) { // Exceptions: me61xx, me62xx, me63xx are handled by one driver. - dev_id &= 0xF0FF; - } - - constructor_name[2] += (char)((dev_id >> 12) & 0x000F); - constructor_name[3] += (char)((dev_id >> 8) & 0x000F); - PDEBUG("release: %s\n", constructor_name); - - symbol_put(constructor_name); - } -} - -static int insert_to_device_list(me_device_t *n_device) -{ - me_device_t *o_device = NULL; - - struct list_head *pos; - int n_vendor_id; - int n_device_id; - int n_serial_no; - int n_bus_type; - int n_bus_no; - int n_dev_no; - int n_func_no; - int n_plugged; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - n_device->me_device_query_info_device(n_device, - &n_vendor_id, - &n_device_id, - &n_serial_no, - &n_bus_type, - &n_bus_no, - &n_dev_no, - &n_func_no, &n_plugged); - - down_write(&me_rwsem); - - list_for_each(pos, &me_device_list) { - o_device = list_entry(pos, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, &o_plugged); - - if (o_plugged == ME_PLUGGED_OUT) { - if (((o_vendor_id == n_vendor_id) && - (o_device_id == n_device_id) && - (o_serial_no == n_serial_no) && - (o_bus_type == n_bus_type)) || - ((o_vendor_id == n_vendor_id) && - (o_device_id == n_device_id) && - (o_bus_type == n_bus_type) && - (o_bus_no == n_bus_no) && - (o_dev_no == n_dev_no) && - (o_func_no == n_func_no))) { - n_device->list.prev = pos->prev; - n_device->list.next = pos->next; - pos->prev->next = &n_device->list; - pos->next->prev = &n_device->list; - release_instance(o_device); - break; - } - } - } - - if (pos == &me_device_list) { - list_add_tail(&n_device->list, &me_device_list); - } - - up_write(&me_rwsem); - - return 0; -} - -static void __devexit me_remove_pci(struct pci_dev *dev) -{ - int vendor_id = dev->vendor; - int device_id = dev->device; - int subsystem_vendor = dev->subsystem_vendor; - int subsystem_device = dev->subsystem_device; - int serial_no = (subsystem_device << 16) | subsystem_vendor; - - PDEBUG("executed.\n"); - - PINFO("Vendor id = 0x%08X\n", vendor_id); - PINFO("Device id = 0x%08X\n", device_id); - PINFO("Serial Number = 0x%08X\n", serial_no); - - replace_with_dummy(vendor_id, device_id, serial_no); -} - -static int replace_with_dummy(int vendor_id, int device_id, int serial_no) -{ - - struct list_head *pos; - me_device_t *n_device = NULL; - me_device_t *o_device = NULL; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - down_write(&me_rwsem); - - list_for_each(pos, &me_device_list) { - o_device = list_entry(pos, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, &o_plugged); - - if (o_plugged == ME_PLUGGED_IN) { - if (((o_vendor_id == vendor_id) && - (o_device_id == device_id) && - (o_serial_no == serial_no))) { - n_device = get_dummy_instance(o_vendor_id, - o_device_id, - o_serial_no, - o_bus_type, - o_bus_no, - o_dev_no, - o_func_no); - - if (!n_device) { - up_write(&me_rwsem); - PERROR("Cannot get dummy instance.\n"); - return 1; - } - - n_device->list.prev = pos->prev; - - n_device->list.next = pos->next; - pos->prev->next = &n_device->list; - pos->next->prev = &n_device->list; - release_instance(o_device); - break; - } - } - } - - up_write(&me_rwsem); - - return 0; -} - -static void clear_device_list(void) -{ - - struct list_head *entry; - me_device_t *device; - - // Clear the device info list . - down_write(&me_rwsem); - - while (!list_empty(&me_device_list)) { - entry = me_device_list.next; - device = list_entry(entry, me_device_t, list); - list_del(entry); - release_instance(device); - } - - up_write(&me_rwsem); -} - -static int lock_driver(struct file *filep, int lock, int flags) -{ - int err = ME_ERRNO_SUCCESS; - me_device_t *device; - - PDEBUG("executed.\n"); - - down_read(&me_rwsem); - - spin_lock(&me_lock); - - switch (lock) { - - case ME_LOCK_SET: - if (me_count) { - PERROR - ("Driver System is currently used by another process.\n"); - err = ME_ERRNO_USED; - } else if ((me_filep != NULL) && (me_filep != filep)) { - PERROR - ("Driver System is already logged by another process.\n"); - err = ME_ERRNO_LOCKED; - } else { - list_for_each_entry(device, &me_device_list, list) { - err = - device->me_device_lock_device(device, filep, - ME_LOCK_CHECK, - flags); - - if (err) - break; - } - - if (!err) - me_filep = filep; - } - - break; - - case ME_LOCK_RELEASE: - if ((me_filep != NULL) && (me_filep != filep)) { - err = ME_ERRNO_SUCCESS; - } else { - list_for_each_entry(device, &me_device_list, list) { - device->me_device_lock_device(device, filep, - ME_LOCK_RELEASE, - flags); - } - - me_filep = NULL; - } - - break; - - default: - PERROR("Invalid lock specified.\n"); - - err = ME_ERRNO_INVALID_LOCK; - - break; - } - - spin_unlock(&me_lock); - - up_read(&me_rwsem); - - return err; -} - -static int me_lock_driver(struct file *filep, me_lock_driver_t *arg) -{ - int err = 0; - - me_lock_driver_t lock; - - PDEBUG("executed.\n"); - - err = copy_from_user(&lock, arg, sizeof(me_lock_driver_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - lock.errno = lock_driver(filep, lock.lock, lock.flags); - - err = copy_to_user(arg, &lock, sizeof(me_lock_driver_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return ME_ERRNO_SUCCESS; -} - -static int me_open(struct inode *inode_ptr, struct file *filep) -{ - - PDEBUG("executed.\n"); - // Nothing to do here. - return 0; -} - -static int me_release(struct inode *inode_ptr, struct file *filep) -{ - - PDEBUG("executed.\n"); - lock_driver(filep, ME_LOCK_RELEASE, ME_LOCK_DRIVER_NO_FLAGS); - - return 0; -} - -static int me_query_version_main_driver(struct file *filep, - me_query_version_main_driver_t *arg) -{ - int err; - me_query_version_main_driver_t karg; - - PDEBUG("executed.\n"); - - karg.version = ME_VERSION_DRIVER; - karg.errno = ME_ERRNO_SUCCESS; - - err = copy_to_user(arg, &karg, sizeof(me_query_version_main_driver_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return 0; -} - -static int me_config_load_device(struct file *filep, - me_cfg_device_entry_t *karg, int device_no) -{ - - int err = ME_ERRNO_SUCCESS; - int k = 0; - - struct list_head *pos = NULL; - me_device_t *device = NULL; - - PDEBUG("executed.\n"); - - list_for_each(pos, &me_device_list) { - if (k == device_no) { - device = list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - PERROR("Invalid device number specified.\n"); - return ME_ERRNO_INVALID_DEVICE; - } else { - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Resource is locked by another process.\n"); - return ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - err = - device->me_device_config_load(device, filep, karg); - - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - } - } - - return err; -} - -static int me_config_load(struct file *filep, me_config_load_t *arg) -{ - int err; - int i; - me_config_load_t cfg_setup; - me_config_load_t karg_cfg_setup; - - struct list_head *pos = NULL; - - struct list_head new_list; - me_device_t *o_device; - me_device_t *n_device; - int o_vendor_id; - int o_device_id; - int o_serial_no; - int o_bus_type; - int o_bus_no; - int o_dev_no; - int o_func_no; - int o_plugged; - - PDEBUG("executed.\n"); - - // Copy argument to kernel space. - err = copy_from_user(&karg_cfg_setup, arg, sizeof(me_config_load_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - // Allocate kernel buffer for device list. - cfg_setup.device_list = - kmalloc(sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count, - GFP_KERNEL); - - if (!cfg_setup.device_list) { - PERROR("Can't get buffer %li for device list.\n", - sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count); - return -ENOMEM; - } - // Copy device list to kernel space. - err = - copy_from_user(cfg_setup.device_list, karg_cfg_setup.device_list, - sizeof(me_cfg_device_entry_t) * - karg_cfg_setup.count); - - if (err) { - PERROR("Can't copy device list to kernel space.\n"); - kfree(cfg_setup.device_list); - return -EFAULT; - } - - cfg_setup.count = karg_cfg_setup.count; - - INIT_LIST_HEAD(&new_list); - - down_write(&me_rwsem); - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - karg_cfg_setup.errno = ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg_cfg_setup.count; i++) { - PDEBUG("me_config_load() device=%d.\n", i); - if (cfg_setup.device_list[i].tcpip.access_type == - ME_ACCESS_TYPE_LOCAL) { - list_for_each(pos, &me_device_list) { - o_device = - list_entry(pos, me_device_t, list); - o_device-> - me_device_query_info_device - (o_device, &o_vendor_id, - &o_device_id, &o_serial_no, - &o_bus_type, &o_bus_no, &o_dev_no, - &o_func_no, &o_plugged); - - if (cfg_setup.device_list[i].info. - hw_location.bus_type == - ME_BUS_TYPE_PCI) { - if (((o_vendor_id == - cfg_setup.device_list[i]. - info.vendor_id) - && (o_device_id == - cfg_setup. - device_list[i].info. - device_id) - && (o_serial_no == - cfg_setup. - device_list[i].info. - serial_no) - && (o_bus_type == - cfg_setup. - device_list[i].info. - hw_location.bus_type)) - || - ((o_vendor_id == - cfg_setup.device_list[i]. - info.vendor_id) - && (o_device_id == - cfg_setup. - device_list[i].info. - device_id) - && (o_bus_type == - cfg_setup. - device_list[i].info. - hw_location.bus_type) - && (o_bus_no == - cfg_setup. - device_list[i].info. - hw_location.pci.bus_no) - && (o_dev_no == - cfg_setup. - device_list[i].info. - hw_location.pci. - device_no) - && (o_func_no == - cfg_setup. - device_list[i].info. - hw_location.pci. - function_no))) { - list_move_tail(pos, - &new_list); - break; - } - } -/* - else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB) - { - if (((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) && - (o_device_id == cfg_setup.device_list[i].info.device_id) && - (o_serial_no == cfg_setup.device_list[i].info.serial_no) && - (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type)) || - ((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) && - (o_device_id == cfg_setup.device_list[i].info.device_id) && - (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type) && - (o_bus_no == cfg_setup.device_list[i].info.hw_location.usb.root_hub_no))) - { - list_move_tail(pos, &new_list); - break; - } - } -*/ - else { - PERROR("Wrong bus type: %d.\n", - cfg_setup.device_list[i]. - info.hw_location. - bus_type); - } - } - - if (pos == &me_device_list) { // Device is not already in the list - if (cfg_setup.device_list[i].info. - hw_location.bus_type == - ME_BUS_TYPE_PCI) { - n_device = - get_dummy_instance - (cfg_setup.device_list[i]. - info.vendor_id, - cfg_setup.device_list[i]. - info.device_id, - cfg_setup.device_list[i]. - info.serial_no, - cfg_setup.device_list[i]. - info.hw_location.bus_type, - cfg_setup.device_list[i]. - info.hw_location.pci. - bus_no, - cfg_setup.device_list[i]. - info.hw_location.pci. - device_no, - cfg_setup.device_list[i]. - info.hw_location.pci. - function_no); - - if (!n_device) { - PERROR - ("Can't get dummy instance.\n"); - kfree(cfg_setup. - device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, - &new_list); - } -/* - else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB) - { - n_device = get_dummy_instance( - cfg_setup.device_list[i].info.vendor_id, - cfg_setup.device_list[i].info.device_id, - cfg_setup.device_list[i].info.serial_no, - cfg_setup.device_list[i].info.hw_location.bus_type, - cfg_setup.device_list[i].info.hw_location.usb.root_hub_no, - 0, - 0); - - if (!n_device) - { - PERROR("Can't get dummy instance.\n"); - kfree(cfg_setup.device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, &new_list); - } -*/ - } - } else { - n_device = get_dummy_instance(0, - 0, 0, 0, 0, 0, 0); - - if (!n_device) { - PERROR("Can't get dummy instance.\n"); - kfree(cfg_setup.device_list); - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - return -EFAULT; - } - - list_add_tail(&n_device->list, &new_list); - } - } - - while (!list_empty(&me_device_list)) { - o_device = - list_entry(me_device_list.next, me_device_t, list); - o_device->me_device_query_info_device(o_device, - &o_vendor_id, - &o_device_id, - &o_serial_no, - &o_bus_type, - &o_bus_no, - &o_dev_no, - &o_func_no, - &o_plugged); - - if (o_plugged == ME_PLUGGED_IN) { - list_move_tail(me_device_list.next, &new_list); - } else { - list_del(me_device_list.next); - release_instance(o_device); - } - } - - // Move temporary new list to global driver list. - list_splice(&new_list, &me_device_list); - - karg_cfg_setup.errno = ME_ERRNO_SUCCESS; - } - - for (i = 0; i < cfg_setup.count; i++) { - - karg_cfg_setup.errno = - me_config_load_device(filep, &cfg_setup.device_list[i], i); - if (karg_cfg_setup.errno) { - PERROR("me_config_load_device(%d)=%d\n", i, - karg_cfg_setup.errno); - break; - } - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - up_write(&me_rwsem); - - err = copy_to_user(arg, &karg_cfg_setup, sizeof(me_config_load_t)); - - if (err) { - PERROR("Can't copy config list to user space.\n"); - kfree(cfg_setup.device_list); - return -EFAULT; - } - - kfree(cfg_setup.device_list); - return 0; -} - -static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_stream_start_t karg; - meIOStreamStart_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_start_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOStreamStart_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for start list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.start_list, - sizeof(meIOStreamStart_t) * karg.count); - - if (err) { - PERROR("Can't copy start list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - down_read(&me_rwsem); - k = 0; - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - list[i].iErrno = - device->me_device_io_stream_start(device, - filep, - list[i]. - iSubdevice, - list[i]. - iStartMode, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_start_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - kfree(list); - return -EFAULT; - } - - err = - copy_to_user(karg.start_list, list, - sizeof(meIOStreamStart_t) * karg.count); - - if (err) { - PERROR("Can't copy start list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_io_single(struct file *filep, me_io_single_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_single_t karg; - meIOSingle_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_single_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOSingle_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for single list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.single_list, - sizeof(meIOSingle_t) * karg.count); - - if (err) { - PERROR("Can't copy single list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - k = 0; - - down_read(&me_rwsem); - - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - if (list[i].iDir == ME_DIR_OUTPUT) { - list[i].iErrno = - device-> - me_device_io_single_write(device, - filep, - list[i]. - iSubdevice, - list[i]. - iChannel, - list[i]. - iValue, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } else if (list[i].iDir == ME_DIR_INPUT) { - list[i].iErrno = - device-> - me_device_io_single_read(device, - filep, - list[i]. - iSubdevice, - list[i]. - iChannel, - &list[i]. - iValue, - list[i]. - iTimeOut, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } else { - up_read(&me_rwsem); - PERROR - ("Invalid single direction specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DIR; - karg.errno = ME_ERRNO_INVALID_DIR; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_single_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - return -EFAULT; - } - - err = - copy_to_user(karg.single_list, list, - sizeof(meIOSingle_t) * karg.count); - - if (err) { - PERROR("Can't copy single list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg) -{ - int err; - int k = 0; - - struct list_head *pos; - me_device_t *device; - me_io_stream_config_t karg; - meIOStreamConfig_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_config_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - list = kmalloc(sizeof(meIOStreamConfig_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for config list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.config_list, - sizeof(meIOStreamConfig_t) * karg.count); - - if (err) { - PERROR("Can't copy config list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - karg.errno = ME_ERRNO_LOCKED; - } else { - me_count++; - spin_unlock(&me_lock); - - down_read(&me_rwsem); - - list_for_each(pos, &me_device_list) { - if (k == karg.device) { - device = list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - PERROR("Invalid device number specified.\n"); - karg.errno = ME_ERRNO_INVALID_DEVICE; - } else { - karg.errno = - device->me_device_io_stream_config(device, filep, - karg.subdevice, - list, karg.count, - &karg.trigger, - karg. - fifo_irq_threshold, - karg.flags); - } - - up_read(&me_rwsem); - - spin_lock(&me_lock); - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_config_t)); - - if (err) { - PERROR("Can't copy back to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -static int me_query_number_devices(struct file *filep, - me_query_number_devices_t *arg) -{ - int err; - me_query_number_devices_t karg; - - struct list_head *pos; - - PDEBUG("executed.\n"); - - karg.number = 0; - down_read(&me_rwsem); - list_for_each(pos, &me_device_list) { - karg.number++; - } - - up_read(&me_rwsem); - - karg.errno = ME_ERRNO_SUCCESS; - - err = copy_to_user(arg, &karg, sizeof(me_query_number_devices_t)); - - if (err) { - PERROR("Can't copy query back to user space.\n"); - return -EFAULT; - } - - return 0; -} - -static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg) -{ - int err; - int i, k; - - struct list_head *pos; - me_device_t *device; - me_io_stream_stop_t karg; - meIOStreamStop_t *list; - - PDEBUG("executed.\n"); - - err = copy_from_user(&karg, arg, sizeof(me_io_stream_stop_t)); - - if (err) { - PERROR("Can't copy arguments to kernel space.\n"); - return -EFAULT; - } - - karg.errno = ME_ERRNO_SUCCESS; - - list = kmalloc(sizeof(meIOStreamStop_t) * karg.count, GFP_KERNEL); - - if (!list) { - PERROR("Can't get buffer for stop list.\n"); - return -ENOMEM; - } - - err = - copy_from_user(list, karg.stop_list, - sizeof(meIOStreamStop_t) * karg.count); - - if (err) { - PERROR("Can't copy stop list to kernel space.\n"); - kfree(list); - return -EFAULT; - } - - spin_lock(&me_lock); - - if ((me_filep != NULL) && (me_filep != filep)) { - spin_unlock(&me_lock); - PERROR("Driver System is logged by another process.\n"); - - for (i = 0; i < karg.count; i++) { - list[i].iErrno = ME_ERRNO_LOCKED; - } - } else { - me_count++; - spin_unlock(&me_lock); - - for (i = 0; i < karg.count; i++) { - k = 0; - down_read(&me_rwsem); - list_for_each(pos, &me_device_list) { - if (k == list[i].iDevice) { - device = - list_entry(pos, me_device_t, list); - break; - } - - k++; - } - - if (pos == &me_device_list) { - up_read(&me_rwsem); - PERROR("Invalid device number specified.\n"); - list[i].iErrno = ME_ERRNO_INVALID_DEVICE; - karg.errno = ME_ERRNO_INVALID_DEVICE; - break; - } else { - list[i].iErrno = - device->me_device_io_stream_stop(device, - filep, - list[i]. - iSubdevice, - list[i]. - iStopMode, - list[i]. - iFlags); - - if (list[i].iErrno) { - up_read(&me_rwsem); - karg.errno = list[i].iErrno; - break; - } - } - - up_read(&me_rwsem); - } - - spin_lock(&me_lock); - - me_count--; - spin_unlock(&me_lock); - } - - err = copy_to_user(arg, &karg, sizeof(me_io_stream_stop_t)); - - if (err) { - PERROR("Can't copy arguments to user space.\n"); - return -EFAULT; - } - - err = - copy_to_user(karg.stop_list, list, - sizeof(meIOStreamStop_t) * karg.count); - - if (err) { - PERROR("Can't copy stop list to user space.\n"); - kfree(list); - return -EFAULT; - } - - kfree(list); - - return err; -} - -/* //me_probe_usb -static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id) -{ - //int err; - //me_usb_constructor_t *constructor = NULL; - me_device_t *n_device = NULL; - - PDEBUG("executed.\n"); - - switch (id->idProduct) - { - case USB_DEVICE_ID_MEPHISTO_S1: - if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){ - err = request_module(MEPHISTO_S1_NAME); - if(err){ - PERROR("Error while request for module %s.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){ - PERROR("Can't get %s driver module constructor.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - } - - if((n_device = (*constructor)(interface)) == NULL){ - symbol_put(mephisto_s1_constructor); - PERROR("Can't get device instance of %s driver module.\n", MEPHISTO_S1_NAME); - return -ENODEV; - } - - break; - - default: - PERROR("Invalid product id.\n"); - - return -EINVAL; - } - - return insert_to_device_list(n_device); -} -*/ - -/* //me_disconnect_usb -static void me_disconnect_usb(struct usb_interface *interface) -{ - - struct usb_device *device = interface_to_usbdev(interface); - int vendor_id = device->descriptor.idVendor; - int device_id = device->descriptor.idProduct; - int serial_no; - - sscanf(&device->serial[2], "%x", &serial_no); - - PDEBUG("executed.\n"); - - PINFO("Vendor id = 0x%08X\n", vendor_id); - PINFO("Device id = 0x%08X\n", device_id); - PINFO("Serial Number = 0x%08X\n", serial_no); - - replace_with_dummy(vendor_id, device_id, serial_no); -} -*/ - -static int me_ioctl(struct inode *inodep, - struct file *filep, unsigned int service, unsigned long arg) -{ - - PDEBUG("executed.\n"); - - if (_IOC_TYPE(service) != MEMAIN_MAGIC) { - PERROR("Invalid magic number.\n"); - return -ENOTTY; - } - - PDEBUG("service number: 0x%x.\n", service); - - switch (service) { - case ME_IO_IRQ_ENABLE: - return me_io_irq_start(filep, (me_io_irq_start_t *) arg); - - case ME_IO_IRQ_WAIT: - return me_io_irq_wait(filep, (me_io_irq_wait_t *) arg); - - case ME_IO_IRQ_DISABLE: - return me_io_irq_stop(filep, (me_io_irq_stop_t *) arg); - - case ME_IO_RESET_DEVICE: - return me_io_reset_device(filep, (me_io_reset_device_t *) arg); - - case ME_IO_RESET_SUBDEVICE: - return me_io_reset_subdevice(filep, - (me_io_reset_subdevice_t *) arg); - - case ME_IO_SINGLE_CONFIG: - return me_io_single_config(filep, - (me_io_single_config_t *) arg); - - case ME_IO_SINGLE: - return me_io_single(filep, (me_io_single_t *) arg); - - case ME_IO_STREAM_CONFIG: - return me_io_stream_config(filep, - (me_io_stream_config_t *) arg); - - case ME_IO_STREAM_NEW_VALUES: - return me_io_stream_new_values(filep, - (me_io_stream_new_values_t *) - arg); - - case ME_IO_STREAM_READ: - return me_io_stream_read(filep, (me_io_stream_read_t *) arg); - - case ME_IO_STREAM_START: - return me_io_stream_start(filep, (me_io_stream_start_t *) arg); - - case ME_IO_STREAM_STATUS: - return me_io_stream_status(filep, - (me_io_stream_status_t *) arg); - - case ME_IO_STREAM_STOP: - return me_io_stream_stop(filep, (me_io_stream_stop_t *) arg); - - case ME_IO_STREAM_WRITE: - return me_io_stream_write(filep, (me_io_stream_write_t *) arg); - - case ME_LOCK_DRIVER: - return me_lock_driver(filep, (me_lock_driver_t *) arg); - - case ME_LOCK_DEVICE: - return me_lock_device(filep, (me_lock_device_t *) arg); - - case ME_LOCK_SUBDEVICE: - return me_lock_subdevice(filep, (me_lock_subdevice_t *) arg); - - case ME_QUERY_INFO_DEVICE: - return me_query_info_device(filep, - (me_query_info_device_t *) arg); - - case ME_QUERY_DESCRIPTION_DEVICE: - return me_query_description_device(filep, - (me_query_description_device_t - *) arg); - - case ME_QUERY_NAME_DEVICE: - return me_query_name_device(filep, - (me_query_name_device_t *) arg); - - case ME_QUERY_NAME_DEVICE_DRIVER: - return me_query_name_device_driver(filep, - (me_query_name_device_driver_t - *) arg); - - case ME_QUERY_NUMBER_DEVICES: - return me_query_number_devices(filep, - (me_query_number_devices_t *) - arg); - - case ME_QUERY_NUMBER_SUBDEVICES: - return me_query_number_subdevices(filep, - (me_query_number_subdevices_t - *) arg); - - case ME_QUERY_NUMBER_CHANNELS: - return me_query_number_channels(filep, - (me_query_number_channels_t *) - arg); - - case ME_QUERY_NUMBER_RANGES: - return me_query_number_ranges(filep, - (me_query_number_ranges_t *) arg); - - case ME_QUERY_RANGE_BY_MIN_MAX: - return me_query_range_by_min_max(filep, - (me_query_range_by_min_max_t *) - arg); - - case ME_QUERY_RANGE_INFO: - return me_query_range_info(filep, - (me_query_range_info_t *) arg); - - case ME_QUERY_SUBDEVICE_BY_TYPE: - return me_query_subdevice_by_type(filep, - (me_query_subdevice_by_type_t - *) arg); - - case ME_QUERY_SUBDEVICE_TYPE: - return me_query_subdevice_type(filep, - (me_query_subdevice_type_t *) - arg); - - case ME_QUERY_SUBDEVICE_CAPS: - return me_query_subdevice_caps(filep, - (me_query_subdevice_caps_t *) - arg); - - case ME_QUERY_SUBDEVICE_CAPS_ARGS: - return me_query_subdevice_caps_args(filep, - (me_query_subdevice_caps_args_t - *) arg); - - case ME_QUERY_TIMER: - return me_query_timer(filep, (me_query_timer_t *) arg); - - case ME_QUERY_VERSION_MAIN_DRIVER: - return me_query_version_main_driver(filep, - (me_query_version_main_driver_t - *) arg); - - case ME_QUERY_VERSION_DEVICE_DRIVER: - return me_query_version_device_driver(filep, - (me_query_version_device_driver_t - *) arg); - - case ME_CONFIG_LOAD: - return me_config_load(filep, (me_config_load_t *) arg); - } - - PERROR("Invalid ioctl number.\n"); - return -ENOTTY; -} - -static struct miscdevice me_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = MEMAIN_NAME, - .fops = &me_file_operations, -}; - -// Init and exit of module. -static int memain_init(void) -{ - int result = 0; - - PDEBUG("executed.\n"); - - // Register pci driver. This will return 0 if the PCI subsystem is not available. - result = pci_register_driver(&me_pci_driver); - - if (result < 0) { - PERROR("Can't register pci driver.\n"); - goto INIT_ERROR_1; - } - -/* - // Register usb driver. This will return -ENODEV if no USB subsystem is available. - result = usb_register(&me_usb_driver); - - if (result) - { - if (result == -ENODEV) - { - PERROR("No USB subsystem available.\n"); - } - else - { - PERROR("Can't register usb driver.\n"); - goto INIT_ERROR_2; - } - } -*/ - result = misc_register(&me_miscdev); - if (result < 0) { - printk(KERN_ERR MEMAIN_NAME ": can't register misc device\n"); - goto INIT_ERROR_3; - } - - return 0; - - INIT_ERROR_3: -// usb_deregister(&me_usb_driver); - -//INIT_ERROR_2: - pci_unregister_driver(&me_pci_driver); - clear_device_list(); - - INIT_ERROR_1: - return result; -} - -static void __exit memain_exit(void) -{ - PDEBUG("executed.\n"); - - misc_deregister(&me_miscdev); - pci_unregister_driver(&me_pci_driver); -// usb_deregister(&me_usb_driver); - clear_device_list(); -} - -module_init(memain_init); -module_exit(memain_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR - ("Guenter Gebhardt & Krzysztof Gantzke "); -MODULE_DESCRIPTION("Central module for Meilhaus Driver System."); -MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards."); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/memain.h b/drivers/staging/meilhaus/memain.h deleted file mode 100644 index 48f83679379..00000000000 --- a/drivers/staging/meilhaus/memain.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : memain.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _MEMAIN_H_ -#define _MEMAIN_H_ - -#include "meinternal.h" - -#include "meids.h" -#include "medebug.h" - -#include "medevice.h" -/*#include "me1000_device.h" -#include "me1400_device.h" -#include "me1600_device.h"*/ -#include "me4600_device.h" -/*#include "me6000_device.h" -#include "me0600_device.h" -#include "me8100_device.h" -#include "me8200_device.h" -#include "me0900_device.h"*/ -#include "medummy.h" - -#ifdef __KERNEL__ - -/*============================================================================= - Templates - ===========================================================================*/ - -#define ME_LOCK_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \ -static int CALL(struct file *filep, TYPE *arg){ \ - int err = 0; \ - int k = 0; \ - struct list_head *pos; \ - me_device_t *device; \ - TYPE karg; \ - \ - PDEBUG("executed.\n"); \ - \ - err = copy_from_user(&karg, arg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments to kernel space\n"); \ - return -EFAULT; \ - } \ - \ - down_read(&me_rwsem); \ - \ - list_for_each(pos, &me_device_list){ \ - if(k == karg.device){ \ - device = list_entry(pos, me_device_t, list); \ - break; \ - } \ - k++; \ - } \ - \ - if(pos == &me_device_list){ \ - PERROR("Invalid device number specified\n"); \ - karg.errno = ME_ERRNO_INVALID_DEVICE; \ - } \ - else{ \ - spin_lock(&me_lock); \ - if((me_filep != NULL) && (me_filep != filep)){ \ - spin_unlock(&me_lock); \ - PERROR("Resource is locked by another process\n"); \ - if(karg.lock == ME_LOCK_SET) \ - karg.errno = ME_ERRNO_LOCKED; \ - else if(karg.lock == ME_LOCK_RELEASE) \ - karg.errno = ME_ERRNO_SUCCESS; \ - else{ \ - PERROR("Invalid lock specified\n"); \ - karg.errno = ME_ERRNO_INVALID_LOCK; \ - }\ - } \ - else { \ - me_count++; \ - spin_unlock(&me_lock); \ - \ - karg.errno = device->DEV_CALL ARGS; \ - \ - spin_lock(&me_lock); \ - me_count--; \ - spin_unlock(&me_lock); \ - } \ - } \ - \ - up_read(&me_rwsem); \ - \ - err = copy_to_user(arg, &karg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments back to user space\n"); \ - return -EFAULT; \ - } \ - \ - return ME_ERRNO_SUCCESS; \ -} - -#define ME_IO_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \ -static int CALL(struct file *filep, TYPE *arg){ \ - int err = 0; \ - int k = 0; \ - struct list_head *pos; \ - me_device_t *device; \ - TYPE karg; \ - \ - PDEBUG("executed.\n"); \ - \ - err = copy_from_user(&karg, arg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments to kernel space\n"); \ - return -EFAULT; \ - } \ - \ - down_read(&me_rwsem); \ - \ - list_for_each(pos, &me_device_list){ \ - if(k == karg.device){ \ - device = list_entry(pos, me_device_t, list); \ - break; \ - } \ - k++; \ - } \ - \ - if(pos == &me_device_list){ \ - PERROR("Invalid device number specified\n"); \ - karg.errno = ME_ERRNO_INVALID_DEVICE; \ - } \ - else{ \ - spin_lock(&me_lock); \ - if((me_filep != NULL) && (me_filep != filep)){ \ - spin_unlock(&me_lock); \ - PERROR("Resource is locked by another process\n"); \ - karg.errno = ME_ERRNO_LOCKED; \ - } \ - else { \ - me_count++; \ - spin_unlock(&me_lock); \ - \ - karg.errno = device->DEV_CALL ARGS; \ - \ - spin_lock(&me_lock); \ - me_count--; \ - spin_unlock(&me_lock); \ - } \ - } \ - \ - up_read(&me_rwsem); \ - \ - err = copy_to_user(arg, &karg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments back to user space\n"); \ - return -EFAULT; \ - } \ - \ - return ME_ERRNO_SUCCESS; \ -} - -#define ME_QUERY_MULTIPLEX_STR_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \ -static int CALL(struct file *filep, TYPE *arg){ \ - int err = 0; \ - int k = 0; \ - struct list_head *pos; \ - me_device_t *device; \ - char *msg = NULL; \ - TYPE karg; \ - \ - PDEBUG("executed.\n"); \ - \ - err = copy_from_user(&karg, arg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments to kernel space\n"); \ - return -EFAULT; \ - } \ - \ - down_read(&me_rwsem); \ - \ - list_for_each(pos, &me_device_list){ \ - if(k == karg.device){ \ - device = list_entry(pos, me_device_t, list); \ - break; \ - } \ - k++; \ - } \ - \ - if(pos == &me_device_list){ \ - PERROR("Invalid device number specified\n"); \ - karg.errno = ME_ERRNO_INVALID_DEVICE; \ - } \ - else{ \ - karg.errno = device->DEV_CALL ARGS; \ - if(!karg.errno){ \ - if((strlen(msg) + 1) > karg.count){ \ - PERROR("User buffer for device name is to little\n"); \ - karg.errno = ME_ERRNO_USER_BUFFER_SIZE; \ - } \ - else{ \ - err = copy_to_user(karg.name, msg, strlen(msg) + 1); \ - if(err){ \ - PERROR("Can't copy device name to user space\n"); \ - return -EFAULT; \ - } \ - } \ - } \ - } \ - \ - up_read(&me_rwsem); \ - \ - err = copy_to_user(arg, &karg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy query back to user space\n"); \ - return -EFAULT; \ - } \ - \ - return ME_ERRNO_SUCCESS; \ -} - -#define ME_QUERY_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS) \ -static int CALL(struct file *filep, TYPE *arg){ \ - int err = 0; \ - int k = 0; \ - struct list_head *pos; \ - me_device_t *device; \ - TYPE karg; \ - \ - PDEBUG("executed.\n"); \ - \ - err = copy_from_user(&karg, arg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments from user space\n"); \ - return -EFAULT; \ - } \ - \ - down_read(&me_rwsem); \ - \ - list_for_each(pos, &me_device_list){ \ - if(k == karg.device){ \ - device = list_entry(pos, me_device_t, list); \ - break; \ - } \ - k++; \ - } \ - \ - if(pos == &me_device_list){ \ - PERROR("Invalid device number specified\n"); \ - karg.errno = ME_ERRNO_INVALID_DEVICE; \ - } \ - else{ \ - karg.errno = device->DEV_CALL ARGS; \ - } \ - \ - up_read(&me_rwsem); \ - \ - err = copy_to_user(arg, &karg, sizeof(TYPE)); \ - if(err){ \ - PERROR("Can't copy arguments to user space\n"); \ - return -EFAULT; \ - } \ - \ - return ME_ERRNO_SUCCESS; \ -} - -#endif //__KERNEL__ -#endif diff --git a/drivers/staging/meilhaus/meplx_reg.h b/drivers/staging/meilhaus/meplx_reg.h deleted file mode 100644 index 1868614dc23..00000000000 --- a/drivers/staging/meilhaus/meplx_reg.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file meplx_reg.h - * - * @brief PLX 9052 PCI bridge register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MEPLX_REG_H_ -#define _MEPLX_REG_H_ - -#ifdef __KERNEL__ - -#define PLX_INTCSR 0x4C /**< Interrupt control and status register. */ -#define PLX_INTCSR_LOCAL_INT1_EN 0x01 /**< If set, local interrupt 1 is enabled (r/w). */ -#define PLX_INTCSR_LOCAL_INT1_POL 0x02 /**< If set, local interrupt 1 polarity is active high (r/w). */ -#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 /**< If set, local interrupt 1 is active (r/_). */ -#define PLX_INTCSR_LOCAL_INT2_EN 0x08 /**< If set, local interrupt 2 is enabled (r/w). */ -#define PLX_INTCSR_LOCAL_INT2_POL 0x10 /**< If set, local interrupt 2 polarity is active high (r/w). */ -#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 /**< If set, local interrupt 2 is active (r/_). */ -#define PLX_INTCSR_PCI_INT_EN 0x40 /**< If set, PCI interrupt is enabled (r/w). */ -#define PLX_INTCSR_SOFT_INT 0x80 /**< If set, a software interrupt is generated (r/w). */ - -#define PLX_ICR 0x50 /**< Initialization control register. */ -#define PLX_ICR_BIT_EEPROM_CLOCK_SET 0x01000000 -#define PLX_ICR_BIT_EEPROM_CHIP_SELECT 0x02000000 -#define PLX_ICR_BIT_EEPROM_WRITE 0x04000000 -#define PLX_ICR_BIT_EEPROM_READ 0x08000000 -#define PLX_ICR_BIT_EEPROM_VALID 0x10000000 - -#define PLX_ICR_MASK_EEPROM 0x1F000000 -#define EEPROM_DELAY 1 - -#endif -#endif diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c deleted file mode 100644 index ce49114df55..00000000000 --- a/drivers/staging/meilhaus/meslist.c +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file me_slist.c - * - * @brief Implements the subdevice list class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "meerror.h" -#include "medefines.h" - -#include "meslist.h" -#include "medebug.h" - -int me_slist_query_number_subdevices(struct me_slist *slist, int *number) -{ - PDEBUG_LOCKS("called.\n"); - *number = slist->n; - return ME_ERRNO_SUCCESS; -} - -unsigned int me_slist_get_number_subdevices(struct me_slist *slist) -{ - PDEBUG_LOCKS("called.\n"); - return slist->n; -} - -me_subdevice_t *me_slist_get_subdevice(struct me_slist * slist, - unsigned int index) -{ - - struct list_head *pos; - me_subdevice_t *subdevice = NULL; - unsigned int i = 0; - - PDEBUG_LOCKS("called.\n"); - - if (index >= slist->n) { - PERROR("Index out of range.\n"); - return NULL; - } - - list_for_each(pos, &slist->head) { - if (i == index) { - subdevice = list_entry(pos, me_subdevice_t, list); - break; - } - - ++i; - } - - return subdevice; -} - -int me_slist_get_subdevice_by_type(struct me_slist *slist, - unsigned int start_subdevice, - int type, int subtype, int *subdevice) -{ - me_subdevice_t *pos; - int s_type, s_subtype; - unsigned int index = 0; - - PDEBUG_LOCKS("called.\n"); - - if (start_subdevice >= slist->n) { - PERROR("Start index out of range.\n"); - return ME_ERRNO_NOMORE_SUBDEVICE_TYPE; - } - - list_for_each_entry(pos, &slist->head, list) { - if (index < start_subdevice) { // Go forward to start subdevice. - ++index; - continue; - } - - pos->me_subdevice_query_subdevice_type(pos, - &s_type, &s_subtype); - - if (subtype == ME_SUBTYPE_ANY) { - if (s_type == type) - break; - } else { - if ((s_type == type) && (s_subtype == subtype)) - break; - } - - ++index; - } - - if (index >= slist->n) { - return ME_ERRNO_NOMORE_SUBDEVICE_TYPE; - } - - *subdevice = index; - - return ME_ERRNO_SUCCESS; -} - -void me_slist_add_subdevice_tail(struct me_slist *slist, - me_subdevice_t *subdevice) -{ - PDEBUG_LOCKS("called.\n"); - - list_add_tail(&subdevice->list, &slist->head); - ++slist->n; -} - -me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist) -{ - - struct list_head *last; - me_subdevice_t *subdevice; - - PDEBUG_LOCKS("called.\n"); - - if (list_empty(&slist->head)) - return NULL; - - last = slist->head.prev; - - subdevice = list_entry(last, me_subdevice_t, list); - - list_del(last); - - --slist->n; - - return subdevice; -} - -int me_slist_init(me_slist_t *slist) -{ - PDEBUG_LOCKS("called.\n"); - - INIT_LIST_HEAD(&slist->head); - slist->n = 0; - return 0; -} - -void me_slist_deinit(me_slist_t *slist) -{ - - struct list_head *s; - me_subdevice_t *subdevice; - - PDEBUG_LOCKS("called.\n"); - - while (!list_empty(&slist->head)) { - s = slist->head.next; - list_del(s); - subdevice = list_entry(s, me_subdevice_t, list); - subdevice->me_subdevice_destructor(subdevice); - } - - slist->n = 0; -} diff --git a/drivers/staging/meilhaus/meslist.h b/drivers/staging/meilhaus/meslist.h deleted file mode 100644 index d26c89693d2..00000000000 --- a/drivers/staging/meilhaus/meslist.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file me_slist.h - * - * @brief Provides the subdevice list class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _ME_SLIST_H_ -#define _ME_SLIST_H_ - -#include - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The subdevice list container. - */ -typedef struct me_slist { - struct list_head head; /**< The head of the internal list. */ - unsigned int n; /**< The number of subdevices in the list. */ -} me_slist_t; - -/** - * @brief Queries the number of subdevices currently inside the list. - * - * @param slist The subdevice list to query. - * @param[out] number The number of subdevices of the device. - * - * @return ME-iDS error code. - */ -int me_slist_query_number_subdevices(struct me_slist *slist, int *number); - -/** - * @brief Returns the number of subdevices currently inside the list. - * - * @param slist The subdevice list to query. - * - * @return The number of subdevices in the list. - */ -unsigned int me_slist_get_number_subdevices(struct me_slist *slist); - -/** - * @brief Get a subdevice by index. - * - * @param slist The subdevice list to query. - * @param index The index of the subdevice to get in the list. - * - * @return The subdevice at index if available.\n - * NULL if the index is out of range. - */ -me_subdevice_t *me_slist_get_subdevice(struct me_slist *slist, - unsigned int index); - -/** - * @brief Get a subdevice index by type and subtype. - * - * @param slist The subdevice list to query. - * @param start_subdevice The subdevice index at which the start shall begin. - * @param type The type of the subdevice to query. - * @param subtype The subtype of the subdevice to query. - * @param[out] subdevice On success this parameter returns the index of the subdevice matching the requested type. - * - * @return ME_ERRNO_SUCCESS on success. - */ -int me_slist_get_subdevice_by_type(struct me_slist *slist, - unsigned int start_subdevice, - int type, int subtype, int *subdevice); - -/** - * @brief Adds a subdevice to the tail of the list. - * - * @param slist The subdevice list to add a subdevice to. - * @param subdevice The subdevice to add to the list. - */ -void me_slist_add_subdevice_tail(struct me_slist *slist, - me_subdevice_t * subdevice); - -/** - * @brief Removes a subdevice from the tail of the list. - * - * @param slist The subdevice list. - * - * @return Pointer to the removed subdeivce.\n - * NULL in cases where the list was empty. - */ -me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist); - -/** - * @brief Initializes a subdevice list structure. - * - * @param lock The subdevice list structure to initialize. - * @return 0 on success. - */ -int me_slist_init(me_slist_t * slist); - -/** - * @brief Deinitializes a subdevice list structure and destructs every subdevice in it. - * - * @param slist The subdevice list structure to deinitialize. - * @return 0 on success. - */ -void me_slist_deinit(me_slist_t * slist); - -#endif -#endif diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c deleted file mode 100644 index abcdb4a2eba..00000000000 --- a/drivers/staging/meilhaus/meslock.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file meslock.c - * - * @brief Implements the subdevice lock class. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include "medefines.h" -#include "meerror.h" - -#include "medebug.h" -#include "meslock.h" - -int me_slock_enter(struct me_slock *slock, struct file *filep) -{ - PDEBUG_LOCKS("executed.\n"); - - spin_lock(&slock->spin_lock); - - if ((slock->filep) != NULL && (slock->filep != filep)) { - PERROR("Subdevice is locked by another process.\n"); - spin_unlock(&slock->spin_lock); - return ME_ERRNO_LOCKED; - } - - slock->count++; - - spin_unlock(&slock->spin_lock); - - return ME_ERRNO_SUCCESS; -} - -int me_slock_exit(struct me_slock *slock, struct file *filep) -{ - PDEBUG_LOCKS("executed.\n"); - - spin_lock(&slock->spin_lock); - slock->count--; - spin_unlock(&slock->spin_lock); - - return ME_ERRNO_SUCCESS; -} - -int me_slock_lock(struct me_slock *slock, struct file *filep, int lock) -{ - PDEBUG_LOCKS("executed.\n"); - - switch (lock) { - - case ME_LOCK_RELEASE: - spin_lock(&slock->spin_lock); - - if (slock->filep == filep) - slock->filep = NULL; - - spin_unlock(&slock->spin_lock); - - break; - - case ME_LOCK_SET: - spin_lock(&slock->spin_lock); - - if (slock->count) { - spin_unlock(&slock->spin_lock); - PERROR("Subdevice is used by another process.\n"); - return ME_ERRNO_USED; - } else if (slock->filep == NULL) - slock->filep = filep; - else if (slock->filep != filep) { - spin_unlock(&slock->spin_lock); - PERROR("Subdevice is locked by another process.\n"); - return ME_ERRNO_LOCKED; - } - - spin_unlock(&slock->spin_lock); - - break; - - case ME_LOCK_CHECK: - spin_lock(&slock->spin_lock); - - if (slock->count) { - spin_unlock(&slock->spin_lock); - return ME_ERRNO_USED; - } else if ((slock->filep != NULL) && (slock->filep != filep)) { - spin_unlock(&slock->spin_lock); - return ME_ERRNO_LOCKED; - } - - spin_unlock(&slock->spin_lock); - - break; - - default: - break; - } - - return ME_ERRNO_SUCCESS; -} - -void me_slock_deinit(struct me_slock *slock) -{ - PDEBUG_LOCKS("executed.\n"); -} - -int me_slock_init(me_slock_t *slock) -{ - PDEBUG_LOCKS("executed.\n"); - - slock->filep = NULL; - slock->count = 0; - spin_lock_init(&slock->spin_lock); - - return 0; -} diff --git a/drivers/staging/meilhaus/meslock.h b/drivers/staging/meilhaus/meslock.h deleted file mode 100644 index f42b25c3f62..00000000000 --- a/drivers/staging/meilhaus/meslock.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file meslock.h - * - * @brief Provides the subdevice lock class. - * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _MESLOCK_H_ -#define _MESLOCK_H_ - -#include - -#ifdef __KERNEL__ - -/** - * @brief The subdevice lock class. - */ -typedef struct me_slock { - struct file *filep; /**< Pointer to file structure holding the subdevice. */ - int count; /**< Number of tasks which are inside the subdevice. */ - spinlock_t spin_lock; /**< Spin lock protecting the attributes from concurrent access. */ -} me_slock_t; - -/** - * @brief Tries to enter a subdevice. - * - * @param slock The subdevice lock instance. - * @param filep The file structure identifying the calling process. - * - * @return 0 on success. - */ -int me_slock_enter(struct me_slock *slock, struct file *filep); - -/** - * @brief Exits a subdevice. - * - * @param slock The subdevice lock instance. - * @param filep The file structure identifying the calling process. - * - * @return 0 on success. - */ -int me_slock_exit(struct me_slock *slock, struct file *filep); - -/** - * @brief Tries to perform a locking action on a subdevice. - * - * @param slock The subdevice lock instance. - * @param filep The file structure identifying the calling process. - * @param The action to be done. - * - * @return 0 on success. - */ -int me_slock_lock(struct me_slock *slock, struct file *filep, int lock); - -/** - * @brief Initializes a lock structure. - * - * @param slock The lock structure to initialize. - * @return 0 on success. - */ -int me_slock_init(me_slock_t * slock); - -/** - * @brief Deinitializes a lock structure. - * - * @param slock The lock structure to deinitialize. - * @return 0 on success. - */ -void me_slock_deinit(me_slock_t * slock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c deleted file mode 100644 index b2e956726b5..00000000000 --- a/drivers/staging/meilhaus/mesubdevice.c +++ /dev/null @@ -1,317 +0,0 @@ -/** - * @file mesubdevice.c - * - * @brief Subdevice base class implemention. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#include - -#include "medefines.h" -#include "meerror.h" - -#include "medebug.h" -#include "mesubdevice.h" - -static int me_subdevice_io_irq_start(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_irq_wait(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *irq_count, - int *value, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_irq_stop(struct me_subdevice *subdevice, - struct file *filep, int channel, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_reset_subdevice(struct me_subdevice *subdevice, - struct file *filep, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_single_config(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, - int trig_edge, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_single_read(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int *value, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_single_write(struct me_subdevice *subdevice, - struct file *filep, - int channel, - int value, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_config(struct me_subdevice *subdevice, - struct file *filep, - meIOStreamConfig_t *config_list, - int count, - meIOStreamTrigger_t *trigger, - int fifo_irq_threshold, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_new_values(struct me_subdevice *subdevice, - struct file *filep, - int time_out, - int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_read(struct me_subdevice *subdevice, - struct file *filep, - int read_mode, - int *values, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_start(struct me_subdevice *subdevice, - struct file *filep, - int start_mode, int time_out, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_status(struct me_subdevice *subdevice, - struct file *filep, - int wait, - int *status, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_stop(struct me_subdevice *subdevice, - struct file *filep, - int stop_mode, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_io_stream_write(struct me_subdevice *subdevice, - struct file *filep, - int write_mode, - int *values, int *count, int flags) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_lock_subdevice(me_subdevice_t *subdevice, - struct file *filep, int lock, int flags) -{ - PDEBUG("executed.\n"); - return me_slock_lock(&subdevice->lock, filep, lock); -} - -static int me_subdevice_query_number_channels(struct me_subdevice *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_number_ranges(struct me_subdevice *subdevice, - int unit, int *count) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_range_by_min_max(struct me_subdevice *subdevice, - int unit, - int *min, - int *max, - int *maxdata, int *range) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_range_info(struct me_subdevice *subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_subdevice_type(struct me_subdevice *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_subdevice_caps(struct me_subdevice *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -static int me_subdevice_query_subdevice_caps_args(struct me_subdevice - *subdevice, int cap, - int *args, int count) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_query_timer(struct me_subdevice *subdevice, - int timer, - int *base_frequency, - long long *min_ticks, long long *max_ticks) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_NOT_SUPPORTED; -} - -static int me_subdevice_config_load(struct me_subdevice *subdevice, - me_cfg_device_entry_t *config) -{ - PDEBUG("executed.\n"); - return ME_ERRNO_SUCCESS; -} - -static void me_subdevice_destructor(struct me_subdevice *subdevice) -{ - PDEBUG("executed.\n"); - me_subdevice_deinit(subdevice); - kfree(subdevice); -} - -int me_subdevice_init(me_subdevice_t *subdevice) -{ - int err; - - PDEBUG("executed.\n"); - - /* Init list head */ - INIT_LIST_HEAD(&subdevice->list); - - /* Initialize the subdevice lock instance */ - - err = me_slock_init(&subdevice->lock); - - if (err) { - PERROR("Cannot initialize subdevice lock instance.\n"); - return 1; - } - - /* Subdevice base class methods */ - subdevice->me_subdevice_io_irq_start = me_subdevice_io_irq_start; - subdevice->me_subdevice_io_irq_wait = me_subdevice_io_irq_wait; - subdevice->me_subdevice_io_irq_stop = me_subdevice_io_irq_stop; - subdevice->me_subdevice_io_reset_subdevice = - me_subdevice_io_reset_subdevice; - subdevice->me_subdevice_io_single_config = - me_subdevice_io_single_config; - subdevice->me_subdevice_io_single_read = me_subdevice_io_single_read; - subdevice->me_subdevice_io_single_write = me_subdevice_io_single_write; - subdevice->me_subdevice_io_stream_config = - me_subdevice_io_stream_config; - subdevice->me_subdevice_io_stream_new_values = - me_subdevice_io_stream_new_values; - subdevice->me_subdevice_io_stream_read = me_subdevice_io_stream_read; - subdevice->me_subdevice_io_stream_start = me_subdevice_io_stream_start; - subdevice->me_subdevice_io_stream_status = - me_subdevice_io_stream_status; - subdevice->me_subdevice_io_stream_stop = me_subdevice_io_stream_stop; - subdevice->me_subdevice_io_stream_write = me_subdevice_io_stream_write; - subdevice->me_subdevice_lock_subdevice = me_subdevice_lock_subdevice; - subdevice->me_subdevice_query_number_channels = - me_subdevice_query_number_channels; - subdevice->me_subdevice_query_number_ranges = - me_subdevice_query_number_ranges; - subdevice->me_subdevice_query_range_by_min_max = - me_subdevice_query_range_by_min_max; - subdevice->me_subdevice_query_range_info = - me_subdevice_query_range_info; - subdevice->me_subdevice_query_subdevice_type = - me_subdevice_query_subdevice_type; - subdevice->me_subdevice_query_subdevice_caps = - me_subdevice_query_subdevice_caps; - subdevice->me_subdevice_query_subdevice_caps_args = - me_subdevice_query_subdevice_caps_args; - subdevice->me_subdevice_query_timer = me_subdevice_query_timer; - subdevice->me_subdevice_config_load = me_subdevice_config_load; - subdevice->me_subdevice_destructor = me_subdevice_destructor; - - return 0; -} - -void me_subdevice_deinit(me_subdevice_t *subdevice) -{ - PDEBUG("executed.\n"); - me_subdevice_io_reset_subdevice(subdevice, NULL, - ME_IO_RESET_SUBDEVICE_NO_FLAGS); - me_slock_deinit(&subdevice->lock); -} diff --git a/drivers/staging/meilhaus/mesubdevice.h b/drivers/staging/meilhaus/mesubdevice.h deleted file mode 100644 index 19ec2b5d96f..00000000000 --- a/drivers/staging/meilhaus/mesubdevice.h +++ /dev/null @@ -1,197 +0,0 @@ -/** - * @file mesubdevice.h - * - * @brief Provides the subdevice base class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -#ifndef _MESUBDEVICE_H_ -#define _MESUBDEVICE_H_ - -#include - -#include "metypes.h" -#include "meioctl.h" -#include "meslock.h" - -# include - -#ifdef __KERNEL__ - -/** - * @brief Macro used to enter a subdevice. - */ -#define ME_SUBDEVICE_ENTER \ -{ \ - int err; \ - err = me_slock_enter(&instance->base.lock, filep); \ - if(err){ \ - PERROR("Cannot enter subdevice.\n"); \ - return err; \ - } \ -} - -/** - * @brief Macro used to exit a subdevice. - */ -#define ME_SUBDEVICE_EXIT \ -{\ - int err; \ - err = me_slock_exit(&instance->base.lock, filep); \ - if(err){ \ - PERROR("Cannot exit subdevice.\n"); \ - return err; \ - } \ -} - -/** - * @brief The subdevice base class. - */ -typedef struct me_subdevice { - /* Attributes */ - struct list_head list; /**< Enables the subdevice to be added to a dynamic list. */ - me_slock_t lock; /**< Used by user application in order to lock the subdevice for exclusive usage. */ - - /* Methods */ - int (*me_subdevice_io_irq_start) (struct me_subdevice * subdevice, - struct file * filep, - int channel, - int irq_source, - int irq_edge, int irq_arg, int flags); - - int (*me_subdevice_io_irq_wait) (struct me_subdevice * subdevice, - struct file * filep, - int channel, - int *irq_count, - int *value, int time_out, int flags); - - int (*me_subdevice_io_irq_stop) (struct me_subdevice * subdevice, - struct file * filep, - int channel, int flags); - - int (*me_subdevice_io_reset_subdevice) (struct me_subdevice * subdevice, - struct file * filep, int flags); - - int (*me_subdevice_io_single_config) (struct me_subdevice * subdevice, - struct file * filep, - int channel, - int single_config, - int ref, - int trig_chan, - int trig_type, - int trig_edge, int flags); - - int (*me_subdevice_io_single_read) (struct me_subdevice * subdevice, - struct file * filep, - int channel, - int *value, - int time_out, int flags); - - int (*me_subdevice_io_single_write) (struct me_subdevice * subdevice, - struct file * filep, - int channel, - int value, - int time_out, int flags); - - int (*me_subdevice_io_stream_config) (struct me_subdevice * subdevice, - struct file * filep, - meIOStreamConfig_t * config_list, - int count, - meIOStreamTrigger_t * trigger, - int fifo_irq_threshold, - int flags); - - int (*me_subdevice_io_stream_new_values) (struct me_subdevice * - subdevice, - struct file * filep, - int time_out, int *count, - int flags); - - int (*me_subdevice_io_stream_read) (struct me_subdevice * subdevice, - struct file * filep, - int read_mode, - int *values, int *count, int flags); - - int (*me_subdevice_io_stream_start) (struct me_subdevice * subdevice, - struct file * filep, - int start_mode, - int time_out, int flags); - - int (*me_subdevice_io_stream_status) (struct me_subdevice * subdevice, - struct file * filep, - int wait, - int *status, - int *count, int flags); - - int (*me_subdevice_io_stream_stop) (struct me_subdevice * subdevice, - struct file * filep, - int stop_mode, int flags); - - int (*me_subdevice_io_stream_write) (struct me_subdevice * subdevice, - struct file * filep, - int write_mode, - int *values, - int *count, int flags); - - int (*me_subdevice_lock_subdevice) (struct me_subdevice * subdevice, - struct file * filep, - int lock, int flags); - - int (*me_subdevice_query_number_channels) (struct me_subdevice * - subdevice, int *number); - - int (*me_subdevice_query_number_ranges) (struct me_subdevice * - subdevice, int unit, - int *count); - - int (*me_subdevice_query_range_by_min_max) (struct me_subdevice * - subdevice, int unit, - int *min, int *max, - int *maxdata, int *range); - - int (*me_subdevice_query_range_info) (struct me_subdevice * subdevice, - int range, - int *unit, - int *min, int *max, int *maxdata); - - int (*me_subdevice_query_subdevice_type) (struct me_subdevice * - subdevice, int *type, - int *subtype); - - int (*me_subdevice_query_subdevice_caps) (struct me_subdevice * - subdevice, int *caps); - - int (*me_subdevice_query_subdevice_caps_args) (struct me_subdevice * - subdevice, int cap, - int *args, int count); - - int (*me_subdevice_query_timer) (struct me_subdevice * subdevice, - int timer, - int *base_frequency, - long long *min_ticks, - long long *max_ticks); - - int (*me_subdevice_config_load) (struct me_subdevice * subdevice, - me_cfg_device_entry_t * config); - - void (*me_subdevice_destructor) (struct me_subdevice * subdevice); -} me_subdevice_t; - -/** - * @brief Initializes a subdevice structure. - * - * @param subdevice The subdevice structure to initialize. - * @return 0 on success. - */ -int me_subdevice_init(me_subdevice_t * subdevice); - -/** - * @brief Deinitializes a subdevice structure. - * - * @param subdevice The subdevice structure to initialize. - */ -void me_subdevice_deinit(me_subdevice_t * subdevice); - -#endif -#endif diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c deleted file mode 100644 index bdaf6df7277..00000000000 --- a/drivers/staging/meilhaus/metempl_device.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file metempl_device.c - * - * @brief template device class implementation. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -#ifndef MODULE -# define MODULE -#endif - -#include - -#include -#include - -#include -#include "meerror.h" -#include "mecommon.h" -#include "meinternal.h" - -#include "medebug.h" -#include "medevice.h" -#include "metempl_device.h" -#include "mesubdevice.h" -#include "metempl_sub.h" - -me_device_t *metempl_pci_constructor(struct pci_dev *pci_device) -{ - metempl_device_t *metempl_device; - me_subdevice_t *subdevice; - unsigned int version_idx; - int err; - int i; - - PDEBUG("executed.\n"); - - // Allocate structure for device instance. - metempl_device = kmalloc(sizeof(metempl_device_t), GFP_KERNEL); - - if (!metempl_device) { - PERROR("Cannot get memory for device instance.\n"); - return NULL; - } - - memset(metempl_device, 0, sizeof(metempl_device_t)); - - // Initialize base class structure. - err = me_device_pci_init((me_device_t *) metempl_device, pci_device); - - if (err) { - kfree(metempl_device); - PERROR("Cannot initialize device base class.\n"); - return NULL; - } - - /* Get the index in the device version information table. */ - version_idx = - metempl_versions_get_device_index(metempl_device->base.info.pci. - device_id); - - // Initialize spin lock . - spin_lock_init(&metempl_device->ctrl_reg_lock); - - // Create subdevice instances. - for (i = 0; i < metempl_versions[version_idx].subdevices; i++) { - subdevice = - (me_subdevice_t *) metempl_sub_constructor(metempl_device-> - base.info.pci. - reg_bases[2], i, - &metempl_device-> - ctrl_reg_lock); - - if (!subdevice) { - me_device_deinit((me_device_t *) metempl_device); - kfree(metempl_device); - PERROR("Cannot get memory for subdevice.\n"); - return NULL; - } - - me_slist_add_subdevice_tail(&metempl_device->base.slist, - subdevice); - } - - /* Overwrite base class methods if applicable. */ - - return (me_device_t *) metempl_device; -} -EXPORT_SYMBOL(metempl_pci_constructor); - -// Init and exit of module. - -static int __init metempl_init(void) -{ - PDEBUG("executed.\n."); - return 0; -} - -static void __exit metempl_exit(void) -{ - PDEBUG("executed.\n."); -} - -module_init(metempl_init); - -module_exit(metempl_exit); - -// Administrative stuff for modinfo. -MODULE_AUTHOR("Guenter Gebhardt "); -MODULE_DESCRIPTION("Device Driver Module for Template Device"); -MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/meilhaus/metempl_device.h b/drivers/staging/meilhaus/metempl_device.h deleted file mode 100644 index c0626e7b73a..00000000000 --- a/drivers/staging/meilhaus/metempl_device.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @file metempl_device.h - * - * @brief template device class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _METEMPL_DEVICE_H -#define _METEMPL_DEVICE_H - -#include -#include - -#include "medevice.h" - -#ifdef __KERNEL__ - -/** - * @brief Structure holding template device capabilities. - */ -typedef struct metempl_version { - uint16_t device_id; - unsigned int subdevices; -} metempl_version_t; - -/** - * @brief Device capabilities. - */ -static metempl_version_t metempl_versions[] = { - {0xDEAD, 1}, - {0}, -}; - -#define METEMPL_DEVICE_VERSIONS (ARRAY_SIZE(metempl_versions) - 1) /**< Returns the number of entries in #metempl_versions. */ - -/** - * @brief Returns the index of the device entry in #metempl_versions. - * - * @param device_id The PCI device id of the device to query. - * @return The index of the device in #metempl_versions. - */ -static inline unsigned int metempl_versions_get_device_index(uint16_t device_id) -{ - unsigned int i; - for (i = 0; i < METEMPL_DEVICE_VERSIONS; i++) - if (metempl_versions[i].device_id == device_id) - break; - return i; -} - -/** - * @brief The template device class structure. - */ -typedef struct metempl_device { - me_device_t base; /**< The Meilhaus device base class. */ - - /* Child class attributes. */ - spinlock_t ctrl_reg_lock; -} metempl_device_t; - -/** - * @brief The template device class constructor. - * - * @param pci_device The pci device structure given by the PCI subsystem. - * - * @return On succes a new template device instance. \n - * NULL on error. - */ -me_device_t *metempl_pci_constructor(struct pci_dev *pci_device) - __attribute__ ((weak)); - -#endif -#endif diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c deleted file mode 100644 index b5a6a978b50..00000000000 --- a/drivers/staging/meilhaus/metempl_sub.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file metempl_sub.c - * - * @brief Subdevice instance. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif - -/* - * Includes - */ -#include - -#include -#include -#include -#include - -#include "medefines.h" -#include "meinternal.h" -#include "meerror.h" - -#include "medebug.h" -#include "metempl_sub_reg.h" -#include "metempl_sub.h" - -/* - * Defines - */ - -/* - * Functions - */ - -static void metempl_sub_destructor(struct me_subdevice *subdevice) -{ - metempl_sub_subdevice_t *instance; - - PDEBUG("executed.\n"); - instance = (metempl_sub_subdevice_t *) subdevice; - - /* Until there this was the things the default constructor does. - If you do not have any additional things to do you can wipe it out. */ - - me_subdevice_deinit(&instance->base); - kfree(instance); -} - -static int metempl_sub_query_number_channels(me_subdevice_t *subdevice, - int *number) -{ - PDEBUG("executed.\n"); - *number = 0; - return ME_ERRNO_SUCCESS; -} - -static int metempl_sub_query_subdevice_type(me_subdevice_t *subdevice, - int *type, int *subtype) -{ - PDEBUG("executed.\n"); - *type = 0; - *subtype = 0; - return ME_ERRNO_SUCCESS; -} - -static int metempl_sub_query_subdevice_caps(me_subdevice_t *subdevice, - int *caps) -{ - PDEBUG("executed.\n"); - *caps = 0; - return ME_ERRNO_SUCCESS; -} - -metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base, - unsigned int sub_idx, - spinlock_t *ctrl_reg_lock) -{ - metempl_sub_subdevice_t *subdevice; - int err; - - PDEBUG("executed.\n"); - - /* Allocate memory for subdevice instance */ - subdevice = kmalloc(sizeof(metempl_sub_subdevice_t), GFP_KERNEL); - - if (!subdevice) { - PERROR("Cannot get memory for subdevice instance.\n"); - return NULL; - } - - memset(subdevice, 0, sizeof(metempl_sub_subdevice_t)); - - /* Check if subdevice index is out of range */ - - if (sub_idx >= 2) { - PERROR("Template subdevice index is out of range.\n"); - kfree(subdevice); - return NULL; - } - - /* Initialize subdevice base class */ - err = me_subdevice_init(&subdevice->base); - - if (err) { - PERROR("Cannot initialize subdevice base class instance.\n"); - kfree(subdevice); - return NULL; - } - // Initialize spin locks. - spin_lock_init(&subdevice->subdevice_lock); - - subdevice->ctrl_reg_lock = ctrl_reg_lock; - - /* Save the subdevice index */ - subdevice->sub_idx = sub_idx; - - /* Override base class methods. */ - subdevice->base.me_subdevice_destructor = metempl_sub_destructor; - subdevice->base.me_subdevice_query_number_channels = - metempl_sub_query_number_channels; - subdevice->base.me_subdevice_query_subdevice_type = - metempl_sub_query_subdevice_type; - subdevice->base.me_subdevice_query_subdevice_caps = - metempl_sub_query_subdevice_caps; - - return subdevice; -} diff --git a/drivers/staging/meilhaus/metempl_sub.h b/drivers/staging/meilhaus/metempl_sub.h deleted file mode 100644 index 80c8af9a8c5..00000000000 --- a/drivers/staging/meilhaus/metempl_sub.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * @file metempl_sub.h - * - * @brief Meilhaus subdevice class. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _METEMPL_SUB_H_ -#define _METEMPL_SUB_H_ - -#include "mesubdevice.h" - -#ifdef __KERNEL__ - -/** - * @brief The subdevice class. - */ -typedef struct metempl_sub_subdevice { - /* Inheritance */ - me_subdevice_t base; /**< The subdevice base class. */ - - /* Attributes */ - spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */ - spinlock_t *ctrl_reg_lock; /**< Spin lock to protect #ctrl_reg from concurrent access. */ - int sub_idx; /**< The index of the subdevice on the device. */ - - unsigned long ctrl_reg; /**< Register to configure the modes. */ -} metempl_sub_subdevice_t; - -/** - * @brief The constructor to generate a subdevice instance. - * - * @param reg_base The register base address of the device as returned by the PCI BIOS. - * @param sub_idx The index of the subdevice on the device. - * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access. - * - * @return Pointer to new instance on success.\n - * NULL on error. - */ -metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base, - unsigned int sub_idx, - spinlock_t * ctrl_reg_lock); - -#endif -#endif diff --git a/drivers/staging/meilhaus/metempl_sub_reg.h b/drivers/staging/meilhaus/metempl_sub_reg.h deleted file mode 100644 index 1a2cab778a1..00000000000 --- a/drivers/staging/meilhaus/metempl_sub_reg.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file metempl_sub_reg.h - * - * @brief Subdevice register definitions. - * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * @author Guenter Gebhardt - */ - -/* - * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * This file 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _METEMPL_SUB_REG_H_ -#define _METEMPL_SUB_REG_H_ - -#ifdef __KERNEL__ - -#define METEMPL_PORT_MODE 0x0010 /**< Configuration register. */ - -#endif -#endif diff --git a/drivers/staging/meilhaus/metypes.h b/drivers/staging/meilhaus/metypes.h deleted file mode 100644 index 228ea15753e..00000000000 --- a/drivers/staging/meilhaus/metypes.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de) - * - * Source File : metypes.h - * Author : GG (Guenter Gebhardt) - */ - -#ifndef _METYPES_H_ -#define _METYPES_H_ - - -typedef int (*meErrorCB_t)(char *pcFunctionName, int iErrorCode); - -typedef int (*meIOStreamCB_t)( - int iDevice, - int iSubdevice, - int iCount, - void *pvContext, - int iErrorCode); - -typedef int (*meIOIrqCB_t)( - int iDevice, - int iSubdevice, - int iChannel, - int iIrqCount, - int iValue, - void *pvContext, - int iErrorCode); - - -typedef struct meIOSingle { - int iDevice; - int iSubdevice; - int iChannel; - int iDir; - int iValue; - int iTimeOut; - int iFlags; - int iErrno; -} meIOSingle_t; - - -typedef struct meIOStreamConfig { - int iChannel; - int iStreamConfig; - int iRef; - int iFlags; -} meIOStreamConfig_t; - - -typedef struct meIOStreamTrigger { - int iAcqStartTrigType; - int iAcqStartTrigEdge; - int iAcqStartTrigChan; - int iAcqStartTicksLow; - int iAcqStartTicksHigh; - int iAcqStartArgs[10]; - int iScanStartTrigType; - int iScanStartTicksLow; - int iScanStartTicksHigh; - int iScanStartArgs[10]; - int iConvStartTrigType; - int iConvStartTicksLow; - int iConvStartTicksHigh; - int iConvStartArgs[10]; - int iScanStopTrigType; - int iScanStopCount; - int iScanStopArgs[10]; - int iAcqStopTrigType; - int iAcqStopCount; - int iAcqStopArgs[10]; - int iFlags; -} meIOStreamTrigger_t; - - -typedef struct meIOStreamStart { - int iDevice; - int iSubdevice; - int iStartMode; - int iTimeOut; - int iFlags; - int iErrno; -} meIOStreamStart_t; - - -typedef struct meIOStreamStop { - int iDevice; - int iSubdevice; - int iStopMode; - int iFlags; - int iErrno; -} meIOStreamStop_t; - - -#endif -- cgit v1.2.3 From ffac040c05f7887896fbd5e1139e7fc59c30fa21 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Sep 2009 21:33:06 -0700 Subject: Staging: rspiusb: remove the driver No one cares, it's a custom userspace interface, and the code hasn't built in a long time. So remove it. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rspiusb/Kconfig | 6 - drivers/staging/rspiusb/Makefile | 1 - drivers/staging/rspiusb/TODO | 22 - drivers/staging/rspiusb/rspiusb.c | 929 -------------------------------------- drivers/staging/rspiusb/rspiusb.h | 33 -- 7 files changed, 994 deletions(-) delete mode 100644 drivers/staging/rspiusb/Kconfig delete mode 100644 drivers/staging/rspiusb/Makefile delete mode 100644 drivers/staging/rspiusb/TODO delete mode 100644 drivers/staging/rspiusb/rspiusb.c delete mode 100644 drivers/staging/rspiusb/rspiusb.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 982e9445606..f7f9051a00e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -85,8 +85,6 @@ source "drivers/staging/rtl8192su/Kconfig" source "drivers/staging/rtl8192e/Kconfig" -source "drivers/staging/rspiusb/Kconfig" - source "drivers/staging/mimio/Kconfig" source "drivers/staging/frontier/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4eabb440a18..3b388edd4f7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ obj-$(CONFIG_RTL8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192SU) += rtl8192su/ obj-$(CONFIG_RTL8192E) += rtl8192e/ -obj-$(CONFIG_USB_RSPI) += rspiusb/ obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_ANDROID) += android/ diff --git a/drivers/staging/rspiusb/Kconfig b/drivers/staging/rspiusb/Kconfig deleted file mode 100644 index d225f6794d0..00000000000 --- a/drivers/staging/rspiusb/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config USB_RSPI - tristate "Princeton Instruments USB camera support" - default n - depends on USB && BROKEN - help - This driver is for the Princeton Instruments USB camera device. diff --git a/drivers/staging/rspiusb/Makefile b/drivers/staging/rspiusb/Makefile deleted file mode 100644 index cc7aed92b0e..00000000000 --- a/drivers/staging/rspiusb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_USB_RSPI) += rspiusb.o diff --git a/drivers/staging/rspiusb/TODO b/drivers/staging/rspiusb/TODO deleted file mode 100644 index cd6336a9254..00000000000 --- a/drivers/staging/rspiusb/TODO +++ /dev/null @@ -1,22 +0,0 @@ -This driver is for the Princeton Instruments USB camera. - -It needs lots of work to get it into the main drivers/usb/ subdirectory: - -Any patches to do any of the following changes are greatly appreciated: - - - make checkpatch.pl clean - - coding style fixups (typedefs, etc.) - - get it to build properly - - audit ioctls - - remove ioctls if possible - - assign proper minor number - - remove dbg() macro - - lots of general cleanups - - review locking - -Please send patches to: - Greg Kroah-Hartman -and CC: - Judd Montgomery - Jeff Frontz -as they have this device and can test any needed changes. diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c deleted file mode 100644 index 0495fbfe59d..00000000000 --- a/drivers/staging/rspiusb/rspiusb.c +++ /dev/null @@ -1,929 +0,0 @@ -/* - * rspiusb.c - * - * Copyright (C) 2005, 2006 Princeton Instruments - * - * 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 version 2 of the License - * - * 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rspiusb.h" - -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug; -#endif -/* Use our own dbg macro */ -#undef dbg -#define dbg(format, arg...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG __FILE__ ": " format "\n" , ##arg); \ - } while (0) - -/* Version Information */ -#define DRIVER_VERSION "V1.0.1" -#define DRIVER_AUTHOR "Princeton Instruments" -#define DRIVER_DESC "PI USB2.0 Device Driver for Linux" - -/* Define these values to match your devices */ -#define VENDOR_ID 0x0BD7 -#define ST133_PID 0xA010 -#define PIXIS_PID 0xA026 - -/* Get a minor range for your devices from the usb maintainer */ -#ifdef CONFIG_USB_DYNAMIC_MINORS -#define PIUSB_MINOR_BASE 0 -#else -#define PIUSB_MINOR_BASE 192 -#endif - -/* prevent races between open() and disconnect() */ -static DECLARE_MUTEX(disconnect_sem); - -/* Structure to hold all of our device specific stuff */ -struct device_extension { - struct usb_device *udev; /* save off the usb device pointer */ - struct usb_interface *interface; /* the interface for this device */ - unsigned char minor; /* the starting minor number - * for this device - */ - size_t bulk_in_size_returned; - int bulk_in_byte_trk; - struct urb ***PixelUrb; - int frameIdx; - int urbIdx; - unsigned int *maplist_numPagesMapped; - int open; /* if the port is open or not */ - int present; /* if the device is not disconnected */ - int userBufMapped; /* has the user buffer been mapped ? */ - struct scatterlist **sgl; /* scatter-gather list for user buffer */ - unsigned int *sgEntries; - struct kref kref; - int gotPixelData; - int pendingWrite; - char **pendedPixelUrbs; - int iama; /* PIXIS or ST133 */ - int num_frames; /* the number of frames that will fit - * in the user buffer - */ - int active_frame; - unsigned long frameSize; - struct semaphore sem; - unsigned int hEP[8]; /* FX2 specific endpoints */ -}; - -#define to_pi_dev(d) container_of(d, struct device_extension, kref) - -/* Prototypes */ -static int MapUserBuffer(struct ioctl_struct *, struct device_extension *); -static int UnMapUserBuffer(struct device_extension *); -static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg); -static int piusb_output(struct ioctl_struct *, unsigned char *, int, - struct device_extension *); -static struct usb_driver piusb_driver; - -/* table of devices that work with this driver */ -static struct usb_device_id pi_device_table[] = { - {USB_DEVICE(VENDOR_ID, ST133_PID)}, - {USB_DEVICE(VENDOR_ID, PIXIS_PID)}, - {0, } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, pi_device_table); - -static int lastErr; -static int errCnt; - -static void piusb_delete(struct kref *kref) -{ - struct device_extension *pdx = to_pi_dev(kref); - - dev_dbg(&pdx->udev->dev, "%s\n", __func__); - usb_put_dev(pdx->udev); - kfree(pdx); -} - -static int piusb_open(struct inode *inode, struct file *file) -{ - struct device_extension *pdx = NULL; - struct usb_interface *interface; - int subminor; - int retval = 0; - - dbg("Piusb_Open()"); - subminor = iminor(inode); - interface = usb_find_interface(&piusb_driver, subminor); - if (!interface) { - printk(KERN_ERR "%s - error, can't find device for minor %d\n", - __func__, subminor); - retval = -ENODEV; - goto exit_no_device; - } - - pdx = usb_get_intfdata(interface); - if (!pdx) { - retval = -ENODEV; - goto exit_no_device; - } - dbg("Alternate Setting = %d", interface->num_altsetting); - - pdx->bulk_in_size_returned = 0; - pdx->bulk_in_byte_trk = 0; - pdx->PixelUrb = NULL; - pdx->frameIdx = 0; - pdx->urbIdx = 0; - pdx->maplist_numPagesMapped = NULL; - pdx->userBufMapped = 0; - pdx->sgl = NULL; - pdx->sgEntries = NULL; - pdx->gotPixelData = 0; - pdx->pendingWrite = 0; - pdx->pendedPixelUrbs = NULL; - pdx->num_frames = 0; - pdx->active_frame = 0; - pdx->frameSize = 0; - - /* increment our usage count for the device */ - kref_get(&pdx->kref); - - /* save our object in the file's private structure */ - file->private_data = pdx; - -exit_no_device: - return retval; -} - -static int piusb_release(struct inode *inode, struct file *file) -{ - struct device_extension *pdx; - int retval = 0; - - dbg("Piusb_Release()"); - pdx = (struct device_extension *)file->private_data; - if (pdx == NULL) { - dbg("%s - object is NULL", __func__); - retval = -ENODEV; - goto object_null; - } - /* decrement the count on our device */ - kref_put(&pdx->kref, piusb_delete); - -object_null: - return retval; -} - -static int pixis_io(struct ioctl_struct *ctrl, struct device_extension *pdx, - struct ioctl_struct *arg) -{ - unsigned int numToRead = 0; - unsigned int totalRead = 0; - unsigned char *uBuf; - int numbytes; - int i; - - uBuf = kmalloc(ctrl->numbytes, GFP_KERNEL); - if (!uBuf) { - dbg("Alloc for uBuf failed"); - return 0; - } - numbytes = (int) ctrl->numbytes; - numToRead = (unsigned int) ctrl->numbytes; - dbg("numbytes to read = %d", numbytes); - dbg("endpoint # %d", ctrl->endpoint); - - if (copy_from_user(uBuf, ctrl->pData, numbytes)) { - dbg("copying ctrl->pData to dummyBuf failed"); - return -EFAULT; - } - - do { - i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl->endpoint], - (uBuf + totalRead), - /* EP0 can only handle 64 bytes at a time */ - (numToRead > 64) ? 64 : numToRead, - &numbytes, HZ * 10); - if (i) { - dbg("CMD = %s, Address = 0x%02X", - ((uBuf[3] == 0x02) ? "WRITE" : "READ"), - uBuf[1]); - dbg("Number of bytes Attempted to read = %d", - (int)ctrl->numbytes); - dbg("Blocking ReadI/O Failed with status %d", i); - kfree(uBuf); - return -1; - } - dbg("Pixis EP0 Read %d bytes", numbytes); - totalRead += numbytes; - numToRead -= numbytes; - } while (numToRead); - - memcpy(ctrl->pData, uBuf, totalRead); - dbg("Total Bytes Read from PIXIS EP0 = %d", totalRead); - ctrl->numbytes = totalRead; - - if (copy_to_user(arg, ctrl, sizeof(struct ioctl_struct))) - dbg("copy_to_user failed in IORB"); - - kfree(uBuf); - return ctrl->numbytes; -} - -static int pixel_data(struct ioctl_struct *ctrl, struct device_extension *pdx) -{ - int i; - - if (!pdx->gotPixelData) - return 0; - - pdx->gotPixelData = 0; - ctrl->numbytes = pdx->bulk_in_size_returned; - pdx->bulk_in_size_returned -= pdx->frameSize; - - for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++) - SetPageDirty(sg_page(&pdx->sgl[pdx->active_frame][i])); - - pdx->active_frame = ((pdx->active_frame + 1) % pdx->num_frames); - - return ctrl->numbytes; -} - -/** - * piusb_ioctl - */ -static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct device_extension *pdx; - char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - unsigned long devRB = 0; - int err = 0; - int retval = 0; - struct ioctl_struct ctrl; - unsigned short controlData = 0; - - pdx = (struct device_extension *)file->private_data; - /* verify that the device wasn't unplugged */ - if (!pdx->present) { - dbg("No Device Present\n"); - return -ENODEV; - } - /* fill in your device specific stuff here */ - 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) { - dev_err(&pdx->udev->dev, "return with error = %d\n", err); - return -EFAULT; - } - switch (cmd) { - case PIUSB_GETVNDCMD: - if (__copy_from_user - (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) { - dev_err(&pdx->udev->dev, "copy_from_user failed\n"); - return -EFAULT; - } - dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd); - retval = - usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), - ctrl.cmd, USB_DIR_IN, 0, 0, &devRB, - ctrl.numbytes, HZ * 10); - if (ctrl.cmd == 0xF1) { - dbg("FW Version returned from HW = %ld.%ld", - (devRB >> 8), (devRB & 0xFF)); - } - if (retval >= 0) - retval = (int)devRB; - return retval; - - case PIUSB_SETVNDCMD: - if (__copy_from_user - (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) { - dev_err(&pdx->udev->dev, "copy_from_user failed\n"); - return -EFAULT; - } - /* dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); */ - controlData = ctrl.pData[0]; - controlData |= (ctrl.pData[1] << 8); - /* dbg( "%s %d", "Vendor Data =",controlData ); */ - retval = usb_control_msg(pdx->udev, - usb_sndctrlpipe(pdx->udev, 0), - ctrl.cmd, - (USB_DIR_OUT | USB_TYPE_VENDOR - /* | USB_RECIP_ENDPOINT */), - controlData, 0, - &dummyCtlBuf, ctrl.numbytes, HZ * 10); - return retval; - - case PIUSB_ISHIGHSPEED: - return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0); - - case PIUSB_WRITEPIPE: - if (__copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) { - dev_err(&pdx->udev->dev, - "copy_from_user WRITE_DUMMY failed\n"); - return -EFAULT; - } - if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) { - dbg("can't access pData"); - return 0; - } - piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx); - return ctrl.numbytes; - - case PIUSB_USERBUFFER: - if (__copy_from_user - (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) { - dev_err(&pdx->udev->dev, "copy_from_user failed\n"); - return -EFAULT; - } - return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx); - - case PIUSB_UNMAP_USERBUFFER: - retval = UnMapUserBuffer(pdx); - return retval; - - case PIUSB_READPIPE: - if (__copy_from_user(&ctrl, (void __user *)arg, - sizeof(struct ioctl_struct))) { - dev_err(&pdx->udev->dev, "copy_from_user failed\n"); - return -EFAULT; - } - if (((0 == ctrl.endpoint) && (PIXIS_PID == pdx->iama)) || - (1 == ctrl.endpoint) || /* ST133IO */ - (4 == ctrl.endpoint)) /* PIXIS IO */ - return pixis_io(&ctrl, pdx, - (struct ioctl_struct *)arg); - else if ((0 == ctrl.endpoint) || /* ST133 Pixel Data */ - (2 == ctrl.endpoint) || /* PIXIS Ping */ - (3 == ctrl.endpoint)) /* PIXIS Pong */ - return pixel_data(&ctrl, pdx); - - break; - - case PIUSB_WHATCAMERA: - return pdx->iama; - - case PIUSB_SETFRAMESIZE: - dbg("PIUSB_SETFRAMESIZE"); - if (__copy_from_user - (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) { - dev_err(&pdx->udev->dev, "copy_from_user failed\n"); - return -EFAULT; - } - pdx->frameSize = ctrl.numbytes; - pdx->num_frames = ctrl.numFrames; - if (!pdx->sgl) - pdx->sgl = - kmalloc(sizeof(struct scatterlist *) * - pdx->num_frames, GFP_KERNEL); - if (!pdx->sgEntries) - pdx->sgEntries = - kmalloc(sizeof(unsigned int) * pdx->num_frames, - GFP_KERNEL); - if (!pdx->PixelUrb) - pdx->PixelUrb = - kmalloc(sizeof(struct urb **) * pdx->num_frames, - GFP_KERNEL); - if (!pdx->maplist_numPagesMapped) - pdx->maplist_numPagesMapped = - vmalloc(sizeof(unsigned int) * pdx->num_frames); - if (!pdx->pendedPixelUrbs) - pdx->pendedPixelUrbs = - kmalloc(sizeof(char *) * pdx->num_frames, - GFP_KERNEL); - return 0; - - default: - dbg("%s\n", "No IOCTL found"); - break; - - } - /* return that we did not understand this ioctl call */ - dbg("Returning -ENOTTY"); - return -ENOTTY; -} - -static void piusb_write_bulk_callback(struct urb *urb) -{ - struct device_extension *pdx = urb->context; - int status = urb->status; - - /* sync/async unlink faults aren't errors */ - if (status && !(status == -ENOENT || status == -ECONNRESET)) - dev_dbg(&urb->dev->dev, - "%s - nonzero write bulk status received: %d", - __func__, status); - - pdx->pendingWrite = 0; - kfree(urb->transfer_buffer); -} - -int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, - struct device_extension *pdx) -{ - struct urb *urb = NULL; - int err = 0; - unsigned char *kbuf = NULL; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (urb != NULL) { - kbuf = kmalloc(len, GFP_KERNEL); - if (!kbuf) { - dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); - return -ENOMEM; - } - if(__copy_from_user(kbuf, uBuf, len)) { - dev_err(&pdx->udev->dev, "__copy_from_user failed\n"); - return -EFAULT; - } - usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, - len, piusb_write_bulk_callback, pdx); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dev_err(&pdx->udev->dev, - "WRITE ERROR:submit urb error = %d\n", err); - } - pdx->pendingWrite = 1; - usb_free_urb(urb); - } - return -EINPROGRESS; -} - -static int UnMapUserBuffer(struct device_extension *pdx) -{ - int i = 0; - int k = 0; - unsigned int epAddr; - - for (k = 0; k < pdx->num_frames; k++) { - dbg("Killing Urbs for Frame %d", k); - for (i = 0; i < pdx->sgEntries[k]; i++) { - usb_kill_urb(pdx->PixelUrb[k][i]); - usb_free_urb(pdx->PixelUrb[k][i]); - pdx->pendedPixelUrbs[k][i] = 0; - } - dbg("Urb error count = %d", errCnt); - errCnt = 0; - dbg("Urbs free'd and Killed for Frame %d", k); - } - - for (k = 0; k < pdx->num_frames; k++) { - if (pdx->iama == PIXIS_PID) - /* which EP should we map this frame to ? */ - /* PONG, odd frames: hEP[3] */ - /* PING, even frames and zero hEP[2] */ - epAddr = (k % 2) ? pdx->hEP[3] : pdx->hEP[2]; - else - /* ST133 only has 1 endpoint for Pixel data transfer */ - epAddr = pdx->hEP[0]; - - usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k], - pdx->maplist_numPagesMapped[k]); - for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++) - page_cache_release(sg_page(&pdx->sgl[k][i])); - kfree(pdx->sgl[k]); - kfree(pdx->PixelUrb[k]); - kfree(pdx->pendedPixelUrbs[k]); - pdx->sgl[k] = NULL; - pdx->PixelUrb[k] = NULL; - pdx->pendedPixelUrbs[k] = NULL; - } - - kfree(pdx->sgEntries); - vfree(pdx->maplist_numPagesMapped); - pdx->sgEntries = NULL; - pdx->maplist_numPagesMapped = NULL; - kfree(pdx->sgl); - kfree(pdx->pendedPixelUrbs); - kfree(pdx->PixelUrb); - pdx->sgl = NULL; - pdx->pendedPixelUrbs = NULL; - pdx->PixelUrb = NULL; - - return 0; -} - -static void piusb_readPIXEL_callback(struct urb *urb) -{ - int i = 0; - struct device_extension *pdx = urb->context; - int status = urb->status; - - if (status && !(status == -ENOENT || status == -ECONNRESET)) { - dbg("%s - nonzero read bulk status received: %d", __func__, - status); - dbg("Error in read EP2 callback"); - dbg("FrameIndex = %d", pdx->frameIdx); - dbg("Bytes received before problem occurred = %d", - pdx->bulk_in_byte_trk); - dbg("Urb Idx = %d", pdx->urbIdx); - pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0; - } else { - pdx->bulk_in_byte_trk += urb->actual_length; - i = usb_submit_urb(urb, GFP_ATOMIC); /* resubmit the URB */ - if (i) { - errCnt++; - if (i != lastErr) { - dbg("submit urb in callback failed " - "with error code %d", i); - lastErr = i; - } - } else { - pdx->urbIdx++; /* point to next URB when we callback */ - if (pdx->bulk_in_byte_trk >= pdx->frameSize) { - pdx->bulk_in_size_returned = - pdx->bulk_in_byte_trk; - pdx->bulk_in_byte_trk = 0; - pdx->gotPixelData = 1; - pdx->frameIdx = - ((pdx->frameIdx + - 1) % pdx->num_frames); - pdx->urbIdx = 0; - } - } - } -} - -/* MapUserBuffer( - inputs: - struct ioctl_struct *io - structure containing user address, - frame #, and size - struct device_extension *pdx - the PIUSB device extension - - returns: - int - status of the task - - Notes: - MapUserBuffer maps a buffer passed down through an ioctl. - The user buffer is Page Aligned by the app and then passed down. - The function get_free_pages(...) does the actual mapping of the buffer - from user space to kernel space. - From there a scatterlist is created from all the pages. - The next function called is to usb_buffer_map_sg which allocated - DMA addresses for each page, even coalescing them if possible. - The DMA address is placed in the scatterlist structure. - The function returns the number of DMA addresses. - This may or may not be equal to the number of pages that - the user buffer uses. - We then build an URB for each DMA address and then submit them. -*/ - -/* -int MapUserBuffer(unsigned long uaddr, unsigned long numbytes, - unsigned long frameInfo, struct device_extension *pdx) -*/ -static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) -{ - unsigned long uaddr; - unsigned long numbytes; - int frameInfo; /* which frame we're mapping */ - unsigned int epAddr = 0; - unsigned long count = 0; - int i = 0; - int k = 0; - int err = 0; - int ret; - struct page **maplist_p; - int numPagesRequired; - - frameInfo = io->numFrames; - uaddr = (unsigned long)io->pData; - numbytes = io->numbytes; - - if (pdx->iama == PIXIS_PID) { - /* which EP should we map this frame to ? */ - /* PONG, odd frames: hEP[3] */ - /* PING, even frames and zero hEP[2] */ - epAddr = (frameInfo % 2) ? pdx->hEP[3] : pdx->hEP[2]; - dbg("Pixis Frame #%d: EP=%d", frameInfo, - (epAddr == pdx->hEP[2]) ? 2 : 4); - } else { /* ST133 only has 1 endpoint for Pixel data transfer */ - epAddr = pdx->hEP[0]; - dbg("ST133 Frame #%d: EP=2", frameInfo); - } - count = numbytes; - dbg("UserAddress = 0x%08lX", uaddr); - dbg("numbytes = %d", (int)numbytes); - - /* number of pages to map the entire user space DMA buffer */ - numPagesRequired = - ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; - dbg("Number of pages needed = %d", numPagesRequired); - maplist_p = vmalloc(numPagesRequired * sizeof(struct page *)); - if (!maplist_p) { - dbg("Can't Allocate Memory for maplist_p"); - return -ENOMEM; - } - - /* map the user buffer to kernel memory */ - down_write(¤t->mm->mmap_sem); - pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current, - current->mm, (uaddr & PAGE_MASK), numPagesRequired, - WRITE, 0 /* Don't Force*/, maplist_p, NULL); - up_write(¤t->mm->mmap_sem); - dbg("Number of pages mapped = %d", - pdx->maplist_numPagesMapped[frameInfo]); - - for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++) - flush_dcache_page(maplist_p[i]); - if (!pdx->maplist_numPagesMapped[frameInfo]) { - dbg("get_user_pages() failed"); - vfree(maplist_p); - return -ENOMEM; - } - - /* need to create a scatterlist that spans each frame - * that can fit into the mapped buffer - */ - pdx->sgl[frameInfo] = - kmalloc((pdx->maplist_numPagesMapped[frameInfo] * - sizeof(struct scatterlist)), GFP_ATOMIC); - if (!pdx->sgl[frameInfo]) { - vfree(maplist_p); - dbg("can't allocate mem for sgl"); - return -ENOMEM; - } - sg_assign_page(&pdx->sgl[frameInfo][0], maplist_p[0]); - pdx->sgl[frameInfo][0].offset = uaddr & ~PAGE_MASK; - if (pdx->maplist_numPagesMapped[frameInfo] > 1) { - pdx->sgl[frameInfo][0].length = - PAGE_SIZE - pdx->sgl[frameInfo][0].offset; - count -= pdx->sgl[frameInfo][0].length; - for (k = 1; k < pdx->maplist_numPagesMapped[frameInfo]; k++) { - pdx->sgl[frameInfo][k].offset = 0; - sg_assign_page(&pdx->sgl[frameInfo][k], maplist_p[k]); - pdx->sgl[frameInfo][k].length = - (count < PAGE_SIZE) ? count : PAGE_SIZE; - count -= PAGE_SIZE; /* example had PAGE_SIZE here */ - } - } else { - pdx->sgl[frameInfo][0].length = count; - } - ret = usb_buffer_map_sg(pdx->udev, epAddr, pdx->sgl[frameInfo], - pdx->maplist_numPagesMapped[frameInfo]); - if (ret < 0) { - vfree(maplist_p); - dbg("usb_buffer_map_sg() failed"); - return -EINVAL; - } - - pdx->sgEntries[frameInfo] = ret; - - dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]); - pdx->userBufMapped = 1; - vfree(maplist_p); - - /* Create and Send the URB's for each s/g entry */ - pdx->PixelUrb[frameInfo] = - kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *), - GFP_KERNEL); - if (!pdx->PixelUrb[frameInfo]) { - dbg("Can't Allocate Memory for Urb"); - return -ENOMEM; - } - for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { - /* 0 iso packets because we're using BULK transfers */ - pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL); - usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], - pdx->udev, - epAddr, - NULL, // non-DMA HC? buy a better hardware - sg_dma_len(&pdx->sgl[frameInfo][i]), - piusb_readPIXEL_callback, (void *)pdx); - pdx->PixelUrb[frameInfo][i]->transfer_dma = - sg_dma_address(&pdx->sgl[frameInfo][i]); - pdx->PixelUrb[frameInfo][i]->transfer_flags = - URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; - } - /* only interrupt when last URB completes */ - pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT; - pdx->pendedPixelUrbs[frameInfo] = - kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL); - if (!pdx->pendedPixelUrbs[frameInfo]) - dbg("Can't allocate Memory for pendedPixelUrbs"); - for (i = 0; i < pdx->sgEntries[frameInfo]; i++) { - err = usb_submit_urb(pdx->PixelUrb[frameInfo][i], GFP_ATOMIC); - if (err) { - dbg("%s %d\n", "submit urb error =", err); - pdx->pendedPixelUrbs[frameInfo][i] = 0; - return err; - } - pdx->pendedPixelUrbs[frameInfo][i] = 1; - } - return 0; -} - -static const struct file_operations piusb_fops = { - .owner = THIS_MODULE, - .ioctl = piusb_ioctl, - .open = piusb_open, - .release = piusb_release, -}; - -static struct usb_class_driver piusb_class = { - .name = "usb/rspiusb%d", - .fops = &piusb_fops, - .minor_base = PIUSB_MINOR_BASE, -}; - -/** - * piusb_probe - * - * Called by the usb core when a new device is connected that it thinks - * this driver might be interested in. - */ -static int piusb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct device_extension *pdx = NULL; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - int i; - int retval = -ENOMEM; - - dev_dbg(&interface->dev, "%s - Looking for PI USB Hardware", __func__); - - pdx = kzalloc(sizeof(struct device_extension), GFP_KERNEL); - if (pdx == NULL) { - dev_err(&interface->dev, "Out of memory\n"); - goto error; - } - kref_init(&pdx->kref); - pdx->udev = usb_get_dev(interface_to_usbdev(interface)); - pdx->interface = interface; - iface_desc = interface->cur_altsetting; - - /* See if the device offered us matches what we can accept */ - if ((pdx->udev->descriptor.idVendor != VENDOR_ID) - || ((pdx->udev->descriptor.idProduct != PIXIS_PID) - && (pdx->udev->descriptor.idProduct != ST133_PID))) - return -ENODEV; - - pdx->iama = pdx->udev->descriptor.idProduct; - - if (debug) { - if (pdx->udev->descriptor.idProduct == PIXIS_PID) - dbg("PIUSB:Pixis Camera Found"); - else - dbg("PIUSB:ST133 USB Controller Found"); - if (pdx->udev->speed == USB_SPEED_HIGH) - dbg("Highspeed(USB2.0) Device Attached"); - else - dbg("Lowspeed (USB1.1) Device Attached"); - - dbg("NumEndpoints in Configuration: %d", - iface_desc->desc.bNumEndpoints); - } - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - if (debug) { - dbg("Endpoint[%d]->bDescriptorType = %d", i, - endpoint->bDescriptorType); - dbg("Endpoint[%d]->bEndpointAddress = 0x%02X", i, - endpoint->bEndpointAddress); - dbg("Endpoint[%d]->bbmAttributes = %d", i, - endpoint->bmAttributes); - dbg("Endpoint[%d]->MaxPacketSize = %d\n", i, - endpoint->wMaxPacketSize); - } - if (usb_endpoint_xfer_bulk(endpoint)) { - if (usb_endpoint_dir_in(endpoint)) - pdx->hEP[i] = - usb_rcvbulkpipe(pdx->udev, - endpoint->bEndpointAddress); - else - pdx->hEP[i] = - usb_sndbulkpipe(pdx->udev, - endpoint->bEndpointAddress); - } - } - usb_set_intfdata(interface, pdx); - retval = usb_register_dev(interface, &piusb_class); - if (retval) { - err("Not able to get a minor for this device."); - usb_set_intfdata(interface, NULL); - goto error; - } - pdx->present = 1; - - /* we can register the device now, as it is ready */ - pdx->minor = interface->minor; - /* let the user know what node this device is now attached to */ - dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor); - return 0; - -error: - if (pdx) - kref_put(&pdx->kref, piusb_delete); - return retval; -} - -/** - * piusb_disconnect - * - * Called by the usb core when the device is removed from the system. - * - * This routine guarantees that the driver will not submit any more urbs - * by clearing pdx->udev. It is also supposed to terminate any currently - * active urbs. Unfortunately, usb_bulk_msg(), used in piusb_read(), does - * not provide any way to do this. But at least we can cancel an active - * write. - */ -static void piusb_disconnect(struct usb_interface *interface) -{ - struct device_extension *pdx; - int minor = interface->minor; - - lock_kernel(); - - pdx = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - /* give back our minor */ - usb_deregister_dev(interface, &piusb_class); - - unlock_kernel(); - - /* prevent device read, write and ioctl */ - pdx->present = 0; - kref_put(&pdx->kref, piusb_delete); - dbg("PI USB2.0 device #%d now disconnected\n", minor); -} - -static struct usb_driver piusb_driver = { - .name = "sub", - .probe = piusb_probe, - .disconnect = piusb_disconnect, - .id_table = pi_device_table, -}; - -/** - * piusb_init - */ -static int __init piusb_init(void) -{ - int result; - - lastErr = 0; - errCnt = 0; - - /* register this driver with the USB subsystem */ - result = usb_register(&piusb_driver); - if (result) - printk(KERN_ERR KBUILD_MODNAME - ": usb_register failed. Error number %d\n", - result); - else - printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC, - DRIVER_VERSION); - return result; -} - -/** - * piusb_exit - */ -static void __exit piusb_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&piusb_driver); -} - -module_init(piusb_init); -module_exit(piusb_exit); - -/* Module parameters */ -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/rspiusb/rspiusb.h b/drivers/staging/rspiusb/rspiusb.h deleted file mode 100644 index 3fc1db7b1c4..00000000000 --- a/drivers/staging/rspiusb/rspiusb.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __RSPIUSB_H -#define __RSPIUSB_H - -#define PIUSB_MAGIC 'm' -#define PIUSB_IOCTL_BASE 192 - -#define PIUSB_IOR(offset) \ - _IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct) -#define PIUSB_IOW(offset) \ - _IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct) -#define PIUSB_IO(offset) \ - _IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset) - -#define PIUSB_GETVNDCMD PIUSB_IOR(1) -#define PIUSB_SETVNDCMD PIUSB_IOW(2) -#define PIUSB_WRITEPIPE PIUSB_IOW(3) -#define PIUSB_READPIPE PIUSB_IOR(4) -#define PIUSB_SETFRAMESIZE PIUSB_IOW(5) -#define PIUSB_WHATCAMERA PIUSB_IO(6) -#define PIUSB_USERBUFFER PIUSB_IOW(7) -#define PIUSB_ISHIGHSPEED PIUSB_IO(8) -#define PIUSB_UNMAP_USERBUFFER PIUSB_IOW(9) - -struct ioctl_struct { - unsigned char cmd; - unsigned long numbytes; - unsigned char dir; /* 1=out; 0=in */ - int endpoint; - int numFrames; - unsigned char *pData; -}; - -#endif -- cgit v1.2.3 From 1c6592f3b78640902494650efb88d8c2520c5c92 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 3 Sep 2009 11:58:09 -0700 Subject: Staging: remove at76_usb wireless driver. There is already an in-kernel driver for this hardware (since 2.6.30), at76c50x-usb, and it supports all of the same devices. So this driver can now be deleted. Acked-by: Kalle Valo Cc: linux-wireless Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/at76_usb/Kconfig | 8 - drivers/staging/at76_usb/Makefile | 1 - drivers/staging/at76_usb/TODO | 7 - drivers/staging/at76_usb/at76_usb.c | 5566 ----------------------------------- drivers/staging/at76_usb/at76_usb.h | 706 ----- 7 files changed, 6291 deletions(-) delete mode 100644 drivers/staging/at76_usb/Kconfig delete mode 100644 drivers/staging/at76_usb/Makefile delete mode 100644 drivers/staging/at76_usb/TODO delete mode 100644 drivers/staging/at76_usb/at76_usb.c delete mode 100644 drivers/staging/at76_usb/at76_usb.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index f7f9051a00e..66188a5bf44 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -57,8 +57,6 @@ source "drivers/staging/wlan-ng/Kconfig" source "drivers/staging/echo/Kconfig" -source "drivers/staging/at76_usb/Kconfig" - source "drivers/staging/poch/Kconfig" source "drivers/staging/agnx/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3b388edd4f7..3c64d5fad65 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_ECHO) += echo/ -obj-$(CONFIG_USB_ATMEL) += at76_usb/ obj-$(CONFIG_POCH) += poch/ obj-$(CONFIG_AGNX) += agnx/ obj-$(CONFIG_OTUS) += otus/ diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig deleted file mode 100644 index 8606f962162..00000000000 --- a/drivers/staging/at76_usb/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -config USB_ATMEL - tristate "Atmel at76c503/at76c505/at76c505a USB cards" - depends on WLAN_80211 && USB - default N - select FW_LOADER - ---help--- - Enable support for USB Wireless devices using Atmel at76c503, - at76c505 or at76c505a chips. diff --git a/drivers/staging/at76_usb/Makefile b/drivers/staging/at76_usb/Makefile deleted file mode 100644 index 6a47e887230..00000000000 --- a/drivers/staging/at76_usb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_USB_ATMEL) += at76_usb.o diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO deleted file mode 100644 index 0c7ed21c3b9..00000000000 --- a/drivers/staging/at76_usb/TODO +++ /dev/null @@ -1,7 +0,0 @@ -Fix the mac80211 port of at76_usb (the proper in-kernel wireless -stack) and get it included to the mainline. Patches available here: - -http://git.kernel.org/?p=linux/kernel/git/linville/wireless-legacy.git;a=shortlog;h=at76 - -Contact Kalle Valo and linux-wireless list - for more information. diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c deleted file mode 100644 index 4db9b976da9..00000000000 --- a/drivers/staging/at76_usb/at76_usb.c +++ /dev/null @@ -1,5566 +0,0 @@ -/* - * at76c503/at76c505 USB driver - * - * Copyright (c) 2002 - 2003 Oliver Kurth - * Copyright (c) 2004 Joerg Albert - * Copyright (c) 2004 Nick Jones - * Copyright (c) 2004 Balint Seeber - * Copyright (c) 2007 Guido Guenther - * - * 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 file is part of the Berlios driver for WLAN USB devices based on the - * Atmel AT76C503A/505/505A. - * - * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "at76_usb.h" - -/* Version information */ -#define DRIVER_NAME "at76_usb" -#define DRIVER_VERSION "0.17" -#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver" - -/* at76_debug bits */ -#define DBG_PROGRESS 0x00000001 /* authentication/accociation */ -#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */ -#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */ -#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */ -#define DBG_TX_DATA 0x00000010 /* tx header */ -#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */ -#define DBG_TX_MGMT 0x00000040 /* tx management */ -#define DBG_RX_DATA 0x00000080 /* rx data header */ -#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */ -#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */ -#define DBG_RX_BEACON 0x00000400 /* rx beacon */ -#define DBG_RX_CTRL 0x00000800 /* rx control */ -#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */ -#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */ -#define DBG_DEVSTART 0x00004000 /* fw download, device start */ -#define DBG_URB 0x00008000 /* rx urb status, ... */ -#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */ -#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */ -#define DBG_PM 0x00040000 /* power management settings */ -#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */ -#define DBG_PARAMS 0x00100000 /* show configured parameters */ -#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */ -#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */ -#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */ -#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */ -#define DBG_MIB 0x02000000 /* dump all MIBs on startup */ -#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */ -#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */ -#define DBG_FW 0x10000000 /* firmware download */ -#define DBG_DFU 0x20000000 /* device firmware upgrade */ - -#define DBG_DEFAULTS 0 - -/* Use our own dbg macro */ -#define at76_dbg(bits, format, arg...) \ - do { \ - if (at76_debug & (bits)) \ - printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \ - } while (0) - -static int at76_debug = DBG_DEFAULTS; - -/* Protect against concurrent firmware loading and parsing */ -static struct mutex fw_mutex; - -static struct fwentry firmwares[] = { - [0] = {""}, - [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"}, - [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"}, - [BOARD_503] = {"atmel_at76c503-rfmd.bin"}, - [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"}, - [BOARD_505] = {"atmel_at76c505-rfmd.bin"}, - [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"}, - [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"}, - [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"}, -}; - -#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) - -static struct usb_device_id dev_table[] = { - /* - * at76c503-i3861 - */ - /* Generic AT76C503/3861 device */ - {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Linksys WUSB11 v2.1/v2.6 */ - {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Netgear MA101 rev. A */ - {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Tekram U300C / Allnet ALL0193 */ - {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* HP HN210W J7801A */ - {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Sitecom/Z-Com/Zyxel M4Y-750 */ - {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Dynalink/Askey WLL013 (intersil) */ - {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */ - {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* BenQ AWL300 */ - {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Addtron AWU-120, Compex WLU11 */ - {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Intel AP310 AnyPoint II USB */ - {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Dynalink L11U */ - {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* Arescom WL-210, FCC id 07J-GL2411USB */ - {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* I-O DATA WN-B11/USB */ - {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* BT Voyager 1010 */ - {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)}, - /* - * at76c503-i3863 - */ - /* Generic AT76C503/3863 device */ - {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)}, - /* Samsung SWL-2100U */ - {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)}, - /* - * at76c503-rfmd - */ - /* Generic AT76C503/RFMD device */ - {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)}, - /* Dynalink/Askey WLL013 (rfmd) */ - {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)}, - /* Linksys WUSB11 v2.6 */ - {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)}, - /* Network Everywhere NWU11B */ - {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)}, - /* Netgear MA101 rev. B */ - {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)}, - /* D-Link DWL-120 rev. E */ - {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)}, - /* Actiontec 802UAT1, HWU01150-01UK */ - {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)}, - /* AirVast W-Buddie WN210 */ - {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)}, - /* Dick Smith Electronics XH1153 802.11b USB adapter */ - {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)}, - /* CNet CNUSB611 */ - {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)}, - /* FiberLine FL-WL200U */ - {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)}, - /* BenQ AWL400 USB stick */ - {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)}, - /* 3Com 3CRSHEW696 */ - {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)}, - /* Siemens Santis ADSL WLAN USB adapter WLL 013 */ - {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)}, - /* Belkin F5D6050, version 2 */ - {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)}, - /* iBlitzz, BWU613 (not *B or *SB) */ - {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)}, - /* Gigabyte GN-WLBM101 */ - {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)}, - /* Planex GW-US11S */ - {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)}, - /* Internal WLAN adapter in h5[4,5]xx series iPAQs */ - {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)}, - /* Corega Wireless LAN USB-11 mini */ - {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)}, - /* Corega Wireless LAN USB-11 mini2 */ - {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)}, - /* Uniden PCW100 */ - {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)}, - /* - * at76c503-rfmd-acc - */ - /* SMC2664W */ - {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)}, - /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */ - {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)}, - /* - * at76c505-rfmd - */ - /* Generic AT76C505/RFMD */ - {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)}, - /* - * at76c505-rfmd2958 - */ - /* Generic AT76C505/RFMD, OvisLink WL-1130USB */ - {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, - /* Fiberline FL-WL240U */ - {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)}, - /* CNet CNUSB-611G */ - {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)}, - /* Linksys WUSB11 v2.8 */ - {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)}, - /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */ - {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)}, - /* Corega WLAN USB Stick 11 */ - {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, - /* Microstar MSI Box MS6978 */ - {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)}, - /* - * at76c505a-rfmd2958 - */ - /* Generic AT76C505A device */ - {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)}, - /* Generic AT76C505AS device */ - {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)}, - /* Siemens Gigaset USB WLAN Adapter 11 */ - {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)}, - /* OQO Model 01+ Internal Wi-Fi */ - {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)}, - /* - * at76c505amx-rfmd - */ - /* Generic AT76C505AMX device */ - {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, dev_table); - -/* Supported rates of this hardware, bit 7 marks basic rates */ -static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 }; - -/* Frequency of each channel in MHz */ -static const long channel_frequency[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 -}; - -#define NUM_CHANNELS ARRAY_SIZE(channel_frequency) - -static const char *const preambles[] = { "long", "short", "auto" }; - -static const char *const mac_states[] = { - [MAC_INIT] = "INIT", - [MAC_SCANNING] = "SCANNING", - [MAC_AUTH] = "AUTH", - [MAC_ASSOC] = "ASSOC", - [MAC_JOINING] = "JOINING", - [MAC_CONNECTED] = "CONNECTED", - [MAC_OWN_IBSS] = "OWN_IBSS" -}; - -/* Firmware download */ -/* DFU states */ -#define STATE_IDLE 0x00 -#define STATE_DETACH 0x01 -#define STATE_DFU_IDLE 0x02 -#define STATE_DFU_DOWNLOAD_SYNC 0x03 -#define STATE_DFU_DOWNLOAD_BUSY 0x04 -#define STATE_DFU_DOWNLOAD_IDLE 0x05 -#define STATE_DFU_MANIFEST_SYNC 0x06 -#define STATE_DFU_MANIFEST 0x07 -#define STATE_DFU_MANIFEST_WAIT_RESET 0x08 -#define STATE_DFU_UPLOAD_IDLE 0x09 -#define STATE_DFU_ERROR 0x0a - -/* DFU commands */ -#define DFU_DETACH 0 -#define DFU_DNLOAD 1 -#define DFU_UPLOAD 2 -#define DFU_GETSTATUS 3 -#define DFU_CLRSTATUS 4 -#define DFU_GETSTATE 5 -#define DFU_ABORT 6 - -#define FW_BLOCK_SIZE 1024 - -struct dfu_status { - unsigned char status; - unsigned char poll_timeout[3]; - unsigned char state; - unsigned char string; -} __attribute__((packed)); - -static inline int at76_is_intersil(enum board_type board) -{ - return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863); -} - -static inline int at76_is_503rfmd(enum board_type board) -{ - return (board == BOARD_503 || board == BOARD_503_ACC); -} - -static inline int at76_is_505a(enum board_type board) -{ - return (board == BOARD_505A || board == BOARD_505AMX); -} - -/* Load a block of the first (internal) part of the firmware */ -static int at76_load_int_fw_block(struct usb_device *udev, int blockno, - void *block, int size) -{ - return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD, - USB_TYPE_CLASS | USB_DIR_OUT | - USB_RECIP_INTERFACE, blockno, 0, block, size, - USB_CTRL_GET_TIMEOUT); -} - -static int at76_dfu_get_status(struct usb_device *udev, - struct dfu_status *status) -{ - int ret; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS, - USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - 0, 0, status, sizeof(struct dfu_status), - USB_CTRL_GET_TIMEOUT); - return ret; -} - -static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state) -{ - int ret; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE, - USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - 0, 0, state, 1, USB_CTRL_GET_TIMEOUT); - return ret; -} - -/* Convert timeout from the DFU status to jiffies */ -static inline unsigned long at76_get_timeout(struct dfu_status *s) -{ - return msecs_to_jiffies((s->poll_timeout[2] << 16) - | (s->poll_timeout[1] << 8) - | (s->poll_timeout[0])); -} - -/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use - * its value in jiffies in the MANIFEST_SYNC state. */ -static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, - int manifest_sync_timeout) -{ - u8 *block; - struct dfu_status dfu_stat_buf; - int ret = 0; - int need_dfu_state = 1; - int is_done = 0; - u8 dfu_state = 0; - u32 dfu_timeout = 0; - int bsize = 0; - int blockno = 0; - - at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size, - manifest_sync_timeout); - - if (!size) { - dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n"); - return -EINVAL; - } - - block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL); - if (!block) - return -ENOMEM; - - do { - if (need_dfu_state) { - ret = at76_dfu_get_state(udev, &dfu_state); - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, - "cannot get DFU state: %d\n", ret); - goto exit; - } - need_dfu_state = 0; - } - - switch (dfu_state) { - case STATE_DFU_DOWNLOAD_SYNC: - at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC"); - ret = at76_dfu_get_status(udev, &dfu_stat_buf); - if (ret >= 0) { - dfu_state = dfu_stat_buf.state; - dfu_timeout = at76_get_timeout(&dfu_stat_buf); - need_dfu_state = 0; - } else - dev_printk(KERN_ERR, &udev->dev, - "at76_dfu_get_status returned %d\n", - ret); - break; - - case STATE_DFU_DOWNLOAD_BUSY: - at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY"); - need_dfu_state = 1; - - at76_dbg(DBG_DFU, "DFU: Resetting device"); - schedule_timeout_interruptible(dfu_timeout); - break; - - case STATE_DFU_DOWNLOAD_IDLE: - at76_dbg(DBG_DFU, "DOWNLOAD..."); - /* fall through */ - case STATE_DFU_IDLE: - at76_dbg(DBG_DFU, "DFU IDLE"); - - bsize = min_t(int, size, FW_BLOCK_SIZE); - memcpy(block, buf, bsize); - at76_dbg(DBG_DFU, "int fw, size left = %5d, " - "bsize = %4d, blockno = %2d", size, bsize, - blockno); - ret = - at76_load_int_fw_block(udev, blockno, block, bsize); - buf += bsize; - size -= bsize; - blockno++; - - if (ret != bsize) - dev_printk(KERN_ERR, &udev->dev, - "at76_load_int_fw_block " - "returned %d\n", ret); - need_dfu_state = 1; - break; - - case STATE_DFU_MANIFEST_SYNC: - at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC"); - - ret = at76_dfu_get_status(udev, &dfu_stat_buf); - if (ret < 0) - break; - - dfu_state = dfu_stat_buf.state; - dfu_timeout = at76_get_timeout(&dfu_stat_buf); - need_dfu_state = 0; - - /* override the timeout from the status response, - needed for AT76C505A */ - if (manifest_sync_timeout > 0) - dfu_timeout = manifest_sync_timeout; - - at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase"); - schedule_timeout_interruptible(dfu_timeout); - break; - - case STATE_DFU_MANIFEST: - at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST"); - is_done = 1; - break; - - case STATE_DFU_MANIFEST_WAIT_RESET: - at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET"); - is_done = 1; - break; - - case STATE_DFU_UPLOAD_IDLE: - at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE"); - break; - - case STATE_DFU_ERROR: - at76_dbg(DBG_DFU, "STATE_DFU_ERROR"); - ret = -EPIPE; - break; - - default: - at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state); - ret = -EINVAL; - break; - } - } while (!is_done && (ret >= 0)); - -exit: - kfree(block); - if (ret >= 0) - ret = 0; - - return ret; -} - -/* Report that the scan results are ready */ -static inline void at76_iwevent_scan_complete(struct net_device *netdev) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name); -} - -static inline void at76_iwevent_bss_connect(struct net_device *netdev, - u8 *bssid) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, - __func__); -} - -static inline void at76_iwevent_bss_disconnect(struct net_device *netdev) -{ - union iwreq_data wrqu; - wrqu.data.length = 0; - wrqu.data.flags = 0; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); - at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, - __func__); -} - -#define HEX2STR_BUFFERS 4 -#define HEX2STR_MAX_LEN 64 -#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10) - -/* Convert binary data into hex string */ -static char *hex2str(void *buf, int len) -{ - static atomic_t a = ATOMIC_INIT(0); - static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1]; - char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)]; - char *obuf = ret; - u8 *ibuf = buf; - - if (len > HEX2STR_MAX_LEN) - len = HEX2STR_MAX_LEN; - - if (len <= 0) { - ret[0] = '\0'; - return ret; - } - - while (len--) { - *obuf++ = BIN2HEX(*ibuf >> 4); - *obuf++ = BIN2HEX(*ibuf & 0xf); - *obuf++ = '-'; - ibuf++; - } - *(--obuf) = '\0'; - - return ret; -} - -/* LED trigger */ -static int tx_activity; -static void at76_ledtrig_tx_timerfunc(unsigned long data); -static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0); -DEFINE_LED_TRIGGER(ledtrig_tx); - -static void at76_ledtrig_tx_timerfunc(unsigned long data) -{ - static int tx_lastactivity; - - if (tx_lastactivity != tx_activity) { - tx_lastactivity = tx_activity; - led_trigger_event(ledtrig_tx, LED_FULL); - mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4); - } else - led_trigger_event(ledtrig_tx, LED_OFF); -} - -static void at76_ledtrig_tx_activity(void) -{ - tx_activity++; - if (!timer_pending(&ledtrig_tx_timer)) - mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4); -} - -/* Check if the given ssid is hidden */ -static inline int at76_is_hidden_ssid(u8 *ssid, int length) -{ - static const u8 zeros[32]; - - if (length == 0) - return 1; - - if (length == 1 && ssid[0] == ' ') - return 1; - - return (memcmp(ssid, zeros, length) == 0); -} - -static inline void at76_free_bss_list(struct at76_priv *priv) -{ - struct list_head *next, *ptr; - unsigned long flags; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - priv->curr_bss = NULL; - - list_for_each_safe(ptr, next, &priv->bss_list) { - list_del(ptr); - kfree(list_entry(ptr, struct bss_info, list)); - } - - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); -} - -static int at76_remap(struct usb_device *udev) -{ - int ret; - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a, - USB_TYPE_VENDOR | USB_DIR_OUT | - USB_RECIP_INTERFACE, 0, 0, NULL, 0, - USB_CTRL_GET_TIMEOUT); - if (ret < 0) - return ret; - return 0; -} - -static int at76_get_op_mode(struct usb_device *udev) -{ - int ret; - u8 saved; - u8 *op_mode; - - op_mode = kmalloc(1, GFP_NOIO); - if (!op_mode) - return -ENOMEM; - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, - USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1, - USB_CTRL_GET_TIMEOUT); - saved = *op_mode; - kfree(op_mode); - - if (ret < 0) - return ret; - else if (ret < 1) - return -EIO; - else - return saved; -} - -/* Load a block of the second ("external") part of the firmware */ -static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno, - void *block, int size) -{ - return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - 0x0802, blockno, block, size, - USB_CTRL_GET_TIMEOUT); -} - -static inline int at76_get_hw_cfg(struct usb_device *udev, - union at76_hwcfg *buf, int buf_size) -{ - return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, - USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, 0x0a02, 0, - buf, buf_size, USB_CTRL_GET_TIMEOUT); -} - -/* Intersil boards use a different "value" for GetHWConfig requests */ -static inline int at76_get_hw_cfg_intersil(struct usb_device *udev, - union at76_hwcfg *buf, int buf_size) -{ - return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, - USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, 0x0902, 0, - buf, buf_size, USB_CTRL_GET_TIMEOUT); -} - -/* Get the hardware configuration for the adapter and put it to the appropriate - * fields of 'priv' (the GetHWConfig request and interpretation of the result - * depends on the board type) */ -static int at76_get_hw_config(struct at76_priv *priv) -{ - int ret; - union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL); - - if (!hwcfg) - return -ENOMEM; - - if (at76_is_intersil(priv->board_type)) { - ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg, - sizeof(hwcfg->i)); - if (ret < 0) - goto exit; - memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN); - priv->regulatory_domain = hwcfg->i.regulatory_domain; - } else if (at76_is_503rfmd(priv->board_type)) { - ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3)); - if (ret < 0) - goto exit; - memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN); - priv->regulatory_domain = hwcfg->r3.regulatory_domain; - } else { - ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5)); - if (ret < 0) - goto exit; - memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN); - priv->regulatory_domain = hwcfg->r5.regulatory_domain; - } - -exit: - kfree(hwcfg); - if (ret < 0) - printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", - priv->netdev->name, ret); - - return ret; -} - -static struct reg_domain const *at76_get_reg_domain(u16 code) -{ - int i; - static struct reg_domain const fd_tab[] = { - {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */ - {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */ - {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */ - {0x31, "Spain", 0x600}, /* ch 10-11 */ - {0x32, "France", 0x1e00}, /* ch 10-13 */ - {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */ - {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */ - {0x50, "Israel", 0x3fc}, /* ch 3-9 */ - {0x00, "", 0xffffffff} /* ch 1-32 */ - }; - - /* Last entry is fallback for unknown domain code */ - for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++) - if (code == fd_tab[i].code) - break; - - return &fd_tab[i]; -} - -static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf, - int buf_size) -{ - int ret; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, - USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size, - USB_CTRL_GET_TIMEOUT); - if (ret >= 0 && ret != buf_size) - return -EIO; - return ret; -} - -/* Return positive number for status, negative for an error */ -static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd) -{ - u8 *stat_buf; - int ret; - - stat_buf = kmalloc(40, GFP_NOIO); - if (!stat_buf) - return -ENOMEM; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22, - USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, cmd, 0, stat_buf, - 40, USB_CTRL_GET_TIMEOUT); - if (ret >= 0) - ret = stat_buf[5]; - kfree(stat_buf); - - return ret; -} - -static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, - int buf_size) -{ - int ret; - struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) + - buf_size, GFP_KERNEL); - - if (!cmd_buf) - return -ENOMEM; - - cmd_buf->cmd = cmd; - cmd_buf->reserved = 0; - cmd_buf->size = cpu_to_le16(buf_size); - memcpy(cmd_buf->data, buf, buf_size); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - 0, 0, cmd_buf, - sizeof(struct at76_command) + buf_size, - USB_CTRL_GET_TIMEOUT); - kfree(cmd_buf); - return ret; -} - -#define MAKE_CMD_STATUS_CASE(c) case (c): return #c -static const char *at76_get_cmd_status_string(u8 cmd_status) -{ - switch (cmd_status) { - MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE); - MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE); - MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN); - MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER); - MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED); - MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT); - MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS); - MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE); - MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED); - } - - return "UNKNOWN"; -} - -/* Wait until the command is completed */ -static int at76_wait_completion(struct at76_priv *priv, int cmd) -{ - int status = 0; - unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT; - - do { - status = at76_get_cmd_status(priv->udev, cmd); - if (status < 0) { - printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", - priv->netdev->name, status); - break; - } - - at76_dbg(DBG_WAIT_COMPLETE, - "%s: Waiting on cmd %d, status = %d (%s)", - priv->netdev->name, cmd, status, - at76_get_cmd_status_string(status)); - - if (status != CMD_STATUS_IN_PROGRESS - && status != CMD_STATUS_IDLE) - break; - - schedule_timeout_interruptible(HZ / 10); /* 100 ms */ - if (time_after(jiffies, timeout)) { - printk(KERN_ERR - "%s: completion timeout for command %d\n", - priv->netdev->name, cmd); - status = -ETIMEDOUT; - break; - } - } while (1); - - return status; -} - -static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf) -{ - int ret; - - ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf, - offsetof(struct set_mib_buffer, - data) + buf->size); - if (ret < 0) - return ret; - - ret = at76_wait_completion(priv, CMD_SET_MIB); - if (ret != CMD_STATUS_COMPLETE) { - printk(KERN_INFO - "%s: set_mib: at76_wait_completion failed " - "with %d\n", priv->netdev->name, ret); - ret = -EIO; - } - - return ret; -} - -/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */ -static int at76_set_radio(struct at76_priv *priv, int enable) -{ - int ret; - int cmd; - - if (priv->radio_on == enable) - return 0; - - cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF; - - ret = at76_set_card_command(priv->udev, cmd, NULL, 0); - if (ret < 0) - printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", - priv->netdev->name, cmd, ret); - else - ret = 1; - - priv->radio_on = enable; - return ret; -} - -/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */ -static int at76_set_pm_mode(struct at76_priv *priv) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode); - priv->mib_buf.data.byte = priv->pm_mode; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -/* Set the association id for power save mode */ -static int at76_set_associd(struct at76_priv *priv, u16 id) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id); - priv->mib_buf.data.word = cpu_to_le16(id); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (associd) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -/* Set the listen interval for power save mode */ -static int at76_set_listen_interval(struct at76_priv *priv, u16 interval) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac, listen_interval); - priv->mib_buf.data.word = cpu_to_le16(interval); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR - "%s: set_mib (listen_interval) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static int at76_set_preamble(struct at76_priv *priv, u8 type) -{ - int ret = 0; - - priv->mib_buf.type = MIB_LOCAL; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_local, preamble_type); - priv->mib_buf.data.byte = type; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static int at76_set_frag(struct at76_priv *priv, u16 size) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold); - priv->mib_buf.data.word = cpu_to_le16(size); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static int at76_set_rts(struct at76_priv *priv, u16 size) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC; - priv->mib_buf.size = 2; - priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold); - priv->mib_buf.data.word = cpu_to_le16(size); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff) -{ - int ret = 0; - - priv->mib_buf.type = MIB_LOCAL; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback); - priv->mib_buf.data.byte = onoff; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static int at76_add_mac_address(struct at76_priv *priv, void *addr) -{ - int ret = 0; - - priv->mib_buf.type = MIB_MAC_ADDR; - priv->mib_buf.size = ETH_ALEN; - priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr); - memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN); - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n", - priv->netdev->name, ret); - - return ret; -} - -static void at76_dump_mib_mac_addr(struct at76_priv *priv) -{ - int i; - int ret; - struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr), - GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m, - sizeof(struct mib_mac_addr)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %pM res 0x%x 0x%x", - priv->netdev->name, m->mac_addr, m->res[0], m->res[1]); - for (i = 0; i < ARRAY_SIZE(m->group_addr); i++) - at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %pM, " - "status %d", priv->netdev->name, i, - m->group_addr[i], m->group_addr_status[i]); -exit: - kfree(m); -} - -static void at76_dump_mib_mac_wep(struct at76_priv *priv) -{ - int i; - int ret; - int key_len; - struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m, - sizeof(struct mib_mac_wep)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u " - "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u " - "encr_level %u key %d", priv->netdev->name, - m->privacy_invoked, m->wep_default_key_id, - m->wep_key_mapping_len, m->exclude_unencrypted, - le32_to_cpu(m->wep_icv_error_count), - le32_to_cpu(m->wep_excluded_count), m->encryption_level, - m->wep_default_key_id); - - key_len = (m->encryption_level == 1) ? - WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN; - - for (i = 0; i < WEP_KEYS; i++) - at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s", - priv->netdev->name, i, - hex2str(m->wep_default_keyvalue[i], key_len)); -exit: - kfree(m); -} - -static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) -{ - int ret; - struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt), - GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m, - sizeof(struct mib_mac_mgmt)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration " - "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d " - "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d " - "current_bssid %pM scurrent_essid %s current_bss_type %d " - "pm_mode %d ibss_change %d res %d " - "multi_domain_capability_implemented %d " - "international_roaming %d country_string %.3s", - priv->netdev->name, le16_to_cpu(m->beacon_period), - le16_to_cpu(m->CFP_max_duration), - le16_to_cpu(m->medium_occupancy_limit), - le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window), - m->CFP_mode, m->privacy_option_implemented, m->DTIM_period, - m->CFP_period, m->current_bssid, - hex2str(m->current_essid, IW_ESSID_MAX_SIZE), - m->current_bss_type, m->power_mgmt_mode, m->ibss_change, - m->res, m->multi_domain_capability_implemented, - m->multi_domain_capability_enabled, m->country_string); -exit: - kfree(m); -} - -static void at76_dump_mib_mac(struct at76_priv *priv) -{ - int ret; - struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d " - "max_rx_lifetime %d frag_threshold %d rts_threshold %d " - "cwmin %d cwmax %d short_retry_time %d long_retry_time %d " - "scan_type %d scan_channel %d probe_delay %u " - "min_channel_time %d max_channel_time %d listen_int %d " - "desired_ssid %s desired_bssid %pM desired_bsstype %d", - priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime), - le32_to_cpu(m->max_rx_lifetime), - le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold), - le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax), - m->short_retry_time, m->long_retry_time, m->scan_type, - m->scan_channel, le16_to_cpu(m->probe_delay), - le16_to_cpu(m->min_channel_time), - le16_to_cpu(m->max_channel_time), - le16_to_cpu(m->listen_interval), - hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE), - m->desired_bssid, m->desired_bsstype); -exit: - kfree(m); -} - -static void at76_dump_mib_phy(struct at76_priv *priv) -{ - int ret; - struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d " - "sifs_time %d preamble_length %d plcp_header_length %d " - "mpdu_max_length %d cca_mode_supported %d operation_rate_set " - "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d " - "phy_type %d current_reg_domain %d", - priv->netdev->name, le32_to_cpu(m->ed_threshold), - le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time), - le16_to_cpu(m->preamble_length), - le16_to_cpu(m->plcp_header_length), - le16_to_cpu(m->mpdu_max_length), - le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0], - m->operation_rate_set[1], m->operation_rate_set[2], - m->operation_rate_set[3], m->channel_id, m->current_cca_mode, - m->phy_type, m->current_reg_domain); -exit: - kfree(m); -} - -static void at76_dump_mib_local(struct at76_priv *priv) -{ - int ret; - struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d " - "txautorate_fallback %d ssid_size %d promiscuous_mode %d " - "preamble_type %d", priv->netdev->name, m->beacon_enable, - m->txautorate_fallback, m->ssid_size, m->promiscuous_mode, - m->preamble_type); -exit: - kfree(m); -} - -static void at76_dump_mib_mdomain(struct at76_priv *priv) -{ - int ret; - struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL); - - if (!m) - return; - - ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m, - sizeof(struct mib_mdomain)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s", - priv->netdev->name, - hex2str(m->channel_list, sizeof(m->channel_list))); - - at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s", - priv->netdev->name, - hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel))); -exit: - kfree(m); -} - -static int at76_get_current_bssid(struct at76_priv *priv) -{ - int ret = 0; - struct mib_mac_mgmt *mac_mgmt = - kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); - - if (!mac_mgmt) { - ret = -ENOMEM; - goto exit; - } - - ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt, - sizeof(struct mib_mac_mgmt)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib failed: %d\n", - priv->netdev->name, ret); - goto error; - } - memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN); - printk(KERN_INFO "%s: using BSSID %pM\n", priv->netdev->name, - priv->bssid); -error: - kfree(mac_mgmt); -exit: - return ret; -} - -static int at76_get_current_channel(struct at76_priv *priv) -{ - int ret = 0; - struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); - - if (!phy) { - ret = -ENOMEM; - goto exit; - } - ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n", - priv->netdev->name, ret); - goto error; - } - priv->channel = phy->channel_id; -error: - kfree(phy); -exit: - return ret; -} - -/** - * at76_start_scan - start a scan - * - * @use_essid - use the configured ESSID in non passive mode - */ -static int at76_start_scan(struct at76_priv *priv, int use_essid) -{ - struct at76_req_scan scan; - - memset(&scan, 0, sizeof(struct at76_req_scan)); - memset(scan.bssid, 0xff, ETH_ALEN); - - if (use_essid) { - memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE); - scan.essid_size = priv->essid_size; - } else - scan.essid_size = 0; - - /* jal: why should we start at a certain channel? we do scan the whole - range allowed by reg domain. */ - scan.channel = priv->channel; - - /* atmelwlandriver differs between scan type 0 and 1 (active/passive) - For ad-hoc mode, it uses type 0 only. */ - scan.scan_type = priv->scan_mode; - - /* INFO: For probe_delay, not multiplying by 1024 as this will be - slightly less than min_channel_time - (per spec: probe delay < min. channel time) */ - scan.min_channel_time = cpu_to_le16(priv->scan_min_time); - scan.max_channel_time = cpu_to_le16(priv->scan_max_time); - scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000); - scan.international_scan = 0; - - /* other values are set to 0 for type 0 */ - - at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, " - "channel = %d, probe_delay = %d, scan_min_time = %d, " - "scan_max_time = %d)", - priv->netdev->name, use_essid, - scan.international_scan, scan.channel, - le16_to_cpu(scan.probe_delay), - le16_to_cpu(scan.min_channel_time), - le16_to_cpu(scan.max_channel_time)); - - return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); -} - -/* Enable monitor mode */ -static int at76_start_monitor(struct at76_priv *priv) -{ - struct at76_req_scan scan; - int ret; - - memset(&scan, 0, sizeof(struct at76_req_scan)); - memset(scan.bssid, 0xff, ETH_ALEN); - - scan.channel = priv->channel; - scan.scan_type = SCAN_TYPE_PASSIVE; - scan.international_scan = 0; - - ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); - if (ret >= 0) - ret = at76_get_cmd_status(priv->udev, CMD_SCAN); - - return ret; -} - -static int at76_start_ibss(struct at76_priv *priv) -{ - struct at76_req_ibss bss; - int ret; - - WARN_ON(priv->mac_state != MAC_OWN_IBSS); - if (priv->mac_state != MAC_OWN_IBSS) - return -EBUSY; - - memset(&bss, 0, sizeof(struct at76_req_ibss)); - memset(bss.bssid, 0xff, ETH_ALEN); - memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE); - bss.essid_size = priv->essid_size; - bss.bss_type = ADHOC_MODE; - bss.channel = priv->channel; - - ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss, - sizeof(struct at76_req_ibss)); - if (ret < 0) { - printk(KERN_ERR "%s: start_ibss failed: %d\n", - priv->netdev->name, ret); - return ret; - } - - ret = at76_wait_completion(priv, CMD_START_IBSS); - if (ret != CMD_STATUS_COMPLETE) { - printk(KERN_ERR "%s: start_ibss failed to complete, %d\n", - priv->netdev->name, ret); - return ret; - } - - ret = at76_get_current_bssid(priv); - if (ret < 0) - return ret; - - ret = at76_get_current_channel(priv); - if (ret < 0) - return ret; - - /* not sure what this is good for ??? */ - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); - priv->mib_buf.data.byte = 0; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) { - printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", - priv->netdev->name, ret); - return ret; - } - - netif_carrier_on(priv->netdev); - netif_start_queue(priv->netdev); - return 0; -} - -/* Request card to join BSS in managed or ad-hoc mode */ -static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr) -{ - struct at76_req_join join; - - BUG_ON(!ptr); - - memset(&join, 0, sizeof(struct at76_req_join)); - memcpy(join.bssid, ptr->bssid, ETH_ALEN); - memcpy(join.essid, ptr->ssid, ptr->ssid_len); - join.essid_size = ptr->ssid_len; - join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2); - join.channel = ptr->channel; - join.timeout = cpu_to_le16(2000); - - at76_dbg(DBG_PROGRESS, - "%s join addr %pM ssid %s stype %d ch %d timeout %d", - priv->netdev->name, join.bssid, join.essid, - join.bss_type, join.channel, le16_to_cpu(join.timeout)); - return at76_set_card_command(priv->udev, CMD_JOIN, &join, - sizeof(struct at76_req_join)); -} - -/* Calculate padding from txbuf->wlength (which excludes the USB TX header), - likely to compensate a flaw in the AT76C503A USB part ... */ -static inline int at76_calc_padding(int wlen) -{ - /* add the USB TX header */ - wlen += AT76_TX_HDRLEN; - - wlen = wlen % 64; - - if (wlen < 50) - return 50 - wlen; - - if (wlen >= 61) - return 64 + 50 - wlen; - - return 0; -} - -/* We are doing a lot of things here in an interrupt. Need - a bh handler (Watching TV with a TV card is probably - a good test: if you see flickers, we are doing too much. - Currently I do see flickers... even with our tasklet :-( ) - Maybe because the bttv driver and usb-uhci use the same interrupt -*/ -/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't - * solve everything.. (alex) */ -static void at76_rx_callback(struct urb *urb) -{ - struct at76_priv *priv = urb->context; - - priv->rx_tasklet.data = (unsigned long)urb; - tasklet_schedule(&priv->rx_tasklet); - return; -} - -static void at76_tx_callback(struct urb *urb) -{ - struct at76_priv *priv = urb->context; - struct net_device_stats *stats = &priv->stats; - unsigned long flags; - struct at76_tx_buffer *mgmt_buf; - int ret; - - switch (urb->status) { - case 0: - stats->tx_packets++; - break; - case -ENOENT: - case -ECONNRESET: - /* urb has been unlinked */ - return; - default: - at76_dbg(DBG_URB, "%s - nonzero tx status received: %d", - __func__, urb->status); - stats->tx_errors++; - break; - } - - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - mgmt_buf = priv->next_mgmt_bulk; - priv->next_mgmt_bulk = NULL; - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); - - if (!mgmt_buf) { - netif_wake_queue(priv->netdev); - return; - } - - /* we don't copy the padding bytes, but add them - to the length */ - memcpy(priv->bulk_out_buffer, mgmt_buf, - le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN); - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, - priv->bulk_out_buffer, - le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding + - AT76_TX_HDRLEN, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - priv->netdev->name, ret); - - kfree(mgmt_buf); -} - -/* Send a management frame on bulk-out. txbuf->wlength must be set */ -static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf) -{ - unsigned long flags; - int ret; - int urb_status; - void *oldbuf = NULL; - - netif_carrier_off(priv->netdev); /* stop netdev watchdog */ - netif_stop_queue(priv->netdev); /* stop tx data packets */ - - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - - urb_status = priv->tx_urb->status; - if (urb_status == -EINPROGRESS) { - /* cannot transmit now, put in the queue */ - oldbuf = priv->next_mgmt_bulk; - priv->next_mgmt_bulk = txbuf; - } - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); - - if (oldbuf) { - /* a data/mgmt tx is already pending in the URB - - if this is no error in some situations we must - implement a queue or silently modify the old msg */ - printk(KERN_ERR "%s: removed pending mgmt buffer %s\n", - priv->netdev->name, hex2str(oldbuf, 64)); - kfree(oldbuf); - return 0; - } - - txbuf->tx_rate = TX_RATE_1MBIT; - txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength)); - memset(txbuf->reserved, 0, sizeof(txbuf->reserved)); - - if (priv->next_mgmt_bulk) - printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n", - priv->netdev->name, urb_status); - - at76_dbg(DBG_TX_MGMT, - "%s: tx mgmt: wlen %d tx_rate %d pad %d %s", - priv->netdev->name, le16_to_cpu(txbuf->wlength), - txbuf->tx_rate, txbuf->padding, - hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength))); - - /* txbuf was not consumed above -> send mgmt msg immediately */ - memcpy(priv->bulk_out_buffer, txbuf, - le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN); - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, - priv->bulk_out_buffer, - le16_to_cpu(txbuf->wlength) + txbuf->padding + - AT76_TX_HDRLEN, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - priv->netdev->name, ret); - - kfree(txbuf); - - return ret; -} - -/* Go to the next information element */ -static inline void next_ie(struct ieee80211_info_element **ie) -{ - *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]); -} - -/* Challenge is the challenge string (in TLV format) - we got with seq_nr 2 for shared secret authentication only and - send in seq_nr 3 WEP encrypted to prove we have the correct WEP key; - otherwise it is NULL */ -static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss, - int seq_nr, struct ieee80211_info_element *challenge) -{ - struct at76_tx_buffer *tx_buffer; - struct ieee80211_hdr_3addr *mgmt; - struct ieee80211_auth *req; - int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE : - AUTH_FRAME_SIZE + 1 + 1 + challenge->len); - - BUG_ON(!bss); - BUG_ON(seq_nr == 3 && !challenge); - tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC); - if (!tx_buffer) - return -ENOMEM; - - req = (struct ieee80211_auth *)tx_buffer->packet; - mgmt = &req->header; - - /* make wireless header */ - /* first auth msg is not encrypted, only the second (seq_nr == 3) */ - mgmt->frame_ctl = - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH | - (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0)); - - mgmt->duration_id = cpu_to_le16(0x8000); - memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); - memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); - memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); - mgmt->seq_ctl = cpu_to_le16(0); - - req->algorithm = cpu_to_le16(priv->auth_mode); - req->transaction = cpu_to_le16(seq_nr); - req->status = cpu_to_le16(0); - - if (seq_nr == 3) - memcpy(req->info_element, challenge, 1 + 1 + challenge->len); - - /* init. at76_priv tx header */ - tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN); - at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %pM alg %d seq_nr %d", - priv->netdev->name, mgmt->addr3, - le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction)); - if (seq_nr == 3) - at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...", - priv->netdev->name, hex2str(req->info_element, 18)); - - /* either send immediately (if no data tx is pending - or put it in pending list */ - return at76_tx_mgmt(priv, tx_buffer); -} - -static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss) -{ - struct at76_tx_buffer *tx_buffer; - struct ieee80211_hdr_3addr *mgmt; - struct ieee80211_assoc_request *req; - struct ieee80211_info_element *ie; - char *essid; - int essid_len; - u16 capa; - - BUG_ON(!bss); - - tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC); - if (!tx_buffer) - return -ENOMEM; - - req = (struct ieee80211_assoc_request *)tx_buffer->packet; - mgmt = &req->header; - ie = req->info_element; - - /* make wireless header */ - mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ASSOC_REQ); - - mgmt->duration_id = cpu_to_le16(0x8000); - memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); - memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); - memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); - mgmt->seq_ctl = cpu_to_le16(0); - - /* we must set the Privacy bit in the capabilities to assure an - Agere-based AP with optional WEP transmits encrypted frames - to us. AP only set the Privacy bit in their capabilities - if WEP is mandatory in the BSS! */ - capa = bss->capa; - if (priv->wep_enabled) - capa |= WLAN_CAPABILITY_PRIVACY; - if (priv->preamble_type != PREAMBLE_TYPE_LONG) - capa |= WLAN_CAPABILITY_SHORT_PREAMBLE; - req->capability = cpu_to_le16(capa); - - req->listen_interval = cpu_to_le16(2 * bss->beacon_interval); - - /* write TLV data elements */ - - ie->id = WLAN_EID_SSID; - ie->len = bss->ssid_len; - memcpy(ie->data, bss->ssid, bss->ssid_len); - next_ie(&ie); - - ie->id = WLAN_EID_SUPP_RATES; - ie->len = sizeof(hw_rates); - memcpy(ie->data, hw_rates, sizeof(hw_rates)); - next_ie(&ie); /* ie points behind the supp_rates field */ - - /* init. at76_priv tx header */ - tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt); - - ie = req->info_element; - essid = ie->data; - essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); - - next_ie(&ie); /* points to IE of rates now */ - at76_dbg(DBG_TX_MGMT, - "%s: AssocReq bssid %pM capa 0x%04x ssid %.*s rates %s", - priv->netdev->name, mgmt->addr3, - le16_to_cpu(req->capability), essid_len, essid, - hex2str(ie->data, ie->len)); - - /* either send immediately (if no data tx is pending - or put it in pending list */ - return at76_tx_mgmt(priv, tx_buffer); -} - -/* We got to check the bss_list for old entries */ -static void at76_bss_list_timeout(unsigned long par) -{ - struct at76_priv *priv = (struct at76_priv *)par; - unsigned long flags; - struct list_head *lptr, *nptr; - struct bss_info *ptr; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - list_for_each_safe(lptr, nptr, &priv->bss_list) { - - ptr = list_entry(lptr, struct bss_info, list); - - if (ptr != priv->curr_bss - && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) { - at76_dbg(DBG_BSS_TABLE_RM, - "%s: bss_list: removing old BSS %pM ch %d", - priv->netdev->name, ptr->bssid, - ptr->channel); - list_del(&ptr->list); - kfree(ptr); - } - } - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - /* restart the timer */ - mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); -} - -static inline void at76_set_mac_state(struct at76_priv *priv, - enum mac_state mac_state) -{ - at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name, - mac_states[mac_state]); - priv->mac_state = mac_state; -} - -static void at76_dump_bss_table(struct at76_priv *priv) -{ - struct bss_info *ptr; - unsigned long flags; - struct list_head *lptr; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name, - priv->curr_bss); - - list_for_each(lptr, &priv->bss_list) { - ptr = list_entry(lptr, struct bss_info, list); - at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %pM channel %d ssid %.*s " - "(%s) capa 0x%04x rates %s rssi %d link %d noise %d", - ptr, ptr->bssid, ptr->channel, ptr->ssid_len, - ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len), - ptr->capa, hex2str(ptr->rates, ptr->rates_len), - ptr->rssi, ptr->link_qual, ptr->noise_level); - } - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); -} - -/* Called upon successful association to mark interface as connected */ -static void at76_work_assoc_done(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_assoc_done); - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_ASSOC); - WARN_ON(!priv->curr_bss); - if (priv->mac_state != MAC_ASSOC || !priv->curr_bss) - goto exit; - - if (priv->iw_mode == IW_MODE_INFRA) { - if (priv->pm_mode != AT76_PM_OFF) { - /* calculate the listen interval in units of - beacon intervals of the curr_bss */ - u32 pm_period_beacon = (priv->pm_period >> 10) / - priv->curr_bss->beacon_interval; - - pm_period_beacon = max(pm_period_beacon, 2u); - pm_period_beacon = min(pm_period_beacon, 0xffffu); - - at76_dbg(DBG_PM, - "%s: pm_mode %d assoc id 0x%x listen int %d", - priv->netdev->name, priv->pm_mode, - priv->assoc_id, pm_period_beacon); - - at76_set_associd(priv, priv->assoc_id); - at76_set_listen_interval(priv, (u16)pm_period_beacon); - } - schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT); - } - at76_set_pm_mode(priv); - - netif_carrier_on(priv->netdev); - netif_wake_queue(priv->netdev); - at76_set_mac_state(priv, MAC_CONNECTED); - at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid); - at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %pM", - priv->netdev->name, priv->curr_bss->bssid); - -exit: - mutex_unlock(&priv->mtx); -} - -/* We only store the new mac address in netdev struct, - it gets set when the netdev is opened. */ -static int at76_set_mac_address(struct net_device *netdev, void *addr) -{ - struct sockaddr *mac = addr; - memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN); - return 1; -} - -static struct net_device_stats *at76_get_stats(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - return &priv->stats; -} - -static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d", - priv->wstats.qual.qual, priv->wstats.qual.level, - priv->wstats.qual.noise, priv->wstats.qual.updated); - - return &priv->wstats; -} - -static void at76_set_multicast(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - int promisc; - - promisc = ((netdev->flags & IFF_PROMISC) != 0); - if (promisc != priv->promisc) { - /* This gets called in interrupt, must reschedule */ - priv->promisc = promisc; - schedule_work(&priv->work_set_promisc); - } -} - -/* Stop all network activity, flush all pending tasks */ -static void at76_quiesce(struct at76_priv *priv) -{ - unsigned long flags; - - netif_stop_queue(priv->netdev); - netif_carrier_off(priv->netdev); - - at76_set_mac_state(priv, MAC_INIT); - - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - cancel_delayed_work(&priv->dwork_restart); - - spin_lock_irqsave(&priv->mgmt_spinlock, flags); - kfree(priv->next_mgmt_bulk); - priv->next_mgmt_bulk = NULL; - spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); -} - -/******************************************************************************* - * at76_priv implementations of iw_handler functions: - */ -static int at76_iw_handler_commit(struct net_device *netdev, - struct iw_request_info *info, - void *null, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name, - __func__); - - if (priv->mac_state != MAC_INIT) - at76_quiesce(priv); - - /* Wait half second before the restart to process subsequent - * requests from the same iwconfig in a single restart */ - schedule_delayed_work(&priv->dwork_restart, HZ / 2); - - return 0; -} - -static int at76_iw_handler_get_name(struct net_device *netdev, - struct iw_request_info *info, - char *name, char *extra) -{ - strcpy(name, "IEEE 802.11b"); - at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name); - return 0; -} - -static int at76_iw_handler_set_freq(struct net_device *netdev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int chan = -1; - int ret = -EIWCOMMIT; - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d", - netdev->name, freq->m, freq->e); - - if ((freq->e == 0) && (freq->m <= 1000)) - /* Setting by channel number */ - chan = freq->m; - else { - /* Setting by frequency - search the table */ - int mult = 1; - int i; - - for (i = 0; i < (6 - freq->e); i++) - mult *= 10; - - for (i = 0; i < NUM_CHANNELS; i++) { - if (freq->m == (channel_frequency[i] * mult)) - chan = i + 1; - } - } - - if (chan < 1 || !priv->domain) - /* non-positive channels are invalid - * we need a domain info to set the channel - * either that or an invalid frequency was - * provided by the user */ - ret = -EINVAL; - else if (!(priv->domain->channel_map & (1 << (chan - 1)))) { - printk(KERN_INFO "%s: channel %d not allowed for domain %s\n", - priv->netdev->name, chan, priv->domain->name); - ret = -EINVAL; - } - - if (ret == -EIWCOMMIT) { - priv->channel = chan; - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name, - chan); - } - - return ret; -} - -static int at76_iw_handler_get_freq(struct net_device *netdev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - freq->m = priv->channel; - freq->e = 0; - - if (priv->channel) - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d", - netdev->name, channel_frequency[priv->channel - 1], 6); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name, - priv->channel); - - return 0; -} - -static int at76_iw_handler_set_mode(struct net_device *netdev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode); - - if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) && - (*mode != IW_MODE_MONITOR)) - return -EINVAL; - - priv->iw_mode = *mode; - if (priv->iw_mode != IW_MODE_INFRA) - priv->pm_mode = AT76_PM_OFF; - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_mode(struct net_device *netdev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - *mode = priv->iw_mode; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode); - - return 0; -} - -static int at76_iw_handler_get_range(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - /* inspired by atmel.c */ - struct at76_priv *priv = netdev_priv(netdev); - struct iw_range *range = (struct iw_range *)extra; - int i; - - data->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - /* TODO: range->throughput = xxxxxx; */ - - range->min_nwid = 0x0000; - range->max_nwid = 0x0000; - - /* this driver doesn't maintain sensitivity information */ - range->sensitivity = 0; - - range->max_qual.qual = 100; - range->max_qual.level = 100; - range->max_qual.noise = 0; - range->max_qual.updated = IW_QUAL_NOISE_INVALID; - - range->avg_qual.qual = 50; - range->avg_qual.level = 50; - range->avg_qual.noise = 0; - range->avg_qual.updated = IW_QUAL_NOISE_INVALID; - - range->bitrate[0] = 1000000; - range->bitrate[1] = 2000000; - range->bitrate[2] = 5500000; - range->bitrate[3] = 11000000; - range->num_bitrates = 4; - - range->min_rts = 0; - range->max_rts = MAX_RTS_THRESHOLD; - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_ON; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R; - - range->encoding_size[0] = WEP_SMALL_KEY_LEN; - range->encoding_size[1] = WEP_LARGE_KEY_LEN; - range->num_encoding_sizes = 2; - range->max_encoding_tokens = WEP_KEYS; - - /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power - - take this for all (ignore antenna gains) */ - range->txpower[0] = 15; - range->num_txpower = 1; - range->txpower_capa = IW_TXPOW_DBM; - - range->we_version_source = WIRELESS_EXT; - range->we_version_compiled = WIRELESS_EXT; - - /* same as the values used in atmel.c */ - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - range->min_retry = 1; - range->max_retry = 255; - - range->num_channels = NUM_CHANNELS; - range->num_frequency = 0; - - for (i = 0; i < NUM_CHANNELS; i++) { - /* test if channel map bit is raised */ - if (priv->domain->channel_map & (0x1 << i)) { - range->num_frequency += 1; - - range->freq[i].i = i + 1; - range->freq[i].m = channel_frequency[i] * 100000; - range->freq[i].e = 1; /* freq * 10^1 */ - } - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name); - - return 0; -} - -static int at76_iw_handler_set_spy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d", - netdev->name, data->length); - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - return ret; -} - -static int at76_iw_handler_get_spy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_get_spy(priv->netdev, info, - (union iwreq_data *)data, extra); - spin_unlock_bh(&priv->spy_spinlock); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d", - netdev->name, data->length); - - return ret; -} - -static int at76_iw_handler_set_thrspy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)", - netdev->name, data->length); - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - return ret; -} - -static int at76_iw_handler_get_thrspy(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret; - - spin_lock_bh(&priv->spy_spinlock); - ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data, - extra); - spin_unlock_bh(&priv->spy_spinlock); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)", - netdev->name, data->length); - - return ret; -} - -static int at76_iw_handler_set_wap(struct net_device *netdev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %pM", netdev->name, - ap_addr->sa_data); - - /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has - chosen any or auto AP preference */ - if (is_broadcast_ether_addr(ap_addr->sa_data) - || is_zero_ether_addr(ap_addr->sa_data)) - priv->wanted_bssid_valid = 0; - else { - /* user wants to set a preferred AP address */ - priv->wanted_bssid_valid = 1; - memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN); - } - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_wap(struct net_device *netdev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %pM", netdev->name, - ap_addr->sa_data); - - return 0; -} - -static int at76_iw_handler_set_scan(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - if (!netif_running(netdev)) { - ret = -ENETDOWN; - goto exit; - } - - /* jal: we don't allow "iwlist ethX scan" while we are - in monitor mode */ - if (priv->iw_mode == IW_MODE_MONITOR) { - ret = -EBUSY; - goto exit; - } - - /* Discard old scan results */ - if ((jiffies - priv->last_scan) > (20 * HZ)) - priv->scan_state = SCAN_IDLE; - priv->last_scan = jiffies; - - /* Initiate a scan command */ - if (priv->scan_state == SCAN_IN_PROGRESS) { - ret = -EBUSY; - goto exit; - } - - priv->scan_state = SCAN_IN_PROGRESS; - - at76_quiesce(priv); - - /* Try to do passive or active scan if WE asks as. */ - if (wrqu->data.length - && wrqu->data.length == sizeof(struct iw_scan_req)) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - if (req->scan_type == IW_SCAN_TYPE_PASSIVE) - priv->scan_mode = SCAN_TYPE_PASSIVE; - else if (req->scan_type == IW_SCAN_TYPE_ACTIVE) - priv->scan_mode = SCAN_TYPE_ACTIVE; - - /* Sanity check values? */ - if (req->min_channel_time > 0) - priv->scan_min_time = req->min_channel_time; - - if (req->max_channel_time > 0) - priv->scan_max_time = req->max_channel_time; - } - - /* change to scanning state */ - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - -exit: - mutex_unlock(&priv->mtx); - return ret; -} - -static int at76_iw_handler_get_scan(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - unsigned long flags; - struct list_head *lptr, *nptr; - struct bss_info *curr_bss; - struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL); - char *curr_val, *curr_pos = extra; - int i; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name); - - if (!iwe) - return -ENOMEM; - - if (priv->scan_state != SCAN_COMPLETED) { - /* scan not yet finished */ - kfree(iwe); - return -EAGAIN; - } - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - - list_for_each_safe(lptr, nptr, &priv->bss_list) { - curr_bss = list_entry(lptr, struct bss_info, list); - - iwe->cmd = SIOCGIWAP; - iwe->u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6); - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_ADDR_LEN); - - iwe->u.data.length = curr_bss->ssid_len; - iwe->cmd = SIOCGIWESSID; - iwe->u.data.flags = 1; - - curr_pos = iwe_stream_add_point(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - curr_bss->ssid); - - iwe->cmd = SIOCGIWMODE; - iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ? - IW_MODE_ADHOC : - (curr_bss->capa & WLAN_CAPABILITY_ESS) ? - IW_MODE_MASTER : IW_MODE_AUTO; - /* IW_MODE_AUTO = 0 which I thought is - * the most logical value to return in this case */ - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_UINT_LEN); - - iwe->cmd = SIOCGIWFREQ; - iwe->u.freq.m = curr_bss->channel; - iwe->u.freq.e = 0; - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_FREQ_LEN); - - iwe->cmd = SIOCGIWENCODE; - if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY) - iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe->u.data.flags = IW_ENCODE_DISABLED; - - iwe->u.data.length = 0; - curr_pos = iwe_stream_add_point(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - NULL); - - /* Add quality statistics */ - iwe->cmd = IWEVQUAL; - iwe->u.qual.noise = 0; - iwe->u.qual.updated = - IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED; - iwe->u.qual.level = (curr_bss->rssi * 100 / 42); - if (iwe->u.qual.level > 100) - iwe->u.qual.level = 100; - if (at76_is_intersil(priv->board_type)) - iwe->u.qual.qual = curr_bss->link_qual; - else { - iwe->u.qual.qual = 0; - iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID; - } - /* Add new value to event */ - curr_pos = iwe_stream_add_event(info, curr_pos, - extra + IW_SCAN_MAX_DATA, iwe, - IW_EV_QUAL_LEN); - - /* Rate: stuffing multiple values in a single event requires - * a bit more of magic - Jean II */ - curr_val = curr_pos + IW_EV_LCP_LEN; - - iwe->cmd = SIOCGIWRATE; - /* Those two flags are ignored... */ - iwe->u.bitrate.fixed = 0; - iwe->u.bitrate.disabled = 0; - /* Max 8 values */ - for (i = 0; i < curr_bss->rates_len; i++) { - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe->u.bitrate.value = - ((curr_bss->rates[i] & 0x7f) * 500000); - /* Add new value to event */ - curr_val = iwe_stream_add_value(info, curr_pos, - curr_val, - extra + - IW_SCAN_MAX_DATA, iwe, - IW_EV_PARAM_LEN); - } - - /* Check if we added any event */ - if ((curr_val - curr_pos) > IW_EV_LCP_LEN) - curr_pos = curr_val; - - /* more information may be sent back using IWECUSTOM */ - - } - - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - - data->length = (curr_pos - extra); - data->flags = 0; - - kfree(iwe); - return 0; -} - -static int at76_iw_handler_set_essid(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra); - - if (data->flags) { - memcpy(priv->essid, extra, data->length); - priv->essid_size = data->length; - } else - priv->essid_size = 0; /* Use any SSID */ - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_essid(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - if (priv->essid_size) { - /* not the ANY ssid in priv->essid */ - data->flags = 1; - data->length = priv->essid_size; - memcpy(extra, priv->essid, data->length); - } else { - /* the ANY ssid was specified */ - if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) { - /* report the SSID we have found */ - data->flags = 1; - data->length = priv->curr_bss->ssid_len; - memcpy(extra, priv->curr_bss->ssid, data->length); - } else { - /* report ANY back */ - data->flags = 0; - data->length = 0; - } - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name, - data->length, extra); - - return 0; -} - -static int at76_iw_handler_set_rate(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *bitrate, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name, - bitrate->value); - - switch (bitrate->value) { - case -1: - priv->txrate = TX_RATE_AUTO; - break; /* auto rate */ - case 1000000: - priv->txrate = TX_RATE_1MBIT; - break; - case 2000000: - priv->txrate = TX_RATE_2MBIT; - break; - case 5500000: - priv->txrate = TX_RATE_5_5MBIT; - break; - case 11000000: - priv->txrate = TX_RATE_11MBIT; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int at76_iw_handler_get_rate(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *bitrate, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - switch (priv->txrate) { - /* return max rate if RATE_AUTO */ - case TX_RATE_AUTO: - bitrate->value = 11000000; - break; - case TX_RATE_1MBIT: - bitrate->value = 1000000; - break; - case TX_RATE_2MBIT: - bitrate->value = 2000000; - break; - case TX_RATE_5_5MBIT: - bitrate->value = 5500000; - break; - case TX_RATE_11MBIT: - bitrate->value = 11000000; - break; - default: - ret = -EINVAL; - } - - bitrate->fixed = (priv->txrate != TX_RATE_AUTO); - bitrate->disabled = 0; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name, - bitrate->value); - - return ret; -} - -static int at76_iw_handler_set_rts(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - int rthr = rts->value; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s", - netdev->name, rts->value, (rts->disabled) ? "true" : "false"); - - if (rts->disabled) - rthr = MAX_RTS_THRESHOLD; - - if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) - ret = -EINVAL; - else - priv->rts_threshold = rthr; - - return ret; -} - -static int at76_iw_handler_get_rts(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - rts->value = priv->rts_threshold; - rts->disabled = (rts->value >= MAX_RTS_THRESHOLD); - rts->fixed = 1; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s", - netdev->name, rts->value, (rts->disabled) ? "true" : "false"); - - return 0; -} - -static int at76_iw_handler_set_frag(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - int fthr = frag->value; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s", - netdev->name, frag->value, - (frag->disabled) ? "true" : "false"); - - if (frag->disabled) - fthr = MAX_FRAG_THRESHOLD; - - if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)) - ret = -EINVAL; - else - priv->frag_threshold = fthr & ~0x1; /* get an even value */ - - return ret; -} - -static int at76_iw_handler_get_frag(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - frag->value = priv->frag_threshold; - frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD); - frag->fixed = 1; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s", - netdev->name, frag->value, - (frag->disabled) ? "true" : "false"); - - return 0; -} - -static int at76_iw_handler_get_txpow(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *power, char *extra) -{ - power->value = 15; - power->fixed = 1; /* No power control */ - power->disabled = 0; - power->flags = IW_TXPOW_DBM; - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name, - power->value); - - return 0; -} - -/* jal: short retry is handled by the firmware (at least 0.90.x), - while long retry is not (?) */ -static int at76_iw_handler_set_retry(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d", - netdev->name, retry->disabled, retry->flags, retry->value); - - if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) { - if ((retry->flags & IW_RETRY_MIN) || - !(retry->flags & IW_RETRY_MAX)) - priv->short_retry_limit = retry->value; - else - ret = -EINVAL; - } else - ret = -EINVAL; - - return ret; -} - -/* Adapted (ripped) from atmel.c */ -static int at76_iw_handler_get_retry(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name); - - retry->disabled = 0; /* Can't be disabled */ - retry->flags = IW_RETRY_LIMIT; - retry->value = priv->short_retry_limit; - - return 0; -} - -static int at76_iw_handler_set_encode(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *encoding, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int index = (encoding->flags & IW_ENCODE_INDEX) - 1; - int len = encoding->length; - - at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x " - "pointer %p len %d", netdev->name, encoding->flags, - encoding->pointer, encoding->length); - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d " - "auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id, - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - /* take the old default key if index is invalid */ - if ((index < 0) || (index >= WEP_KEYS)) - index = priv->wep_key_id; - - if (len > 0) { - if (len > WEP_LARGE_KEY_LEN) - len = WEP_LARGE_KEY_LEN; - - memset(priv->wep_keys[index], 0, WEP_KEY_LEN); - memcpy(priv->wep_keys[index], extra, len); - priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ? - WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN; - priv->wep_enabled = 1; - } - - priv->wep_key_id = index; - priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0); - - if (encoding->flags & IW_ENCODE_RESTRICTED) - priv->auth_mode = WLAN_AUTH_SHARED_KEY; - if (encoding->flags & IW_ENCODE_OPEN) - priv->auth_mode = WLAN_AUTH_OPEN; - - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d " - "key_len %d auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, - priv->wep_keys_len[priv->wep_key_id], - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - return -EIWCOMMIT; -} - -static int at76_iw_handler_get_encode(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *encoding, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int index = (encoding->flags & IW_ENCODE_INDEX) - 1; - - if ((index < 0) || (index >= WEP_KEYS)) - index = priv->wep_key_id; - - encoding->flags = - (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ? - IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; - - if (!priv->wep_enabled) - encoding->flags |= IW_ENCODE_DISABLED; - - if (encoding->pointer) { - encoding->length = priv->wep_keys_len[index]; - - memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]); - - encoding->flags |= (index + 1); - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x " - "pointer %p len %d", netdev->name, encoding->flags, - encoding->pointer, encoding->length); - at76_dbg(DBG_IOCTL, - "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d " - "key_len %d auth_mode %s", netdev->name, - (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, - priv->wep_keys_len[priv->wep_key_id], - (priv->auth_mode == - WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); - - return 0; -} - -static int at76_iw_handler_set_power(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *prq, char *extra) -{ - int err = -EIWCOMMIT; - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_IOCTL, - "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x", - netdev->name, (prq->disabled) ? "true" : "false", prq->flags, - prq->value); - - if (prq->disabled) - priv->pm_mode = AT76_PM_OFF; - else { - switch (prq->flags & IW_POWER_MODE) { - case IW_POWER_ALL_R: - case IW_POWER_ON: - break; - default: - err = -EINVAL; - goto exit; - } - if (prq->flags & IW_POWER_PERIOD) - priv->pm_period = prq->value; - - if (prq->flags & IW_POWER_TIMEOUT) { - err = -EINVAL; - goto exit; - } - priv->pm_mode = AT76_PM_ON; - } -exit: - return err; -} - -static int at76_iw_handler_get_power(struct net_device *netdev, - struct iw_request_info *info, - struct iw_param *power, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - power->disabled = (priv->pm_mode == AT76_PM_OFF); - if (!power->disabled) { - power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R; - power->value = priv->pm_period; - } - - at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x", - netdev->name, power->disabled ? "disabled" : "enabled", - power->flags, power->value); - - return 0; -} - -/******************************************************************************* - * Private IOCTLS - */ -static int at76_iw_set_short_preamble(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d", - netdev->name, val); - - if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO) - ret = -EINVAL; - else - priv->preamble_type = val; - - return ret; -} - -static int at76_iw_get_short_preamble(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - - snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)", - preambles[priv->preamble_type], priv->preamble_type); - return 0; -} - -static int at76_iw_set_debug(struct net_device *netdev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - char *ptr; - u32 val; - - if (data->length > 0) { - val = simple_strtol(extra, &ptr, 0); - - if (ptr == extra) - val = DBG_DEFAULTS; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x", - netdev->name, data->length, extra, val); - } else - val = DBG_DEFAULTS; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x", - netdev->name, at76_debug, val); - - /* jal: some more output to pin down lockups */ - at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d " - "carrier_ok %d", netdev->name, netif_running(netdev), - netif_queue_stopped(netdev), netif_carrier_ok(netdev)); - - at76_debug = val; - - return 0; -} - -static int at76_iw_get_debug(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug); - return 0; -} - -static int at76_iw_set_powersave_mode(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)", - netdev->name, val, - val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" : - val == AT76_PM_SMART ? "smart save" : ""); - if (val < AT76_PM_OFF || val > AT76_PM_SMART) - ret = -EINVAL; - else - priv->pm_mode = val; - - return ret; -} - -static int at76_iw_get_powersave_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->pm_mode; - return 0; -} - -static int at76_iw_set_scan_times(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int mint = *((int *)name); - int maxt = *((int *)name + 1); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d", - netdev->name, mint, maxt); - if (mint <= 0 || maxt <= 0 || mint > maxt) - ret = -EINVAL; - else { - priv->scan_min_time = mint; - priv->scan_max_time = maxt; - } - - return ret; -} - -static int at76_iw_get_scan_times(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->scan_min_time; - param[1] = priv->scan_max_time; - return 0; -} - -static int at76_iw_set_scan_mode(struct net_device *netdev, - struct iw_request_info *info, char *name, - char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int val = *((int *)name); - int ret = -EIWCOMMIT; - - at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s", - netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" : - (val = SCAN_TYPE_PASSIVE) ? "passive" : ""); - - if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE) - ret = -EINVAL; - else - priv->scan_mode = val; - - return ret; -} - -static int at76_iw_get_scan_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct at76_priv *priv = netdev_priv(netdev); - int *param = (int *)extra; - - param[0] = priv->scan_mode; - return 0; -} - -#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f - -/* Standard wireless handlers */ -static const iw_handler at76_handlers[] = { - AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit), - AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name), - AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq), - AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq), - AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode), - AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode), - AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range), - AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy), - AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy), - AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy), - AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy), - AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap), - AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap), - AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan), - AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan), - AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid), - AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid), - AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate), - AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate), - AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts), - AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts), - AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag), - AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag), - AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow), - AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry), - AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry), - AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode), - AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode), - AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power), - AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power) -}; - -#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f - -/* Private wireless handlers */ -static const iw_handler at76_priv_handlers[] = { - AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble), - AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble), - AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug), - AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug), - AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode), - AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode), - AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times), - AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times), - AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode), - AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode), -}; - -/* Names and arguments of private wireless handlers */ -static const struct iw_priv_args at76_priv_args[] = { - /* 0 - long, 1 - short */ - {AT76_SET_SHORT_PREAMBLE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"}, - - {AT76_GET_SHORT_PREAMBLE, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"}, - - /* we must pass the new debug mask as a string, because iwpriv cannot - * parse hex numbers starting with 0x :-( */ - {AT76_SET_DEBUG, - IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"}, - - {AT76_GET_DEBUG, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"}, - - /* 1 - active, 2 - power save, 3 - smart power save */ - {AT76_SET_POWERSAVE_MODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"}, - - {AT76_GET_POWERSAVE_MODE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"}, - - /* min_channel_time, max_channel_time */ - {AT76_SET_SCAN_TIMES, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"}, - - {AT76_GET_SCAN_TIMES, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"}, - - /* 0 - active, 1 - passive scan */ - {AT76_SET_SCAN_MODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"}, - - {AT76_GET_SCAN_MODE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"}, -}; - -static const struct iw_handler_def at76_handler_def = { - .num_standard = ARRAY_SIZE(at76_handlers), - .num_private = ARRAY_SIZE(at76_priv_handlers), - .num_private_args = ARRAY_SIZE(at76_priv_args), - .standard = at76_handlers, - .private = at76_priv_handlers, - .private_args = at76_priv_args, - .get_wireless_stats = at76_get_wireless_stats, -}; - -static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 }; - -/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with - * a SNAP OID of 0 (0x00, 0x00, 0x00) */ -static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; - -static int at76_tx(struct sk_buff *skb, struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - struct net_device_stats *stats = &priv->stats; - int ret = 0; - int wlen; - int submit_len; - struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; - struct ieee80211_hdr_3addr *i802_11_hdr = - (struct ieee80211_hdr_3addr *)tx_buffer->packet; - u8 *payload = i802_11_hdr->payload; - struct ethhdr *eh = (struct ethhdr *)skb->data; - - if (netif_queue_stopped(netdev)) { - printk(KERN_ERR "%s: %s called while netdev is stopped\n", - netdev->name, __func__); - /* skip this packet */ - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - if (priv->tx_urb->status == -EINPROGRESS) { - printk(KERN_ERR "%s: %s called while tx urb is pending\n", - netdev->name, __func__); - /* skip this packet */ - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - if (skb->len < ETH_HLEN) { - printk(KERN_ERR "%s: %s: skb too short (%d)\n", - netdev->name, __func__, skb->len); - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ - - /* we can get rid of memcpy if we set netdev->hard_header_len to - reserve enough space, but we would need to keep the skb around */ - - if (ntohs(eh->h_proto) <= ETH_DATA_LEN) { - /* this is a 802.3 packet */ - if (skb->len >= ETH_HLEN + sizeof(rfc1042sig) - && skb->data[ETH_HLEN] == rfc1042sig[0] - && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) { - /* higher layer delivered SNAP header - keep it */ - memcpy(payload, skb->data + ETH_HLEN, - skb->len - ETH_HLEN); - wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN; - } else { - printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet " - "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n", - priv->netdev->name, skb->data[ETH_HLEN], - skb->data[ETH_HLEN + 1], - skb->data[ETH_HLEN + 2]); - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - } else { - /* add RFC 1042 header in front */ - memcpy(payload, rfc1042sig, sizeof(rfc1042sig)); - memcpy(payload + sizeof(rfc1042sig), &eh->h_proto, - skb->len - offsetof(struct ethhdr, h_proto)); - wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len - - offsetof(struct ethhdr, h_proto); - } - - /* make wireless header */ - i802_11_hdr->frame_ctl = - cpu_to_le16(IEEE80211_FTYPE_DATA | - (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) | - (priv->iw_mode == - IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0)); - - if (priv->iw_mode == IW_MODE_ADHOC) { - memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN); - memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); - memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN); - } else if (priv->iw_mode == IW_MODE_INFRA) { - memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN); - memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); - memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN); - } - - i802_11_hdr->duration_id = cpu_to_le16(0); - i802_11_hdr->seq_ctl = cpu_to_le16(0); - - /* setup 'Atmel' header */ - tx_buffer->wlength = cpu_to_le16(wlen); - tx_buffer->tx_rate = priv->txrate; - /* for broadcast destination addresses, the firmware 0.100.x - seems to choose the highest rate set with CMD_STARTUP in - basic_rate_set replacing this value */ - - memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); - - tx_buffer->padding = at76_calc_padding(wlen); - submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding; - - at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name, - hex2str(skb->data, 32)); - at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s", - priv->netdev->name, - le16_to_cpu(tx_buffer->wlength), - tx_buffer->padding, tx_buffer->tx_rate, - hex2str(i802_11_hdr, sizeof(*i802_11_hdr))); - at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name, - hex2str(payload, 48)); - - /* send stuff */ - netif_stop_queue(netdev); - netdev->trans_start = jiffies; - - usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer, - submit_len, at76_tx_callback, priv); - ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); - if (ret) { - stats->tx_errors++; - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - netdev->name, ret); - if (ret == -EINVAL) - printk(KERN_ERR - "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", - priv->netdev->name, priv->tx_urb, - priv->tx_urb->hcpriv, priv->tx_urb->complete); - } else - stats->tx_bytes += skb->len; - - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - -static void at76_tx_timeout(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - if (!priv) - return; - dev_warn(&netdev->dev, "tx timeout."); - - usb_unlink_urb(priv->tx_urb); - priv->stats.tx_errors++; -} - -static int at76_submit_rx_urb(struct at76_priv *priv) -{ - int ret; - int size; - struct sk_buff *skb = priv->rx_skb; - - if (!priv->rx_urb) { - printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", - priv->netdev->name, __func__); - return -EFAULT; - } - - if (!skb) { - skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); - if (!skb) { - printk(KERN_ERR "%s: cannot allocate rx skbuff\n", - priv->netdev->name); - ret = -ENOMEM; - goto exit; - } - priv->rx_skb = skb; - } else { - skb_push(skb, skb_headroom(skb)); - skb_trim(skb, 0); - } - - size = skb_tailroom(skb); - usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe, - skb_put(skb, size), size, at76_rx_callback, priv); - ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC); - if (ret < 0) { - if (ret == -ENODEV) - at76_dbg(DBG_DEVSTART, - "usb_submit_urb returned -ENODEV"); - else - printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", - priv->netdev->name, ret); - } - -exit: - if (ret < 0 && ret != -ENODEV) - printk(KERN_ERR "%s: cannot submit rx urb - please unload the " - "driver and/or power cycle the device\n", - priv->netdev->name); - - return ret; -} - -static int at76_open(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - int ret = 0; - - at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - /* if netdev->dev_addr != priv->mac_addr we must - set the mac address in the device ! */ - if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) { - if (at76_add_mac_address(priv, netdev->dev_addr) >= 0) - at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %pM", - netdev->name, netdev->dev_addr); - } - - priv->scan_state = SCAN_IDLE; - priv->last_scan = jiffies; - - ret = at76_submit_rx_urb(priv); - if (ret < 0) { - printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", - netdev->name, ret); - goto error; - } - - schedule_delayed_work(&priv->dwork_restart, 0); - - at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__); -error: - mutex_unlock(&priv->mtx); - return ret < 0 ? ret : 0; -} - -static int at76_stop(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - - at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__); - - if (mutex_lock_interruptible(&priv->mtx)) - return -EINTR; - - at76_quiesce(priv); - - if (!priv->device_unplugged) { - /* We are called by "ifconfig ethX down", not because the - * device is not available anymore. */ - at76_set_radio(priv, 0); - - /* We unlink rx_urb because at76_open() re-submits it. - * If unplugged, at76_delete_device() takes care of it. */ - usb_kill_urb(priv->rx_urb); - } - - /* free the bss_list */ - at76_free_bss_list(priv); - - mutex_unlock(&priv->mtx); - at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__); - - return 0; -} - -static void at76_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info) -{ - struct at76_priv *priv = netdev_priv(netdev); - - strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); - strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); - - usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info)); - - snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d", - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); -} - -static u32 at76_ethtool_get_link(struct net_device *netdev) -{ - struct at76_priv *priv = netdev_priv(netdev); - return priv->mac_state == MAC_CONNECTED; -} - -static const struct ethtool_ops at76_ethtool_ops = { - .get_drvinfo = at76_ethtool_get_drvinfo, - .get_link = at76_ethtool_get_link, -}; - -/* Download external firmware */ -static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) -{ - int ret; - int op_mode; - int blockno = 0; - int bsize; - u8 *block; - u8 *buf = fwe->extfw; - int size = fwe->extfw_size; - - if (!buf || !size) - return -ENOENT; - - op_mode = at76_get_op_mode(udev); - at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); - - if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { - dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", - op_mode); - return -EINVAL; - } - - block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL); - if (!block) - return -ENOMEM; - - at76_dbg(DBG_DEVSTART, "downloading external firmware"); - - /* for fw >= 0.100, the device needs an extra empty block */ - do { - bsize = min_t(int, size, FW_BLOCK_SIZE); - memcpy(block, buf, bsize); - at76_dbg(DBG_DEVSTART, - "ext fw, size left = %5d, bsize = %4d, blockno = %2d", - size, bsize, blockno); - ret = at76_load_ext_fw_block(udev, blockno, block, bsize); - if (ret != bsize) { - dev_printk(KERN_ERR, &udev->dev, - "loading %dth firmware block failed: %d\n", - blockno, ret); - goto exit; - } - buf += bsize; - size -= bsize; - blockno++; - } while (bsize > 0); - - if (at76_is_505a(fwe->board_type)) { - at76_dbg(DBG_DEVSTART, "200 ms delay for 505a"); - schedule_timeout_interruptible(HZ / 5 + 1); - } - -exit: - kfree(block); - if (ret < 0) - dev_printk(KERN_ERR, &udev->dev, - "downloading external firmware failed: %d\n", ret); - return ret; -} - -/* Download internal firmware */ -static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) -{ - int ret; - int need_remap = !at76_is_505a(fwe->board_type); - - ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size, - need_remap ? 0 : 2 * HZ); - - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, - "downloading internal fw failed with %d\n", ret); - goto exit; - } - - at76_dbg(DBG_DEVSTART, "sending REMAP"); - - /* no REMAP for 505A (see SF driver) */ - if (need_remap) { - ret = at76_remap(udev); - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, - "sending REMAP failed with %d\n", ret); - goto exit; - } - } - - at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds"); - schedule_timeout_interruptible(2 * HZ + 1); - usb_reset_device(udev); - -exit: - return ret; -} - -static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr) -{ - /* common criteria for both modi */ - - int ret = (priv->essid_size == 0 /* ANY ssid */ || - (priv->essid_size == ptr->ssid_len && - !memcmp(priv->essid, ptr->ssid, ptr->ssid_len))); - if (!ret) - at76_dbg(DBG_BSS_MATCH, - "%s bss table entry %p: essid didn't match", - priv->netdev->name, ptr); - return ret; -} - -static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr) -{ - int ret; - - if (priv->iw_mode == IW_MODE_ADHOC) - ret = ptr->capa & WLAN_CAPABILITY_IBSS; - else - ret = ptr->capa & WLAN_CAPABILITY_ESS; - if (!ret) - at76_dbg(DBG_BSS_MATCH, - "%s bss table entry %p: mode didn't match", - priv->netdev->name, ptr); - return ret; -} - -static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr) -{ - int i; - - for (i = 0; i < ptr->rates_len; i++) { - u8 rate = ptr->rates[i]; - - if (!(rate & 0x80)) - continue; - - /* this is a basic rate we have to support - (see IEEE802.11, ch. 7.3.2.2) */ - if (rate != (0x80 | hw_rates[0]) - && rate != (0x80 | hw_rates[1]) - && rate != (0x80 | hw_rates[2]) - && rate != (0x80 | hw_rates[3])) { - at76_dbg(DBG_BSS_MATCH, - "%s: bss table entry %p: basic rate %02x not " - "supported", priv->netdev->name, ptr, rate); - return 0; - } - } - - /* if we use short preamble, the bss must support it */ - if (priv->preamble_type == PREAMBLE_TYPE_SHORT && - !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) { - at76_dbg(DBG_BSS_MATCH, - "%s: %p does not support short preamble", - priv->netdev->name, ptr); - return 0; - } else - return 1; -} - -static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr) -{ - if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) { - /* we have disabled WEP, but the BSS signals privacy */ - at76_dbg(DBG_BSS_MATCH, - "%s: bss table entry %p: requires encryption", - priv->netdev->name, ptr); - return 0; - } - /* otherwise if the BSS does not signal privacy it may well - accept encrypted packets from us ... */ - return 1; -} - -static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr) -{ - if (!priv->wanted_bssid_valid || - !compare_ether_addr(ptr->bssid, priv->wanted_bssid)) - return 1; - - at76_dbg(DBG_BSS_MATCH, - "%s: requested bssid - %pM does not match", - priv->netdev->name, priv->wanted_bssid); - at76_dbg(DBG_BSS_MATCH, - " AP bssid - %pM of bss table entry %p", - ptr->bssid, ptr); - return 0; -} - -/** - * at76_match_bss - try to find a matching bss in priv->bss - * - * last - last bss tried - * - * last == NULL signals a new round starting with priv->bss_list.next - * this function must be called inside an acquired priv->bss_list_spinlock - * otherwise the timeout on bss may remove the newly chosen entry - */ -static struct bss_info *at76_match_bss(struct at76_priv *priv, - struct bss_info *last) -{ - struct bss_info *ptr = NULL; - struct list_head *curr; - - curr = last ? last->list.next : priv->bss_list.next; - while (curr != &priv->bss_list) { - ptr = list_entry(curr, struct bss_info, list); - if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr) - && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr) - && at76_match_bssid(priv, ptr)) - break; - curr = curr->next; - } - - if (curr == &priv->bss_list) - ptr = NULL; - /* otherwise ptr points to the struct bss_info we have chosen */ - - at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name, - __func__, ptr); - return ptr; -} - -/* Start joining a matching BSS, or create own IBSS */ -static void at76_work_join(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_join); - int ret; - unsigned long flags; - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_JOINING); - if (priv->mac_state != MAC_JOINING) - goto exit; - - /* secure the access to priv->curr_bss ! */ - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - priv->curr_bss = at76_match_bss(priv, priv->curr_bss); - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); - - if (!priv->curr_bss) { - /* here we haven't found a matching (i)bss ... */ - if (priv->iw_mode == IW_MODE_ADHOC) { - at76_set_mac_state(priv, MAC_OWN_IBSS); - at76_start_ibss(priv); - goto exit; - } - /* haven't found a matching BSS in infra mode - try again */ - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - goto exit; - } - - ret = at76_join_bss(priv, priv->curr_bss); - if (ret < 0) { - printk(KERN_ERR "%s: join_bss failed with %d\n", - priv->netdev->name, ret); - goto exit; - } - - ret = at76_wait_completion(priv, CMD_JOIN); - if (ret != CMD_STATUS_COMPLETE) { - if (ret != CMD_STATUS_TIME_OUT) - printk(KERN_ERR "%s: join_bss completed with %d\n", - priv->netdev->name, ret); - else - printk(KERN_INFO "%s: join_bss ssid %pM timed out\n", - priv->netdev->name, - priv->curr_bss->bssid); - - /* retry next BSS immediately */ - schedule_work(&priv->work_join); - goto exit; - } - - /* here we have joined the (I)BSS */ - if (priv->iw_mode == IW_MODE_ADHOC) { - struct bss_info *bptr = priv->curr_bss; - at76_set_mac_state(priv, MAC_CONNECTED); - /* get ESSID, BSSID and channel for priv->curr_bss */ - priv->essid_size = bptr->ssid_len; - memcpy(priv->essid, bptr->ssid, bptr->ssid_len); - memcpy(priv->bssid, bptr->bssid, ETH_ALEN); - priv->channel = bptr->channel; - at76_iwevent_bss_connect(priv->netdev, bptr->bssid); - netif_carrier_on(priv->netdev); - netif_start_queue(priv->netdev); - /* just to be sure */ - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - } else { - /* send auth req */ - priv->retries = AUTH_RETRIES; - at76_set_mac_state(priv, MAC_AUTH); - at76_auth_req(priv, priv->curr_bss, 1, NULL); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Reap scan results */ -static void at76_dwork_get_scan(struct work_struct *work) -{ - int status; - int ret; - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_get_scan.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_SCANNING); - if (priv->mac_state != MAC_SCANNING) - goto exit; - - status = at76_get_cmd_status(priv->udev, CMD_SCAN); - if (status < 0) { - printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n", - priv->netdev->name, __func__, status); - status = CMD_STATUS_IN_PROGRESS; - /* INFO: Hope it was a one off error - if not, scanning - further down the line and stop this cycle */ - } - at76_dbg(DBG_PROGRESS, - "%s %s: got cmd_status %d (state %s, need_any %d)", - priv->netdev->name, __func__, status, - mac_states[priv->mac_state], priv->scan_need_any); - - if (status != CMD_STATUS_COMPLETE) { - if ((status != CMD_STATUS_IN_PROGRESS) && - (status != CMD_STATUS_IDLE)) - printk(KERN_ERR "%s: %s: Bad scan status: %s\n", - priv->netdev->name, __func__, - at76_get_cmd_status_string(status)); - - /* the first cmd status after scan start is always a IDLE -> - start the timer to poll again until COMPLETED */ - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", - __func__, __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - goto exit; - } - - if (at76_debug & DBG_BSS_TABLE) - at76_dump_bss_table(priv); - - if (priv->scan_need_any) { - ret = at76_start_scan(priv, 0); - if (ret < 0) - printk(KERN_ERR - "%s: %s: start_scan (ANY) failed with %d\n", - priv->netdev->name, __func__, ret); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", __func__, - __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - priv->scan_need_any = 0; - } else { - priv->scan_state = SCAN_COMPLETED; - /* report the end of scan to user space */ - at76_iwevent_scan_complete(priv->netdev); - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle loss of beacons from the AP */ -static void at76_dwork_beacon(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_beacon.work); - - mutex_lock(&priv->mtx); - if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA) - goto exit; - - /* We haven't received any beacons from out AP for BEACON_TIMEOUT */ - printk(KERN_INFO "%s: lost beacon bssid %pM\n", - priv->netdev->name, priv->curr_bss->bssid); - - netif_carrier_off(priv->netdev); - netif_stop_queue(priv->netdev); - at76_iwevent_bss_disconnect(priv->netdev); - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle authentication response timeout */ -static void at76_dwork_auth(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_auth.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_AUTH); - if (priv->mac_state != MAC_AUTH) - goto exit; - - at76_dbg(DBG_PROGRESS, "%s: authentication response timeout", - priv->netdev->name); - - if (priv->retries-- >= 0) { - at76_auth_req(priv, priv->curr_bss, 1, NULL); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", - __func__, __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); - } else { - /* try to get next matching BSS */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Handle association response timeout */ -static void at76_dwork_assoc(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_assoc.work); - - mutex_lock(&priv->mtx); - WARN_ON(priv->mac_state != MAC_ASSOC); - if (priv->mac_state != MAC_ASSOC) - goto exit; - - at76_dbg(DBG_PROGRESS, "%s: association response timeout", - priv->netdev->name); - - if (priv->retries-- >= 0) { - at76_assoc_req(priv, priv->curr_bss); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", - __func__, __LINE__); - schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); - } else { - /* try to get next matching BSS */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Read new bssid in ad-hoc mode */ -static void at76_work_new_bss(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_new_bss); - int ret; - struct mib_mac_mgmt mac_mgmt; - - mutex_lock(&priv->mtx); - - ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt, - sizeof(struct mib_mac_mgmt)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib failed: %d\n", - priv->netdev->name, ret); - goto exit; - } - - at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change); - memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN); - at76_dbg(DBG_PROGRESS, "using BSSID %pM", priv->bssid); - - at76_iwevent_bss_connect(priv->netdev, priv->bssid); - - priv->mib_buf.type = MIB_MAC_MGMT; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); - priv->mib_buf.data.byte = 0; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", - priv->netdev->name, ret); - -exit: - mutex_unlock(&priv->mtx); -} - -static int at76_startup_device(struct at76_priv *priv) -{ - struct at76_card_config *ccfg = &priv->card_config; - int ret; - - at76_dbg(DBG_PARAMS, - "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d " - "keylen %d", priv->netdev->name, priv->essid_size, priv->essid, - hex2str(priv->essid, IW_ESSID_MAX_SIZE), - priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra", - priv->channel, priv->wep_enabled ? "enabled" : "disabled", - priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]); - at76_dbg(DBG_PARAMS, - "%s param: preamble %s rts %d retry %d frag %d " - "txrate %s auth_mode %d", priv->netdev->name, - preambles[priv->preamble_type], priv->rts_threshold, - priv->short_retry_limit, priv->frag_threshold, - priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate == - TX_RATE_2MBIT ? "2MBit" : priv->txrate == - TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate == - TX_RATE_11MBIT ? "11MBit" : priv->txrate == - TX_RATE_AUTO ? "auto" : "", priv->auth_mode); - at76_dbg(DBG_PARAMS, - "%s param: pm_mode %d pm_period %d auth_mode %s " - "scan_times %d %d scan_mode %s", - priv->netdev->name, priv->pm_mode, priv->pm_period, - priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret", - priv->scan_min_time, priv->scan_max_time, - priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive"); - - memset(ccfg, 0, sizeof(struct at76_card_config)); - ccfg->promiscuous_mode = 0; - ccfg->short_retry_limit = priv->short_retry_limit; - - if (priv->wep_enabled) { - if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN) - ccfg->encryption_type = 2; - else - ccfg->encryption_type = 1; - - /* jal: always exclude unencrypted if WEP is active */ - ccfg->exclude_unencrypted = 1; - } else { - ccfg->exclude_unencrypted = 0; - ccfg->encryption_type = 0; - } - - ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold); - ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold); - - memcpy(ccfg->basic_rate_set, hw_rates, 4); - /* jal: really needed, we do a set_mib for autorate later ??? */ - ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0); - ccfg->channel = priv->channel; - ccfg->privacy_invoked = priv->wep_enabled; - memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE); - ccfg->ssid_len = priv->essid_size; - - ccfg->wep_default_key_id = priv->wep_key_id; - memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN); - - ccfg->short_preamble = priv->preamble_type; - ccfg->beacon_period = cpu_to_le16(priv->beacon_period); - - ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config, - sizeof(struct at76_card_config)); - if (ret < 0) { - printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", - priv->netdev->name, ret); - return ret; - } - - at76_wait_completion(priv, CMD_STARTUP); - - /* remove BSSID from previous run */ - memset(priv->bssid, 0, ETH_ALEN); - - if (at76_set_radio(priv, 1) == 1) - at76_wait_completion(priv, CMD_RADIO_ON); - - ret = at76_set_preamble(priv, priv->preamble_type); - if (ret < 0) - return ret; - - ret = at76_set_frag(priv, priv->frag_threshold); - if (ret < 0) - return ret; - - ret = at76_set_rts(priv, priv->rts_threshold); - if (ret < 0) - return ret; - - ret = at76_set_autorate_fallback(priv, - priv->txrate == TX_RATE_AUTO ? 1 : 0); - if (ret < 0) - return ret; - - ret = at76_set_pm_mode(priv); - if (ret < 0) - return ret; - - if (at76_debug & DBG_MIB) { - at76_dump_mib_mac(priv); - at76_dump_mib_mac_addr(priv); - at76_dump_mib_mac_mgmt(priv); - at76_dump_mib_mac_wep(priv); - at76_dump_mib_mdomain(priv); - at76_dump_mib_phy(priv); - at76_dump_mib_local(priv); - } - - return 0; -} - -/* Restart the interface */ -static void at76_dwork_restart(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - dwork_restart.work); - - mutex_lock(&priv->mtx); - - netif_carrier_off(priv->netdev); /* stop netdev watchdog */ - netif_stop_queue(priv->netdev); /* stop tx data packets */ - - at76_startup_device(priv); - - if (priv->iw_mode != IW_MODE_MONITOR) { - priv->netdev->type = ARPHRD_ETHER; - at76_set_mac_state(priv, MAC_SCANNING); - schedule_work(&priv->work_start_scan); - } else { - priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP; - at76_start_monitor(priv); - } - - mutex_unlock(&priv->mtx); -} - -/* Initiate scanning */ -static void at76_work_start_scan(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_start_scan); - int ret; - - mutex_lock(&priv->mtx); - - WARN_ON(priv->mac_state != MAC_SCANNING); - if (priv->mac_state != MAC_SCANNING) - goto exit; - - /* only clear the bss list when a scan is actively initiated, - * otherwise simply rely on at76_bss_list_timeout */ - if (priv->scan_state == SCAN_IN_PROGRESS) { - at76_free_bss_list(priv); - priv->scan_need_any = 1; - } else - priv->scan_need_any = 0; - - ret = at76_start_scan(priv, 1); - - if (ret < 0) - printk(KERN_ERR "%s: %s: start_scan failed with %d\n", - priv->netdev->name, __func__, ret); - else { - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer for %d ticks", - __func__, __LINE__, SCAN_POLL_INTERVAL); - schedule_delayed_work(&priv->dwork_get_scan, - SCAN_POLL_INTERVAL); - } - -exit: - mutex_unlock(&priv->mtx); -} - -/* Enable or disable promiscuous mode */ -static void at76_work_set_promisc(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_set_promisc); - int ret = 0; - - mutex_lock(&priv->mtx); - - priv->mib_buf.type = MIB_LOCAL; - priv->mib_buf.size = 1; - priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode); - priv->mib_buf.data.byte = priv->promisc ? 1 : 0; - - ret = at76_set_mib(priv, &priv->mib_buf); - if (ret < 0) - printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", - priv->netdev->name, ret); - - mutex_unlock(&priv->mtx); -} - -/* Submit Rx urb back to the device */ -static void at76_work_submit_rx(struct work_struct *work) -{ - struct at76_priv *priv = container_of(work, struct at76_priv, - work_submit_rx); - - mutex_lock(&priv->mtx); - at76_submit_rx_urb(priv); - mutex_unlock(&priv->mtx); -} - -/* We got an association response */ -static void at76_rx_mgmt_assoc(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_assoc_response *resp = - (struct ieee80211_assoc_response *)buf->packet; - u16 assoc_id = le16_to_cpu(resp->aid); - u16 status = le16_to_cpu(resp->status); - - at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %pM capa 0x%04x status " - "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name, - resp->header.addr3, le16_to_cpu(resp->capability), - status, assoc_id, hex2str(resp->info_element->data, - resp->info_element->len)); - - if (priv->mac_state != MAC_ASSOC) { - printk(KERN_INFO "%s: AssocResp in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - - BUG_ON(!priv->curr_bss); - - cancel_delayed_work(&priv->dwork_assoc); - if (status == WLAN_STATUS_SUCCESS) { - struct bss_info *ptr = priv->curr_bss; - priv->assoc_id = assoc_id & 0x3fff; - /* update iwconfig params */ - memcpy(priv->bssid, ptr->bssid, ETH_ALEN); - memcpy(priv->essid, ptr->ssid, ptr->ssid_len); - priv->essid_size = ptr->ssid_len; - priv->channel = ptr->channel; - schedule_work(&priv->work_assoc_done); - } else { - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - } -} - -/* Process disassociation request from the AP */ -static void at76_rx_mgmt_disassoc(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_disassoc *resp = - (struct ieee80211_disassoc *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - - at76_dbg(DBG_RX_MGMT, - "%s: rx DisAssoc bssid %pM reason 0x%04x destination %pM", - priv->netdev->name, mgmt->addr3, - le16_to_cpu(resp->reason), mgmt->addr1); - - /* We are not connected, ignore */ - if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT - || !priv->curr_bss) - return; - - /* Not our BSSID, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) - return; - - /* Not for our STA and not broadcast, ignore */ - if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) - && !is_broadcast_ether_addr(mgmt->addr1)) - return; - - if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED - && priv->mac_state != MAC_JOINING) { - printk(KERN_INFO "%s: DisAssoc in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - - if (priv->mac_state == MAC_CONNECTED) { - netif_carrier_off(priv->netdev); - netif_stop_queue(priv->netdev); - at76_iwevent_bss_disconnect(priv->netdev); - } - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); -} - -static void at76_rx_mgmt_auth(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - int seq_nr = le16_to_cpu(resp->transaction); - int alg = le16_to_cpu(resp->algorithm); - int status = le16_to_cpu(resp->status); - - at76_dbg(DBG_RX_MGMT, - "%s: rx AuthFrame bssid %pM alg %d seq_nr %d status %d " - "destination %pM", priv->netdev->name, mgmt->addr3, - alg, seq_nr, status, mgmt->addr1); - - if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2) - at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...", - priv->netdev->name, hex2str(resp->info_element, 18)); - - if (priv->mac_state != MAC_AUTH) { - printk(KERN_INFO "%s: ignored AuthFrame in state %s\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - if (priv->auth_mode != alg) { - printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n", - priv->netdev->name, alg); - return; - } - - BUG_ON(!priv->curr_bss); - - /* Not our BSSID or not for our STA, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid) - || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)) - return; - - cancel_delayed_work(&priv->dwork_auth); - if (status != WLAN_STATUS_SUCCESS) { - /* try to join next bss */ - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - return; - } - - if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) { - priv->retries = ASSOC_RETRIES; - at76_set_mac_state(priv, MAC_ASSOC); - at76_assoc_req(priv, priv->curr_bss); - at76_dbg(DBG_MGMT_TIMER, - "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); - schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); - return; - } - - WARN_ON(seq_nr != 2); - at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element); - at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__, - __LINE__); - schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); -} - -static void at76_rx_mgmt_deauth(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_disassoc *resp = - (struct ieee80211_disassoc *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &resp->header; - - at76_dbg(DBG_RX_MGMT | DBG_PROGRESS, - "%s: rx DeAuth bssid %pM reason 0x%04x destination %pM", - priv->netdev->name, mgmt->addr3, - le16_to_cpu(resp->reason), mgmt->addr1); - - if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC - && priv->mac_state != MAC_CONNECTED) { - printk(KERN_INFO "%s: DeAuth in state %s ignored\n", - priv->netdev->name, mac_states[priv->mac_state]); - return; - } - - BUG_ON(!priv->curr_bss); - - /* Not our BSSID, ignore */ - if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) - return; - - /* Not for our STA and not broadcast, ignore */ - if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) - && !is_broadcast_ether_addr(mgmt->addr1)) - return; - - if (priv->mac_state == MAC_CONNECTED) - at76_iwevent_bss_disconnect(priv->netdev); - - at76_set_mac_state(priv, MAC_JOINING); - schedule_work(&priv->work_join); - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); -} - -static void at76_rx_mgmt_beacon(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - int varpar_len; - /* beacon content */ - struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet; - struct ieee80211_hdr_3addr *mgmt = &bdata->header; - - struct list_head *lptr; - struct bss_info *match; /* entry matching addr3 with its bssid */ - int new_entry = 0; - int len; - struct ieee80211_info_element *ie; - int have_ssid = 0; - int have_rates = 0; - int have_channel = 0; - int keep_going = 1; - unsigned long flags; - - spin_lock_irqsave(&priv->bss_list_spinlock, flags); - if (priv->mac_state == MAC_CONNECTED) { - /* in state MAC_CONNECTED we use the mgmt_timer to control - the beacon of the BSS */ - BUG_ON(!priv->curr_bss); - - if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) { - /* We got our AP's beacon, defer the timeout handler. - Kill pending work first, as schedule_delayed_work() - won't do it. */ - cancel_delayed_work(&priv->dwork_beacon); - schedule_delayed_work(&priv->dwork_beacon, - BEACON_TIMEOUT); - priv->curr_bss->rssi = buf->rssi; - priv->beacons_received++; - goto exit; - } - } - - /* look if we have this BSS already in the list */ - match = NULL; - - if (!list_empty(&priv->bss_list)) { - list_for_each(lptr, &priv->bss_list) { - struct bss_info *bss_ptr = - list_entry(lptr, struct bss_info, list); - if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) { - match = bss_ptr; - break; - } - } - } - - if (!match) { - /* BSS not in the list - append it */ - match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC); - if (!match) { - at76_dbg(DBG_BSS_TABLE, - "%s: cannot kmalloc new bss info (%zd byte)", - priv->netdev->name, sizeof(struct bss_info)); - goto exit; - } - new_entry = 1; - list_add_tail(&match->list, &priv->bss_list); - } - - match->capa = le16_to_cpu(bdata->capability); - match->beacon_interval = le16_to_cpu(bdata->beacon_interval); - match->rssi = buf->rssi; - match->link_qual = buf->link_quality; - match->noise_level = buf->noise_level; - memcpy(match->bssid, mgmt->addr3, ETH_ALEN); - at76_dbg(DBG_RX_BEACON, "%s: bssid %pM", priv->netdev->name, - match->bssid); - - ie = bdata->info_element; - - /* length of var length beacon parameters */ - varpar_len = min_t(int, le16_to_cpu(buf->wlength) - - sizeof(struct ieee80211_beacon), - BEACON_MAX_DATA_LENGTH); - - /* This routine steps through the bdata->data array to get - * some useful information about the access point. - * Currently, this implementation supports receipt of: SSID, - * supported transfer rates and channel, in any order, with some - * tolerance for intermittent unknown codes (although this - * functionality may not be necessary as the useful information will - * usually arrive in consecutively, but there have been some - * reports of some of the useful information fields arriving in a - * different order). - * It does not support any more IE types although MFIE_TYPE_TIM may - * be supported (on my AP at least). - * The bdata->data array is about 1500 bytes long but only ~36 of those - * bytes are useful, hence the have_ssid etc optimizations. */ - - while (keep_going && - ((&ie->data[ie->len] - (u8 *)bdata->info_element) <= - varpar_len)) { - - switch (ie->id) { - - case WLAN_EID_SSID: - if (have_ssid) - break; - - len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); - - /* we copy only if this is a new entry, - or the incoming SSID is not a hidden SSID. This - will protect us from overwriting a real SSID read - in a ProbeResponse with a hidden one from a - following beacon. */ - if (!new_entry && at76_is_hidden_ssid(ie->data, len)) { - have_ssid = 1; - break; - } - - match->ssid_len = len; - memcpy(match->ssid, ie->data, len); - at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s", - priv->netdev->name, len, match->ssid); - have_ssid = 1; - break; - - case WLAN_EID_SUPP_RATES: - if (have_rates) - break; - - match->rates_len = - min_t(int, sizeof(match->rates), ie->len); - memcpy(match->rates, ie->data, match->rates_len); - have_rates = 1; - at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s", - priv->netdev->name, - hex2str(ie->data, ie->len)); - break; - - case WLAN_EID_DS_PARAMS: - if (have_channel) - break; - - match->channel = ie->data[0]; - have_channel = 1; - at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d", - priv->netdev->name, match->channel); - break; - - case WLAN_EID_CF_PARAMS: - case WLAN_EID_TIM: - case WLAN_EID_IBSS_PARAMS: - default: - at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s", - priv->netdev->name, ie->id, ie->len, - hex2str(ie->data, ie->len)); - break; - } - - /* advance to the next informational element */ - next_ie(&ie); - - /* Optimization: after all, the bdata->data array is - * varpar_len bytes long, whereas we get all of the useful - * information after only ~36 bytes, this saves us a lot of - * time (and trouble as the remaining portion of the array - * could be full of junk) - * Comment this out if you want to see what other information - * comes from the AP - although little of it may be useful */ - } - - at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data", - priv->netdev->name); - - match->last_rx = jiffies; /* record last rx of beacon */ - -exit: - spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); -} - -/* Calculate the link level from a given rx_buffer */ -static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) -{ - /* just a guess for now, might be different for other chips */ - int max_rssi = 42; - - qual->level = (buf->rssi * 100 / max_rssi); - if (qual->level > 100) - qual->level = 100; - qual->updated |= IW_QUAL_LEVEL_UPDATED; -} - -/* Calculate the link quality from a given rx_buffer */ -static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) -{ - if (at76_is_intersil(priv->board_type)) - qual->qual = buf->link_quality; - else { - unsigned long elapsed; - - /* Update qual at most once a second */ - elapsed = jiffies - priv->beacons_last_qual; - if (elapsed < 1 * HZ) - return; - - qual->qual = qual->level * priv->beacons_received * - msecs_to_jiffies(priv->beacon_period) / elapsed; - - priv->beacons_last_qual = jiffies; - priv->beacons_received = 0; - } - qual->qual = (qual->qual > 100) ? 100 : qual->qual; - qual->updated |= IW_QUAL_QUAL_UPDATED; -} - -/* Calculate the noise quality from a given rx_buffer */ -static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf, - struct iw_quality *qual) -{ - qual->noise = 0; - qual->updated |= IW_QUAL_NOISE_INVALID; -} - -static void at76_update_wstats(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct iw_quality *qual = &priv->wstats.qual; - - if (buf->rssi && priv->mac_state == MAC_CONNECTED) { - qual->updated = 0; - at76_calc_level(priv, buf, qual); - at76_calc_qual(priv, buf, qual); - at76_calc_noise(priv, buf, qual); - } else { - qual->qual = 0; - qual->level = 0; - qual->noise = 0; - qual->updated = IW_QUAL_ALL_INVALID; - } -} - -static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf) -{ - struct ieee80211_hdr_3addr *mgmt = - (struct ieee80211_hdr_3addr *)buf->packet; - u16 framectl = le16_to_cpu(mgmt->frame_ctl); - - /* update wstats */ - if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) { - /* jal: this is a dirty hack needed by Tim in ad-hoc mode */ - /* Data packets always seem to have a 0 link level, so we - only read link quality info from management packets. - Atmel driver actually averages the present, and previous - values, we just present the raw value at the moment - TJS */ - if (priv->iw_mode == IW_MODE_ADHOC - || (priv->curr_bss - && !compare_ether_addr(mgmt->addr3, - priv->curr_bss->bssid))) - at76_update_wstats(priv, buf); - } - - at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s", - priv->netdev->name, framectl, - hex2str(mgmt, le16_to_cpu(buf->wlength))); - - switch (framectl & IEEE80211_FCTL_STYPE) { - case IEEE80211_STYPE_BEACON: - case IEEE80211_STYPE_PROBE_RESP: - at76_rx_mgmt_beacon(priv, buf); - break; - - case IEEE80211_STYPE_ASSOC_RESP: - at76_rx_mgmt_assoc(priv, buf); - break; - - case IEEE80211_STYPE_DISASSOC: - at76_rx_mgmt_disassoc(priv, buf); - break; - - case IEEE80211_STYPE_AUTH: - at76_rx_mgmt_auth(priv, buf); - break; - - case IEEE80211_STYPE_DEAUTH: - at76_rx_mgmt_deauth(priv, buf); - break; - - default: - printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", - priv->netdev->name, framectl); - } - - return; -} - -/* Convert the 802.11 header into an ethernet-style header, make skb - * ready for consumption by netif_rx() */ -static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode) -{ - struct ieee80211_hdr_3addr *i802_11_hdr; - struct ethhdr *eth_hdr_p; - u8 *src_addr; - u8 *dest_addr; - - i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; - - /* That would be the ethernet header if the hardware converted - * the frame for us. Make sure the source and the destination - * match the 802.11 header. Which hardware does it? */ - eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN); - - dest_addr = i802_11_hdr->addr1; - if (iw_mode == IW_MODE_ADHOC) - src_addr = i802_11_hdr->addr2; - else - src_addr = i802_11_hdr->addr3; - - if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) && - !compare_ether_addr(eth_hdr_p->h_dest, dest_addr)) - /* Yes, we already have an ethernet header */ - skb_reset_mac_header(skb); - else { - u16 len; - - /* Need to build an ethernet header */ - if (!memcmp(skb->data, snapsig, sizeof(snapsig))) { - /* SNAP frame - decapsulate, keep proto */ - skb_push(skb, offsetof(struct ethhdr, h_proto) - - sizeof(rfc1042sig)); - len = 0; - } else { - /* 802.3 frame, proto is length */ - len = skb->len; - skb_push(skb, ETH_HLEN); - } - - skb_reset_mac_header(skb); - eth_hdr_p = eth_hdr(skb); - /* This needs to be done in this order (eth_hdr_p->h_dest may - * overlap src_addr) */ - memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN); - memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN); - if (len) - eth_hdr_p->h_proto = htons(len); - } - - skb->protocol = eth_type_trans(skb, skb->dev); -} - -/* Check for fragmented data in priv->rx_skb. If the packet was no fragment - or it was the last of a fragment set a skb containing the whole packet - is returned for further processing. Otherwise we get NULL and are - done and the packet is either stored inside the fragment buffer - or thrown away. Every returned skb starts with the ieee802_11 header - and contains _no_ FCS at the end */ -static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv) -{ - struct sk_buff *skb = priv->rx_skb; - struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; - struct ieee80211_hdr_3addr *i802_11_hdr = - (struct ieee80211_hdr_3addr *)buf->packet; - /* seq_ctrl, fragment_number, sequence number of new packet */ - u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl); - u16 fragnr = sctl & 0xf; - u16 seqnr = sctl >> 4; - u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); - - /* Length including the IEEE802.11 header, but without the trailing - * FCS and without the Atmel Rx header */ - int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN; - - /* where does the data payload start in skb->data ? */ - u8 *data = i802_11_hdr->payload; - - /* length of payload, excl. the trailing FCS */ - int data_len = length - IEEE80211_3ADDR_LEN; - - int i; - struct rx_data_buf *bptr, *optr; - unsigned long oldest = ~0UL; - - at76_dbg(DBG_RX_FRAGS, - "%s: rx data frame_ctl %04x addr2 %pM seq/frag %d/%d " - "length %d data %d: %s ...", priv->netdev->name, frame_ctl, - i802_11_hdr->addr2, seqnr, fragnr, length, data_len, - hex2str(data, 32)); - - at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p " - "tail %p end %p len %d", priv->netdev->name, skb->head, - skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), - skb->len); - - if (data_len < 0) { - /* make sure data starts in the buffer */ - printk(KERN_INFO "%s: data frame too short\n", - priv->netdev->name); - return NULL; - } - - WARN_ON(length <= AT76_RX_HDRLEN); - if (length <= AT76_RX_HDRLEN) - return NULL; - - /* remove the at76_rx_buffer header - we don't need it anymore */ - /* we need the IEEE802.11 header (for the addresses) if this packet - is the first of a chain */ - skb_pull(skb, AT76_RX_HDRLEN); - - /* remove FCS at end */ - skb_trim(skb, length); - - at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p " - "end %p len %d data %p data_len %d", priv->netdev->name, - skb->head, skb->data, skb_tail_pointer(skb), - skb_end_pointer(skb), skb->len, data, data_len); - - if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { - /* unfragmented packet received */ - /* Use a new skb for the next receive */ - priv->rx_skb = NULL; - at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name); - return skb; - } - - /* look if we've got a chain for the sender address. - afterwards optr points to first free or the oldest entry, - or, if i < NR_RX_DATA_BUF, bptr points to the entry for the - sender address */ - /* determining the oldest entry doesn't cope with jiffies wrapping - but I don't care to delete a young entry at these rare moments ... */ - - bptr = priv->rx_data; - optr = NULL; - for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) { - if (!bptr->skb) { - optr = bptr; - oldest = 0UL; - continue; - } - - if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender)) - break; - - if (!optr) { - optr = bptr; - oldest = bptr->last_rx; - } else if (bptr->last_rx < oldest) - optr = bptr; - } - - if (i < NR_RX_DATA_BUF) { - - at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) " - "matched sender addr", - priv->netdev->name, i, bptr->seqnr, bptr->fragnr); - - /* bptr points to an entry for the sender address */ - if (bptr->seqnr == seqnr) { - int left; - /* the fragment has the current sequence number */ - if (((bptr->fragnr + 1) & 0xf) != fragnr) { - /* wrong fragment number -> ignore it */ - /* is & 0xf necessary above ??? */ - at76_dbg(DBG_RX_FRAGS, - "%s: frag nr mismatch: %d + 1 != %d", - priv->netdev->name, bptr->fragnr, - fragnr); - return NULL; - } - bptr->last_rx = jiffies; - /* the next following fragment number -> - add the data at the end */ - - /* for test only ??? */ - left = skb_tailroom(bptr->skb); - if (left < data_len) - printk(KERN_INFO - "%s: only %d byte free (need %d)\n", - priv->netdev->name, left, data_len); - else - memcpy(skb_put(bptr->skb, data_len), data, - data_len); - - bptr->fragnr = fragnr; - if (frame_ctl & IEEE80211_FCTL_MOREFRAGS) - return NULL; - - /* this was the last fragment - send it */ - skb = bptr->skb; - bptr->skb = NULL; /* free the entry */ - at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d", - priv->netdev->name, seqnr); - return skb; - } - - /* got another sequence number */ - if (fragnr == 0) { - /* it's the start of a new chain - replace the - old one by this */ - /* bptr->sender has the correct value already */ - at76_dbg(DBG_RX_FRAGS, - "%s: start of new seq %d, removing old seq %d", - priv->netdev->name, seqnr, bptr->seqnr); - bptr->seqnr = seqnr; - bptr->fragnr = 0; - bptr->last_rx = jiffies; - /* swap bptr->skb and priv->rx_skb */ - skb = bptr->skb; - bptr->skb = priv->rx_skb; - priv->rx_skb = skb; - } else { - /* it from the middle of a new chain -> - delete the old entry and skip the new one */ - at76_dbg(DBG_RX_FRAGS, - "%s: middle of new seq %d (%d) " - "removing old seq %d", - priv->netdev->name, seqnr, fragnr, - bptr->seqnr); - dev_kfree_skb(bptr->skb); - bptr->skb = NULL; - } - return NULL; - } - - /* if we didn't find a chain for the sender address, optr - points either to the first free or the oldest entry */ - - if (fragnr != 0) { - /* this is not the begin of a fragment chain ... */ - at76_dbg(DBG_RX_FRAGS, - "%s: no chain for non-first fragment (%d)", - priv->netdev->name, fragnr); - return NULL; - } - - BUG_ON(!optr); - if (optr->skb) { - /* swap the skb's */ - skb = optr->skb; - optr->skb = priv->rx_skb; - priv->rx_skb = skb; - - at76_dbg(DBG_RX_FRAGS, - "%s: free old contents: sender %pM seq/frag %d/%d", - priv->netdev->name, optr->sender, - optr->seqnr, optr->fragnr); - - } else { - /* take the skb from priv->rx_skb */ - optr->skb = priv->rx_skb; - /* let at76_submit_rx_urb() allocate a new skb */ - priv->rx_skb = NULL; - - at76_dbg(DBG_RX_FRAGS, "%s: use a free entry", - priv->netdev->name); - } - memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN); - optr->seqnr = seqnr; - optr->fragnr = 0; - optr->last_rx = jiffies; - - return NULL; -} - -/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */ -static void at76_rx_data(struct at76_priv *priv) -{ - struct net_device *netdev = priv->netdev; - struct net_device_stats *stats = &priv->stats; - struct sk_buff *skb = priv->rx_skb; - struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; - struct ieee80211_hdr_3addr *i802_11_hdr; - int length = le16_to_cpu(buf->wlength); - - at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name, - hex2str(skb->data, AT76_RX_HDRLEN)); - - at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s", - hex2str(skb->data + AT76_RX_HDRLEN, length)); - - skb = at76_check_for_rx_frags(priv); - if (!skb) - return; - - /* Atmel header and the FCS are already removed */ - i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; - - skb->dev = netdev; - skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */ - - if (is_broadcast_ether_addr(i802_11_hdr->addr1)) { - if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast)) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_MULTICAST; - } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr)) - skb->pkt_type = PACKET_OTHERHOST; - - at76_ieee80211_to_eth(skb, priv->iw_mode); - - netdev->last_rx = jiffies; - netif_rx(skb); - stats->rx_packets++; - stats->rx_bytes += length; - - return; -} - -static void at76_rx_monitor_mode(struct at76_priv *priv) -{ - struct at76_rx_radiotap *rt; - u8 *payload; - int skblen; - struct net_device *netdev = priv->netdev; - struct at76_rx_buffer *buf = - (struct at76_rx_buffer *)priv->rx_skb->data; - /* length including the IEEE802.11 header and the trailing FCS, - but not at76_rx_buffer */ - int length = le16_to_cpu(buf->wlength); - struct sk_buff *skb = priv->rx_skb; - struct net_device_stats *stats = &priv->stats; - - if (length < IEEE80211_FCS_LEN) { - /* buffer contains no data */ - at76_dbg(DBG_MONITOR_MODE, - "%s: MONITOR MODE: rx skb without data", - priv->netdev->name); - return; - } - - skblen = sizeof(struct at76_rx_radiotap) + length; - - skb = dev_alloc_skb(skblen); - if (!skb) { - printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap " - "header returned NULL\n", priv->netdev->name); - return; - } - - skb_put(skb, skblen); - - rt = (struct at76_rx_radiotap *)skb->data; - payload = skb->data + sizeof(struct at76_rx_radiotap); - - rt->rt_hdr.it_version = 0; - rt->rt_hdr.it_pad = 0; - rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap)); - rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT); - - rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time)); - rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80); - rt->rt_signal = buf->rssi; - rt->rt_noise = buf->noise_level; - rt->rt_flags = IEEE80211_RADIOTAP_F_FCS; - if (buf->fragmentation) - rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG; - - memcpy(payload, buf->packet, length); - skb->dev = netdev; - skb->ip_summed = CHECKSUM_NONE; - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - - netdev->last_rx = jiffies; - netif_rx(skb); - stats->rx_packets++; - stats->rx_bytes += length; -} - -/* Check if we spy on the sender address in buf and update stats */ -static void at76_iwspy_update(struct at76_priv *priv, - struct at76_rx_buffer *buf) -{ - struct ieee80211_hdr_3addr *hdr = - (struct ieee80211_hdr_3addr *)buf->packet; - struct iw_quality qual; - - /* We can only set the level here */ - qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; - qual.level = 0; - qual.noise = 0; - at76_calc_level(priv, buf, &qual); - - spin_lock_bh(&priv->spy_spinlock); - - if (priv->spy_data.spy_number > 0) - wireless_spy_update(priv->netdev, hdr->addr2, &qual); - - spin_unlock_bh(&priv->spy_spinlock); -} - -static void at76_rx_tasklet(unsigned long param) -{ - struct urb *urb = (struct urb *)param; - struct at76_priv *priv = urb->context; - struct net_device *netdev = priv->netdev; - struct at76_rx_buffer *buf; - struct ieee80211_hdr_3addr *i802_11_hdr; - u16 frame_ctl; - - if (priv->device_unplugged) { - at76_dbg(DBG_DEVSTART, "device unplugged"); - if (urb) - at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); - return; - } - - if (!priv->rx_skb || !netdev || !priv->rx_skb->data) - return; - - buf = (struct at76_rx_buffer *)priv->rx_skb->data; - - i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet; - - frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); - - if (urb->status != 0) { - if (urb->status != -ENOENT && urb->status != -ECONNRESET) - at76_dbg(DBG_URB, - "%s %s: - nonzero Rx bulk status received: %d", - __func__, netdev->name, urb->status); - return; - } - - at76_dbg(DBG_RX_ATMEL_HDR, - "%s: rx frame: rate %d rssi %d noise %d link %d %s", - priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level, - buf->link_quality, hex2str(i802_11_hdr, 48)); - if (priv->iw_mode == IW_MODE_MONITOR) { - at76_rx_monitor_mode(priv); - goto exit; - } - - /* there is a new bssid around, accept it: */ - if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) { - at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name); - schedule_work(&priv->work_new_bss); - } - - switch (frame_ctl & IEEE80211_FCTL_FTYPE) { - case IEEE80211_FTYPE_DATA: - at76_rx_data(priv); - break; - - case IEEE80211_FTYPE_MGMT: - /* jal: TODO: find out if we can update iwspy also on - other frames than management (might depend on the - radio chip / firmware version !) */ - - at76_iwspy_update(priv, buf); - - at76_rx_mgmt(priv, buf); - break; - - case IEEE80211_FTYPE_CTL: - at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x", - priv->netdev->name, frame_ctl); - break; - - default: - printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", - priv->netdev->name, frame_ctl); - } -exit: - at76_submit_rx_urb(priv); -} - -/* Load firmware into kernel memory and parse it */ -static struct fwentry *at76_load_firmware(struct usb_device *udev, - enum board_type board_type) -{ - int ret; - char *str; - struct at76_fw_header *fwh; - struct fwentry *fwe = &firmwares[board_type]; - - mutex_lock(&fw_mutex); - - if (fwe->loaded) { - at76_dbg(DBG_FW, "re-using previously loaded fw"); - goto exit; - } - - at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); - ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); - if (ret < 0) { - dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", - fwe->fwname); - dev_printk(KERN_ERR, &udev->dev, - "you may need to download the firmware from " - "http://developer.berlios.de/projects/at76c503a/"); - goto exit; - } - - at76_dbg(DBG_FW, "got it."); - fwh = (struct at76_fw_header *)(fwe->fw->data); - - if (fwe->fw->size <= sizeof(*fwh)) { - dev_printk(KERN_ERR, &udev->dev, - "firmware is too short (0x%zx)\n", fwe->fw->size); - goto exit; - } - - /* CRC currently not checked */ - fwe->board_type = le32_to_cpu(fwh->board_type); - if (fwe->board_type != board_type) { - dev_printk(KERN_ERR, &udev->dev, - "board type mismatch, requested %u, got %u\n", - board_type, fwe->board_type); - goto exit; - } - - fwe->fw_version.major = fwh->major; - fwe->fw_version.minor = fwh->minor; - fwe->fw_version.patch = fwh->patch; - fwe->fw_version.build = fwh->build; - - str = (char *)fwh + le32_to_cpu(fwh->str_offset); - fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset); - fwe->intfw_size = le32_to_cpu(fwh->int_fw_len); - fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset); - fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len); - - fwe->loaded = 1; - - dev_printk(KERN_DEBUG, &udev->dev, - "using firmware %s (version %d.%d.%d-%d)\n", - fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build); - - at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type, - le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len), - le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len)); - at76_dbg(DBG_DEVSTART, "firmware id %s", str); - -exit: - mutex_unlock(&fw_mutex); - - if (fwe->loaded) - return fwe; - else - return NULL; -} - -/* Allocate network device and initialize private data */ -static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) -{ - struct net_device *netdev; - struct at76_priv *priv; - int i; - - /* allocate memory for our device state and initialize it */ - netdev = alloc_etherdev(sizeof(struct at76_priv)); - if (!netdev) { - dev_printk(KERN_ERR, &udev->dev, "out of memory\n"); - return NULL; - } - - priv = netdev_priv(netdev); - - priv->udev = udev; - priv->netdev = netdev; - - mutex_init(&priv->mtx); - INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done); - INIT_WORK(&priv->work_join, at76_work_join); - INIT_WORK(&priv->work_new_bss, at76_work_new_bss); - INIT_WORK(&priv->work_start_scan, at76_work_start_scan); - INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); - INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); - INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart); - INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan); - INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon); - INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth); - INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc); - - spin_lock_init(&priv->mgmt_spinlock); - priv->next_mgmt_bulk = NULL; - priv->mac_state = MAC_INIT; - - /* initialize empty BSS list */ - priv->curr_bss = NULL; - INIT_LIST_HEAD(&priv->bss_list); - spin_lock_init(&priv->bss_list_spinlock); - - init_timer(&priv->bss_list_timer); - priv->bss_list_timer.data = (unsigned long)priv; - priv->bss_list_timer.function = at76_bss_list_timeout; - - spin_lock_init(&priv->spy_spinlock); - - /* mark all rx data entries as unused */ - for (i = 0; i < NR_RX_DATA_BUF; i++) - priv->rx_data[i].skb = NULL; - - priv->rx_tasklet.func = at76_rx_tasklet; - priv->rx_tasklet.data = 0; - - priv->pm_mode = AT76_PM_OFF; - priv->pm_period = 0; - - return priv; -} - -static int at76_alloc_urbs(struct at76_priv *priv, - struct usb_interface *interface) -{ - struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out; - int i; - int buffer_size; - struct usb_host_interface *iface_desc; - - at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__); - - at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__, - interface->altsetting[0].desc.bNumEndpoints); - - ep_in = NULL; - ep_out = NULL; - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - endpoint = &iface_desc->endpoint[i].desc; - - at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x", - __func__, i, endpoint->bEndpointAddress, - endpoint->bmAttributes); - - if (!ep_in && usb_endpoint_is_bulk_in(endpoint)) - ep_in = endpoint; - - if (!ep_out && usb_endpoint_is_bulk_out(endpoint)) - ep_out = endpoint; - } - - if (!ep_in || !ep_out) { - dev_printk(KERN_ERR, &interface->dev, - "bulk endpoints missing\n"); - return -ENXIO; - } - - priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress); - priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress); - - priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->rx_urb || !priv->tx_urb) { - dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n"); - return -ENOMEM; - } - - buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; - priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!priv->bulk_out_buffer) { - dev_printk(KERN_ERR, &interface->dev, - "cannot allocate output buffer\n"); - return -ENOMEM; - } - - at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__); - - return 0; -} - -static const struct net_device_ops at76_netdev_ops = { - .ndo_open = at76_open, - .ndo_stop = at76_stop, - .ndo_get_stats = at76_get_stats, - .ndo_start_xmit = at76_tx, - .ndo_tx_timeout = at76_tx_timeout, - .ndo_set_multicast_list = at76_set_multicast, - .ndo_set_mac_address = at76_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, -}; - -/* Register network device and initialize the hardware */ -static int at76_init_new_device(struct at76_priv *priv, - struct usb_interface *interface) -{ - struct net_device *netdev = priv->netdev; - int ret; - - /* set up the endpoint information */ - /* check out the endpoints */ - - at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints", - interface->cur_altsetting->desc.bNumEndpoints); - - ret = at76_alloc_urbs(priv, interface); - if (ret < 0) - goto exit; - - /* MAC address */ - ret = at76_get_hw_config(priv); - if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "cannot get MAC address\n"); - goto exit; - } - - priv->domain = at76_get_reg_domain(priv->regulatory_domain); - /* init. netdev->dev_addr */ - memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN); - - priv->channel = DEF_CHANNEL; - priv->iw_mode = IW_MODE_INFRA; - priv->rts_threshold = DEF_RTS_THRESHOLD; - priv->frag_threshold = DEF_FRAG_THRESHOLD; - priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT; - priv->txrate = TX_RATE_AUTO; - priv->preamble_type = PREAMBLE_TYPE_LONG; - priv->beacon_period = 100; - priv->beacons_last_qual = jiffies; - priv->auth_mode = WLAN_AUTH_OPEN; - priv->scan_min_time = DEF_SCAN_MIN_TIME; - priv->scan_max_time = DEF_SCAN_MAX_TIME; - priv->scan_mode = SCAN_TYPE_ACTIVE; - - netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ - netdev->netdev_ops = &at76_netdev_ops; - netdev->ethtool_ops = &at76_ethtool_ops; - - /* Add pointers to enable iwspy support. */ - priv->wireless_data.spy_data = &priv->spy_data; -#ifdef CONFIG_WIRELESS_EXT - netdev->wireless_data = &priv->wireless_data; - netdev->wireless_handlers = &at76_handler_def; -#endif - - netdev->watchdog_timeo = 2 * HZ; - dev_alloc_name(netdev, "wlan%d"); - - ret = register_netdev(priv->netdev); - if (ret) { - dev_printk(KERN_ERR, &interface->dev, - "cannot register netdevice (status %d)!\n", ret); - goto exit; - } - priv->netdev_registered = 1; - - printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n", - netdev->name, dev_name(&interface->dev), priv->mac_addr, - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); - printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name, - priv->regulatory_domain, priv->domain->name); - - /* we let this timer run the whole time this driver instance lives */ - mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); - -exit: - return ret; -} - -static void at76_delete_device(struct at76_priv *priv) -{ - int i; - - at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__); - - /* The device is gone, don't bother turning it off */ - priv->device_unplugged = 1; - - if (priv->netdev_registered) - unregister_netdev(priv->netdev); - - /* assuming we used keventd, it must quiesce too */ - flush_scheduled_work(); - - kfree(priv->bulk_out_buffer); - - if (priv->tx_urb) { - usb_kill_urb(priv->tx_urb); - usb_free_urb(priv->tx_urb); - } - if (priv->rx_urb) { - usb_kill_urb(priv->rx_urb); - usb_free_urb(priv->rx_urb); - } - - at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__); - - kfree_skb(priv->rx_skb); - - at76_free_bss_list(priv); - del_timer_sync(&priv->bss_list_timer); - cancel_delayed_work(&priv->dwork_get_scan); - cancel_delayed_work(&priv->dwork_beacon); - cancel_delayed_work(&priv->dwork_auth); - cancel_delayed_work(&priv->dwork_assoc); - - if (priv->mac_state == MAC_CONNECTED) - at76_iwevent_bss_disconnect(priv->netdev); - - for (i = 0; i < NR_RX_DATA_BUF; i++) - if (priv->rx_data[i].skb) { - dev_kfree_skb(priv->rx_data[i].skb); - priv->rx_data[i].skb = NULL; - } - usb_put_dev(priv->udev); - - at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__); - free_netdev(priv->netdev); /* priv is in netdev */ - - at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__); -} - -static int at76_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - int ret; - struct at76_priv *priv; - struct fwentry *fwe; - struct usb_device *udev; - int op_mode; - int need_ext_fw = 0; - struct mib_fw_version fwv; - int board_type = (int)id->driver_info; - - udev = usb_get_dev(interface_to_usbdev(interface)); - - /* Load firmware into kernel memory */ - fwe = at76_load_firmware(udev, board_type); - if (!fwe) { - ret = -ENOENT; - goto error; - } - - op_mode = at76_get_op_mode(udev); - - at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); - - /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ??? - we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ - - if (op_mode == OPMODE_HW_CONFIG_MODE) { - dev_printk(KERN_ERR, &interface->dev, - "cannot handle a device in HW_CONFIG_MODE\n"); - ret = -EBUSY; - goto error; - } - - if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH - && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { - /* download internal firmware part */ - dev_printk(KERN_DEBUG, &interface->dev, - "downloading internal firmware\n"); - ret = at76_load_internal_fw(udev, fwe); - if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "error %d downloading internal firmware\n", - ret); - goto error; - } - usb_put_dev(udev); - return ret; - } - - /* Internal firmware already inside the device. Get firmware - * version to test if external firmware is loaded. - * This works only for newer firmware, e.g. the Intersil 0.90.x - * says "control timeout on ep0in" and subsequent - * at76_get_op_mode() fail too :-( */ - - /* if version >= 0.100.x.y or device with built-in flash we can - * query the device for the fw version */ - if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100) - || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) { - ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); - if (ret < 0 || (fwv.major | fwv.minor) == 0) - need_ext_fw = 1; - } else - /* No way to check firmware version, reload to be sure */ - need_ext_fw = 1; - - if (need_ext_fw) { - dev_printk(KERN_DEBUG, &interface->dev, - "downloading external firmware\n"); - - ret = at76_load_external_fw(udev, fwe); - if (ret) - goto error; - - /* Re-check firmware version */ - ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); - if (ret < 0) { - dev_printk(KERN_ERR, &interface->dev, - "error %d getting firmware version\n", ret); - goto error; - } - } - - priv = at76_alloc_new_device(udev); - if (!priv) { - ret = -ENOMEM; - goto error; - } - - SET_NETDEV_DEV(priv->netdev, &interface->dev); - usb_set_intfdata(interface, priv); - - memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version)); - priv->board_type = board_type; - - ret = at76_init_new_device(priv, interface); - if (ret < 0) - at76_delete_device(priv); - - return ret; - -error: - usb_put_dev(udev); - return ret; -} - -static void at76_disconnect(struct usb_interface *interface) -{ - struct at76_priv *priv; - - priv = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - /* Disconnect after loading internal firmware */ - if (!priv) - return; - - printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name); - at76_delete_device(priv); - dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); -} - -/* Structure for registering this driver with the USB subsystem */ -static struct usb_driver at76_driver = { - .name = DRIVER_NAME, - .probe = at76_probe, - .disconnect = at76_disconnect, - .id_table = dev_table, -}; - -static int __init at76_mod_init(void) -{ - int result; - - printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n"); - - mutex_init(&fw_mutex); - - /* register this driver with the USB subsystem */ - result = usb_register(&at76_driver); - if (result < 0) - printk(KERN_ERR DRIVER_NAME - ": usb_register failed (status %d)\n", result); - - led_trigger_register_simple("at76_usb-tx", &ledtrig_tx); - return result; -} - -static void __exit at76_mod_exit(void) -{ - int i; - - printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n"); - usb_deregister(&at76_driver); - for (i = 0; i < ARRAY_SIZE(firmwares); i++) { - if (firmwares[i].fw) - release_firmware(firmwares[i].fw); - } - led_trigger_unregister_simple(ledtrig_tx); -} - -module_param_named(debug, at76_debug, int, 0600); -MODULE_PARM_DESC(debug, "Debugging level"); - -module_init(at76_mod_init); -module_exit(at76_mod_exit); - -MODULE_AUTHOR("Oliver Kurth "); -MODULE_AUTHOR("Joerg Albert "); -MODULE_AUTHOR("Alex "); -MODULE_AUTHOR("Nick Jones"); -MODULE_AUTHOR("Balint Seeber "); -MODULE_AUTHOR("Pavel Roskin "); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h deleted file mode 100644 index 6d60c6e23a0..00000000000 --- a/drivers/staging/at76_usb/at76_usb.h +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright (c) 2002,2003 Oliver Kurth - * (c) 2003,2004 Joerg Albert - * (c) 2007 Guido Guenther - * - * 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 driver was based on information from the Sourceforge driver - * released and maintained by Atmel: - * - * http://sourceforge.net/projects/atmelwlandriver/ - * - * Although the code was completely re-written, - * it would have been impossible without Atmel's decision to - * release an Open Source driver (unfortunately the firmware was - * kept binary only). Thanks for that decision to Atmel! - */ - -#ifndef _AT76_USB_H -#define _AT76_USB_H - -/* - * ieee80211 definitions copied from net/ieee80211.h - */ - -#define WEP_KEY_LEN 13 -#define WEP_KEYS 4 - -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ - -#define IEEE80211_1ADDR_LEN 10 -#define IEEE80211_2ADDR_LEN 16 -#define IEEE80211_3ADDR_LEN 24 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_FCS_LEN 4 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - -struct ieee80211_info_element { - u8 id; - u8 len; - u8 data[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_auth { - struct ieee80211_hdr_3addr header; - __le16 algorithm; - __le16 transaction; - __le16 status; - /* challenge */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_assoc_request { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_probe_response { - struct ieee80211_hdr_3addr header; - __le32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -/* Alias beacon for probe_response */ -#define ieee80211_beacon ieee80211_probe_response - -struct ieee80211_assoc_response { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 status; - __le16 aid; - /* supported rates */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_disassoc { - struct ieee80211_hdr_3addr header; - __le16 reason; -} __attribute__ ((packed)); - -/* Board types */ -enum board_type { - BOARD_503_ISL3861 = 1, - BOARD_503_ISL3863 = 2, - BOARD_503 = 3, - BOARD_503_ACC = 4, - BOARD_505 = 5, - BOARD_505_2958 = 6, - BOARD_505A = 7, - BOARD_505AMX = 8 -}; - -/* our private ioctl's */ -/* preamble length (0 - long, 1 - short, 2 - auto) */ -#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0) -#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1) -/* which debug channels are enabled */ -#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2) -#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3) -/* power save mode (incl. the Atmel proprietary smart save mode) */ -#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4) -#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5) -/* min and max channel times for scan */ -#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6) -#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7) -/* scan mode (0 - active, 1 - passive) */ -#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8) -#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9) - -#define CMD_STATUS_IDLE 0x00 -#define CMD_STATUS_COMPLETE 0x01 -#define CMD_STATUS_UNKNOWN 0x02 -#define CMD_STATUS_INVALID_PARAMETER 0x03 -#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04 -#define CMD_STATUS_TIME_OUT 0x07 -#define CMD_STATUS_IN_PROGRESS 0x08 -#define CMD_STATUS_HOST_FAILURE 0xff -#define CMD_STATUS_SCAN_FAILED 0xf0 - -/* answers to get op mode */ -#define OPMODE_NONE 0x00 -#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01 -#define OPMODE_HW_CONFIG_MODE 0x02 -#define OPMODE_DFU_MODE_WITH_FLASH 0x03 -#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04 - -#define CMD_SET_MIB 0x01 -#define CMD_GET_MIB 0x02 -#define CMD_SCAN 0x03 -#define CMD_JOIN 0x04 -#define CMD_START_IBSS 0x05 -#define CMD_RADIO_ON 0x06 -#define CMD_RADIO_OFF 0x07 -#define CMD_STARTUP 0x0B - -#define MIB_LOCAL 0x01 -#define MIB_MAC_ADDR 0x02 -#define MIB_MAC 0x03 -#define MIB_MAC_MGMT 0x05 -#define MIB_MAC_WEP 0x06 -#define MIB_PHY 0x07 -#define MIB_FW_VERSION 0x08 -#define MIB_MDOMAIN 0x09 - -#define ADHOC_MODE 1 -#define INFRASTRUCTURE_MODE 2 - -/* values for struct mib_local, field preamble_type */ -#define PREAMBLE_TYPE_LONG 0 -#define PREAMBLE_TYPE_SHORT 1 -#define PREAMBLE_TYPE_AUTO 2 - -/* values for tx_rate */ -#define TX_RATE_1MBIT 0 -#define TX_RATE_2MBIT 1 -#define TX_RATE_5_5MBIT 2 -#define TX_RATE_11MBIT 3 -#define TX_RATE_AUTO 4 - -/* power management modes */ -#define AT76_PM_OFF 1 -#define AT76_PM_ON 2 -#define AT76_PM_SMART 3 - -struct hwcfg_r505 { - u8 cr39_values[14]; - u8 reserved1[14]; - u8 bb_cr[14]; - u8 pidvid[4]; - u8 mac_addr[ETH_ALEN]; - u8 regulatory_domain; - u8 reserved2[14]; - u8 cr15_values[14]; - u8 reserved3[3]; -} __attribute__((packed)); - -struct hwcfg_rfmd { - u8 cr20_values[14]; - u8 cr21_values[14]; - u8 bb_cr[14]; - u8 pidvid[4]; - u8 mac_addr[ETH_ALEN]; - u8 regulatory_domain; - u8 low_power_values[14]; - u8 normal_power_values[14]; - u8 reserved1[3]; -} __attribute__((packed)); - -struct hwcfg_intersil { - u8 mac_addr[ETH_ALEN]; - u8 cr31_values[14]; - u8 cr58_values[14]; - u8 pidvid[4]; - u8 regulatory_domain; - u8 reserved[1]; -} __attribute__((packed)); - -union at76_hwcfg { - struct hwcfg_intersil i; - struct hwcfg_rfmd r3; - struct hwcfg_r505 r5; -}; - -#define WEP_SMALL_KEY_LEN (40 / 8) -#define WEP_LARGE_KEY_LEN (104 / 8) - -struct at76_card_config { - u8 exclude_unencrypted; - u8 promiscuous_mode; - u8 short_retry_limit; - u8 encryption_type; - __le16 rts_threshold; - __le16 fragmentation_threshold; /* 256..2346 */ - u8 basic_rate_set[4]; - u8 auto_rate_fallback; /* 0,1 */ - u8 channel; - u8 privacy_invoked; - u8 wep_default_key_id; /* 0..3 */ - u8 current_ssid[32]; - u8 wep_default_key_value[4][WEP_KEY_LEN]; - u8 ssid_len; - u8 short_preamble; - __le16 beacon_period; -} __attribute__((packed)); - -struct at76_command { - u8 cmd; - u8 reserved; - __le16 size; - u8 data[0]; -} __attribute__((packed)); - -/* Length of Atmel-specific Rx header before 802.11 frame */ -#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet) - -struct at76_rx_buffer { - __le16 wlength; - u8 rx_rate; - u8 newbss; - u8 fragmentation; - u8 rssi; - u8 link_quality; - u8 noise_level; - __le32 rx_time; - u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; -} __attribute__((packed)); - -/* Length of Atmel-specific Tx header before 802.11 frame */ -#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet) - -struct at76_tx_buffer { - __le16 wlength; - u8 tx_rate; - u8 padding; - u8 reserved[4]; - u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; -} __attribute__((packed)); - -/* defines for scan_type below */ -#define SCAN_TYPE_ACTIVE 0 -#define SCAN_TYPE_PASSIVE 1 - -struct at76_req_scan { - u8 bssid[ETH_ALEN]; - u8 essid[32]; - u8 scan_type; - u8 channel; - __le16 probe_delay; - __le16 min_channel_time; - __le16 max_channel_time; - u8 essid_size; - u8 international_scan; -} __attribute__((packed)); - -struct at76_req_ibss { - u8 bssid[ETH_ALEN]; - u8 essid[32]; - u8 bss_type; - u8 channel; - u8 essid_size; - u8 reserved[3]; -} __attribute__((packed)); - -struct at76_req_join { - u8 bssid[ETH_ALEN]; - u8 essid[32]; - u8 bss_type; - u8 channel; - __le16 timeout; - u8 essid_size; - u8 reserved; -} __attribute__((packed)); - -struct set_mib_buffer { - u8 type; - u8 size; - u8 index; - u8 reserved; - union { - u8 byte; - __le16 word; - u8 addr[ETH_ALEN]; - } data; -} __attribute__((packed)); - -struct mib_local { - u16 reserved0; - u8 beacon_enable; - u8 txautorate_fallback; - u8 reserved1; - u8 ssid_size; - u8 promiscuous_mode; - u16 reserved2; - u8 preamble_type; - u16 reserved3; -} __attribute__((packed)); - -struct mib_mac_addr { - u8 mac_addr[ETH_ALEN]; - u8 res[2]; /* ??? */ - u8 group_addr[4][ETH_ALEN]; - u8 group_addr_status[4]; -} __attribute__((packed)); - -struct mib_mac { - __le32 max_tx_msdu_lifetime; - __le32 max_rx_lifetime; - __le16 frag_threshold; - __le16 rts_threshold; - __le16 cwmin; - __le16 cwmax; - u8 short_retry_time; - u8 long_retry_time; - u8 scan_type; /* active or passive */ - u8 scan_channel; - __le16 probe_delay; /* delay before ProbeReq in active scan, RO */ - __le16 min_channel_time; - __le16 max_channel_time; - __le16 listen_interval; - u8 desired_ssid[32]; - u8 desired_bssid[ETH_ALEN]; - u8 desired_bsstype; /* ad-hoc or infrastructure */ - u8 reserved2; -} __attribute__((packed)); - -struct mib_mac_mgmt { - __le16 beacon_period; - __le16 CFP_max_duration; - __le16 medium_occupancy_limit; - __le16 station_id; /* assoc id */ - __le16 ATIM_window; - u8 CFP_mode; - u8 privacy_option_implemented; - u8 DTIM_period; - u8 CFP_period; - u8 current_bssid[ETH_ALEN]; - u8 current_essid[32]; - u8 current_bss_type; - u8 power_mgmt_mode; - /* rfmd and 505 */ - u8 ibss_change; - u8 res; - u8 multi_domain_capability_implemented; - u8 multi_domain_capability_enabled; - u8 country_string[3]; - u8 reserved[3]; -} __attribute__((packed)); - -struct mib_mac_wep { - u8 privacy_invoked; /* 0 disable encr., 1 enable encr */ - u8 wep_default_key_id; - u8 wep_key_mapping_len; - u8 exclude_unencrypted; - __le32 wep_icv_error_count; - __le32 wep_excluded_count; - u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN]; - u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */ -} __attribute__((packed)); - -struct mib_phy { - __le32 ed_threshold; - - __le16 slot_time; - __le16 sifs_time; - __le16 preamble_length; - __le16 plcp_header_length; - __le16 mpdu_max_length; - __le16 cca_mode_supported; - - u8 operation_rate_set[4]; - u8 channel_id; - u8 current_cca_mode; - u8 phy_type; - u8 current_reg_domain; -} __attribute__((packed)); - -struct mib_fw_version { - u8 major; - u8 minor; - u8 patch; - u8 build; -} __attribute__((packed)); - -struct mib_mdomain { - u8 tx_powerlevel[14]; - u8 channel_list[14]; /* 0 for invalid channels */ -} __attribute__((packed)); - -struct at76_fw_header { - __le32 crc; /* CRC32 of the whole image */ - __le32 board_type; /* firmware compatibility code */ - u8 build; /* firmware build number */ - u8 patch; /* firmware patch level */ - u8 minor; /* firmware minor version */ - u8 major; /* firmware major version */ - __le32 str_offset; /* offset of the copyright string */ - __le32 int_fw_offset; /* internal firmware image offset */ - __le32 int_fw_len; /* internal firmware image length */ - __le32 ext_fw_offset; /* external firmware image offset */ - __le32 ext_fw_len; /* external firmware image length */ -} __attribute__((packed)); - -enum mac_state { - MAC_INIT, - MAC_SCANNING, - MAC_AUTH, - MAC_ASSOC, - MAC_JOINING, - MAC_CONNECTED, - MAC_OWN_IBSS -}; - -/* a description of a regulatory domain and the allowed channels */ -struct reg_domain { - u16 code; - char const *name; - u32 channel_map; /* if bit N is set, channel (N+1) is allowed */ -}; - -/* how long do we keep a (I)BSS in the bss_list in jiffies - this should be long enough for the user to retrieve the table - (by iwlist ?) after the device started, because all entries from - other channels than the one the device locks on get removed, too */ -#define BSS_LIST_TIMEOUT (120 * HZ) -/* struct to store BSS info found during scan */ -#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */ - -struct bss_info { - struct list_head list; - - u8 bssid[ETH_ALEN]; /* bssid */ - u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */ - u8 ssid_len; /* length of ssid above */ - u8 channel; - u16 capa; /* BSS capabilities */ - u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */ - u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of - 500 kbps, ORed with 0x80 for - basic rates */ - u8 rates_len; - - /* quality of received beacon */ - u8 rssi; - u8 link_qual; - u8 noise_level; - - unsigned long last_rx; /* time (jiffies) of last beacon received */ -}; - -/* a rx data buffer to collect rx fragments */ -struct rx_data_buf { - u8 sender[ETH_ALEN]; /* sender address */ - u16 seqnr; /* sequence number */ - u16 fragnr; /* last fragment received */ - unsigned long last_rx; /* jiffies of last rx */ - struct sk_buff *skb; /* == NULL if entry is free */ -}; - -#define NR_RX_DATA_BUF 8 - -/* Data for one loaded firmware file */ -struct fwentry { - const char *const fwname; - const struct firmware *fw; - int extfw_size; - int intfw_size; - /* pointer to loaded firmware, no need to free */ - u8 *extfw; /* external firmware, extfw_size bytes long */ - u8 *intfw; /* internal firmware, intfw_size bytes long */ - enum board_type board_type; /* board type */ - struct mib_fw_version fw_version; - int loaded; /* Loaded and parsed successfully */ -}; - -struct at76_priv { - struct usb_device *udev; /* USB device pointer */ - struct net_device *netdev; /* net device pointer */ - struct net_device_stats stats; /* net device stats */ - struct iw_statistics wstats; /* wireless stats */ - - struct sk_buff *rx_skb; /* skbuff for receiving data */ - void *bulk_out_buffer; /* buffer for sending data */ - - struct urb *tx_urb; /* URB for sending data */ - struct urb *rx_urb; /* URB for receiving data */ - - unsigned int tx_pipe; /* bulk out pipe */ - unsigned int rx_pipe; /* bulk in pipe */ - - struct mutex mtx; /* locks this structure */ - - /* work queues */ - struct work_struct work_assoc_done; - struct work_struct work_join; - struct work_struct work_new_bss; - struct work_struct work_start_scan; - struct work_struct work_set_promisc; - struct work_struct work_submit_rx; - struct delayed_work dwork_restart; - struct delayed_work dwork_get_scan; - struct delayed_work dwork_beacon; - struct delayed_work dwork_auth; - struct delayed_work dwork_assoc; - - struct tasklet_struct rx_tasklet; - - /* the WEP stuff */ - int wep_enabled; /* 1 if WEP is enabled */ - int wep_key_id; /* key id to be used */ - u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys, - 5 or 13 bytes are used */ - u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */ - - int channel; - int iw_mode; - u8 bssid[ETH_ALEN]; - u8 essid[IW_ESSID_MAX_SIZE]; - int essid_size; - int radio_on; - int promisc; - - int preamble_type; /* 0 - long, 1 - short, 2 - auto */ - int auth_mode; /* authentication type: 0 open, 1 shared key */ - int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */ - int frag_threshold; /* threshold for fragmentation of tx packets */ - int rts_threshold; /* threshold for RTS mechanism */ - int short_retry_limit; - - int scan_min_time; /* scan min channel time */ - int scan_max_time; /* scan max channel time */ - int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ - int scan_need_any; /* if set, need to scan for any ESSID */ - - /* the list we got from scanning */ - spinlock_t bss_list_spinlock; /* protects bss_list operations */ - struct list_head bss_list; /* list of BSS we got beacons from */ - struct timer_list bss_list_timer; /* timer to purge old entries - from bss_list */ - struct bss_info *curr_bss; /* current BSS */ - u16 assoc_id; /* current association ID, if associated */ - - u8 wanted_bssid[ETH_ALEN]; - int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */ - - /* some data for infrastructure mode only */ - spinlock_t mgmt_spinlock; /* this spinlock protects access to - next_mgmt_bulk */ - - struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to - send via bulk out */ - enum mac_state mac_state; - enum { - SCAN_IDLE, - SCAN_IN_PROGRESS, - SCAN_COMPLETED - } scan_state; - time_t last_scan; - - int retries; /* remaining retries in case of timeout when - * sending AuthReq or AssocReq */ - u8 pm_mode; /* power management mode */ - u32 pm_period; /* power management period in microseconds */ - - struct reg_domain const *domain; /* reg domain description */ - - /* iwspy support */ - spinlock_t spy_spinlock; - struct iw_spy_data spy_data; - - struct iw_public_data wireless_data; - - /* These fields contain HW config provided by the device (not all of - * these fields are used by all board types) */ - u8 mac_addr[ETH_ALEN]; - u8 regulatory_domain; - - struct at76_card_config card_config; - - /* store rx fragments until complete */ - struct rx_data_buf rx_data[NR_RX_DATA_BUF]; - - enum board_type board_type; - struct mib_fw_version fw_version; - - unsigned int device_unplugged:1; - unsigned int netdev_registered:1; - struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */ - - /* beacon counting */ - int beacon_period; /* period of mgmt beacons, Kus */ - int beacons_received; - unsigned long beacons_last_qual; /* time we restarted counting - beacons */ -}; - -struct at76_rx_radiotap { - struct ieee80211_radiotap_header rt_hdr; - __le64 rt_tsft; - u8 rt_flags; - u8 rt_rate; - s8 rt_signal; - s8 rt_noise; -}; - -#define AT76_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_TSFT) | \ - (1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTNOISE)) - -#define BEACON_MAX_DATA_LENGTH 1500 - -/* the maximum size of an AssocReq packet */ -#define ASSOCREQ_MAX_SIZE \ - (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \ - 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4) - -/* for shared secret auth, add the challenge text size */ -#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth)) - -/* Maximal number of AuthReq retries */ -#define AUTH_RETRIES 3 - -/* Maximal number of AssocReq retries */ -#define ASSOC_RETRIES 3 - -/* Beacon timeout in managed mode when we are connected */ -#define BEACON_TIMEOUT (10 * HZ) - -/* Timeout for authentication response */ -#define AUTH_TIMEOUT (1 * HZ) - -/* Timeout for association response */ -#define ASSOC_TIMEOUT (1 * HZ) - -/* Polling interval when scan is running */ -#define SCAN_POLL_INTERVAL (HZ / 4) - -/* Command completion timeout */ -#define CMD_COMPLETION_TIMEOUT (5 * HZ) - -#define DEF_RTS_THRESHOLD 1536 -#define DEF_FRAG_THRESHOLD 1536 -#define DEF_SHORT_RETRY_LIMIT 8 -#define DEF_CHANNEL 10 -#define DEF_SCAN_MIN_TIME 10 -#define DEF_SCAN_MAX_TIME 120 - -#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1) - -/* the max padding size for tx in bytes (see calc_padding) */ -#define MAX_PADDING_SIZE 53 - -#endif /* _AT76_USB_H */ -- cgit v1.2.3 From 0b33559a1adb3b9953503c9b55a61c37db34ffc0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Sep 2009 09:46:35 -0700 Subject: Staging: remove heci driver Intel has officially abandoned this project and does not want to maintian it or have it included in the main kernel tree, as no one should use the code, it's not needed anymore. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/heci/Kconfig | 7 - drivers/staging/heci/Makefile | 9 - drivers/staging/heci/TODO | 6 - drivers/staging/heci/heci.h | 175 --- drivers/staging/heci/heci_data_structures.h | 529 --------- drivers/staging/heci/heci_init.c | 1083 ------------------ drivers/staging/heci/heci_interface.c | 498 --------- drivers/staging/heci/heci_interface.h | 170 --- drivers/staging/heci/heci_main.c | 1576 --------------------------- drivers/staging/heci/heci_version.h | 54 - drivers/staging/heci/interrupt.c | 1555 -------------------------- drivers/staging/heci/io_heci.c | 872 --------------- 14 files changed, 6537 deletions(-) delete mode 100644 drivers/staging/heci/Kconfig delete mode 100644 drivers/staging/heci/Makefile delete mode 100644 drivers/staging/heci/TODO delete mode 100644 drivers/staging/heci/heci.h delete mode 100644 drivers/staging/heci/heci_data_structures.h delete mode 100644 drivers/staging/heci/heci_init.c delete mode 100644 drivers/staging/heci/heci_interface.c delete mode 100644 drivers/staging/heci/heci_interface.h delete mode 100644 drivers/staging/heci/heci_main.c delete mode 100644 drivers/staging/heci/heci_version.h delete mode 100644 drivers/staging/heci/interrupt.c delete mode 100644 drivers/staging/heci/io_heci.c (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 66188a5bf44..e86a6716156 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -103,8 +103,6 @@ source "drivers/staging/phison/Kconfig" source "drivers/staging/p9auth/Kconfig" -source "drivers/staging/heci/Kconfig" - source "drivers/staging/line6/Kconfig" source "drivers/gpu/drm/radeon/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3c64d5fad65..fa5361664ba 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_STLC45XX) += stlc45xx/ obj-$(CONFIG_B3DFG) += b3dfg/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_PLAN9AUTH) += p9auth/ -obj-$(CONFIG_HECI) += heci/ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ diff --git a/drivers/staging/heci/Kconfig b/drivers/staging/heci/Kconfig deleted file mode 100644 index c7206f8bcd9..00000000000 --- a/drivers/staging/heci/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config HECI - tristate "Intel Management Engine Interface (MEI) Support" - depends on PCI - ---help--- - The Intel Management Engine Interface (Intel MEI) driver allows - applications to access the Active Management Technology - firmware and other Management Engine sub-systems. diff --git a/drivers/staging/heci/Makefile b/drivers/staging/heci/Makefile deleted file mode 100644 index 0524856fa3a..00000000000 --- a/drivers/staging/heci/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-$(CONFIG_HECI) += heci.o - -heci-objs := \ - heci_init.o \ - interrupt.o \ - heci_interface.o \ - io_heci.o \ - heci_main.o - diff --git a/drivers/staging/heci/TODO b/drivers/staging/heci/TODO deleted file mode 100644 index f86715d631c..00000000000 --- a/drivers/staging/heci/TODO +++ /dev/null @@ -1,6 +0,0 @@ -TODO: - - fix user/kernel pointer mess in the ioctl handlers as pointed - out by sparse. - - resolve the ioctls and see if most of them can just be simple - sysfs files - - fix locking issues that sparse points out at the least. diff --git a/drivers/staging/heci/heci.h b/drivers/staging/heci/heci.h deleted file mode 100644 index 48f120dc3b2..00000000000 --- a/drivers/staging/heci/heci.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#ifndef _HECI_H_ -#define _HECI_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "heci_data_structures.h" - -extern const struct guid heci_pthi_guid; -extern const struct guid heci_wd_guid; -extern const __u8 heci_start_wd_params[]; -extern const __u8 heci_stop_wd_params[]; -extern const __u8 heci_wd_state_independence_msg[3][4]; - -/* - * heci device ID - */ -#define HECI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ -#define HECI_DEV_ID_82G35 0x2984 /* 82G35 Express */ -#define HECI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ -#define HECI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ - -#define HECI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ -#define HECI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ - -#define HECI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ -#define HECI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ -#define HECI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ -#define HECI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ -#define HECI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ - -#define HECI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ -#define HECI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ -#define HECI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ -#define HECI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ -#define HECI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ - -#define HECI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ -#define HECI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ -#define HECI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ -#define HECI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ - -#define HECI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ -#define HECI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ -#define HECI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ -#define HECI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ - -/* - * heci init function prototypes - */ -struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); -void heci_reset(struct iamt_heci_device *dev, int interrupts); -int heci_hw_init(struct iamt_heci_device *dev); -int heci_task_initialize_clients(void *data); -int heci_initialize_clients(struct iamt_heci_device *dev); -struct heci_file_private *heci_alloc_file_private(struct file *file); -int heci_disconnect_host_client(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); -void heci_initialize_list(struct io_heci_list *list, - struct iamt_heci_device *dev); -void heci_flush_list(struct io_heci_list *list, - struct heci_file_private *file_ext); -void heci_flush_queues(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); - -void heci_remove_client_from_file_list(struct iamt_heci_device *dev, - __u8 host_client_id); - -/* - * interrupt function prototype - */ -irqreturn_t heci_isr_interrupt(int irq, void *dev_id); - -void heci_wd_timer(unsigned long data); - -/* - * input output function prototype - */ -int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num, - struct heci_message_data __user *u_msg, - struct heci_message_data k_msg, - struct heci_file_private *file_ext); - -int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, - struct heci_message_data __user *u_msg, - struct heci_message_data k_msg, - struct file *file); - -int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num, - struct heci_message_data k_msg, - struct heci_file_private *file_ext); - -int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num, - struct heci_message_data k_msg, - struct heci_file_private *file_ext); - -int heci_start_read(struct iamt_heci_device *dev, int if_num, - struct heci_file_private *file_ext); - -int pthi_write(struct iamt_heci_device *dev, - struct heci_cb_private *priv_cb); - -int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file, - char __user *ubuf, size_t length, loff_t *offset); - -struct heci_cb_private *find_pthi_read_list_entry( - struct iamt_heci_device *dev, - struct file *file); - -void run_next_iamthif_cmd(struct iamt_heci_device *dev); - -void heci_free_cb_private(struct heci_cb_private *priv_cb); - -/** - * heci_fe_same_id - tell if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns !=0 - if ids are the same, 0 - if differ. - */ -static inline int heci_fe_same_id(const struct heci_file_private *fe1, - const struct heci_file_private *fe2) -{ - return ((fe1->host_client_id == fe2->host_client_id) - && (fe1->me_client_id == fe2->me_client_id)); -} - -#endif /* _HECI_H_ */ diff --git a/drivers/staging/heci/heci_data_structures.h b/drivers/staging/heci/heci_data_structures.h deleted file mode 100644 index ff30386d097..00000000000 --- a/drivers/staging/heci/heci_data_structures.h +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#ifndef _HECI_DATA_STRUCTURES_H_ -#define _HECI_DATA_STRUCTURES_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * error code definition - */ -#define ESLOTS_OVERFLOW 1 -#define ECORRUPTED_MESSAGE_HEADER 1000 -#define ECOMPLETE_MESSAGE 1001 - -#define HECI_FC_MESSAGE_RESERVED_LENGTH 5 - -/* - * Number of queue lists used by this driver - */ -#define HECI_IO_LISTS_NUMBER 7 - -/* - * Maximum transmission unit (MTU) of heci messages - */ -#define IAMTHIF_MTU 4160 - - -/* - * HECI HW Section - */ - -/* HECI registers */ -/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ -#define H_CB_WW 0 -/* H_CSR - Host Control Status register */ -#define H_CSR 4 -/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ -#define ME_CB_RW 8 -/* ME_CSR_HA - ME Control Status Host Access register (read only) */ -#define ME_CSR_HA 0xC - - -/* register bits of H_CSR (Host Control Status register) */ -/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ -#define H_CBD 0xFF000000 -/* Host Circular Buffer Write Pointer */ -#define H_CBWP 0x00FF0000 -/* Host Circular Buffer Read Pointer */ -#define H_CBRP 0x0000FF00 -/* Host Reset */ -#define H_RST 0x00000010 -/* Host Ready */ -#define H_RDY 0x00000008 -/* Host Interrupt Generate */ -#define H_IG 0x00000004 -/* Host Interrupt Status */ -#define H_IS 0x00000002 -/* Host Interrupt Enable */ -#define H_IE 0x00000001 - - -/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ -/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - * - host read only access to ME_CBD */ -#define ME_CBD_HRA 0xFF000000 -/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ -#define ME_CBWP_HRA 0x00FF0000 -/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ -#define ME_CBRP_HRA 0x0000FF00 -/* ME Reset HRA - host read only access to ME_RST */ -#define ME_RST_HRA 0x00000010 -/* ME Ready HRA - host read only access to ME_RDY */ -#define ME_RDY_HRA 0x00000008 -/* ME Interrupt Generate HRA - host read only access to ME_IG */ -#define ME_IG_HRA 0x00000004 -/* ME Interrupt Status HRA - host read only access to ME_IS */ -#define ME_IS_HRA 0x00000002 -/* ME Interrupt Enable HRA - host read only access to ME_IE */ -#define ME_IE_HRA 0x00000001 - -#define HECI_MINORS_BASE 1 -#define HECI_MINORS_COUNT 1 - -#define HECI_MINOR_NUMBER 1 -#define HECI_MAX_OPEN_HANDLE_COUNT 253 - -/* - * debug kernel print macro define - */ -extern int heci_debug; - -#define DBG(format, arg...) do { \ - if (heci_debug) \ - printk(KERN_INFO "heci: %s: " format, __func__, ## arg); \ -} while (0) - - -/* - * time to wait HECI become ready after init - */ -#define HECI_INTEROP_TIMEOUT (HZ * 7) - -/* - * watch dog definition - */ -#define HECI_WATCHDOG_DATA_SIZE 16 -#define HECI_START_WD_DATA_SIZE 20 -#define HECI_WD_PARAMS_SIZE 4 -#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) - -#define HECI_WD_HOST_CLIENT_ID 1 -#define HECI_IAMTHIF_HOST_CLIENT_ID 2 - -struct guid { - __u32 data1; - __u16 data2; - __u16 data3; - __u8 data4[8]; -}; - -/* File state */ -enum file_state { - HECI_FILE_INITIALIZING = 0, - HECI_FILE_CONNECTING, - HECI_FILE_CONNECTED, - HECI_FILE_DISCONNECTING, - HECI_FILE_DISCONNECTED -}; - -/* HECI device states */ -enum heci_states { - HECI_INITIALIZING = 0, - HECI_ENABLED, - HECI_RESETING, - HECI_DISABLED, - HECI_RECOVERING_FROM_RESET, - HECI_POWER_DOWN, - HECI_POWER_UP -}; - -enum iamthif_states { - HECI_IAMTHIF_IDLE, - HECI_IAMTHIF_WRITING, - HECI_IAMTHIF_FLOW_CONTROL, - HECI_IAMTHIF_READING, - HECI_IAMTHIF_READ_COMPLETE -}; - -enum heci_file_transaction_states { - HECI_IDLE, - HECI_WRITING, - HECI_WRITE_COMPLETE, - HECI_FLOW_CONTROL, - HECI_READING, - HECI_READ_COMPLETE -}; - -/* HECI CB */ -enum heci_cb_major_types { - HECI_READ = 0, - HECI_WRITE, - HECI_IOCTL, - HECI_OPEN, - HECI_CLOSE -}; - -/* HECI user data struct */ -struct heci_message_data { - __u32 size; - char *data; -} __attribute__((packed)); - -#define HECI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ - -#define IAMTHIF_STALL_TIMER 12 /* seconds */ -#define IAMTHIF_READ_TIMER 15 /* seconds */ - -struct heci_cb_private { - struct list_head cb_list; - enum heci_cb_major_types major_file_operations; - void *file_private; - struct heci_message_data request_buffer; - struct heci_message_data response_buffer; - unsigned long information; - unsigned long read_time; - struct file *file_object; -}; - -/* Private file struct */ -struct heci_file_private { - struct list_head link; - struct file *file; - enum file_state state; - wait_queue_head_t tx_wait; - wait_queue_head_t rx_wait; - wait_queue_head_t wait; - spinlock_t file_lock; /* file lock */ - spinlock_t read_io_lock; /* read lock */ - spinlock_t write_io_lock; /* write lock */ - int read_pending; - int status; - /* ID of client connected */ - __u8 host_client_id; - __u8 me_client_id; - __u8 flow_ctrl_creds; - __u8 timer_count; - enum heci_file_transaction_states reading_state; - enum heci_file_transaction_states writing_state; - int sm_state; - struct heci_cb_private *read_cb; -}; - -struct io_heci_list { - struct heci_cb_private heci_cb; - int status; - struct iamt_heci_device *device_extension; -}; - -struct heci_driver_version { - __u8 major; - __u8 minor; - __u8 hotfix; - __u16 build; -} __attribute__((packed)); - - -struct heci_client { - __u32 max_msg_length; - __u8 protocol_version; -} __attribute__((packed)); - -/* - * HECI BUS Interface Section - */ -struct heci_msg_hdr { - __u32 me_addr:8; - __u32 host_addr:8; - __u32 length:9; - __u32 reserved:6; - __u32 msg_complete:1; -} __attribute__((packed)); - - -struct hbm_cmd { - __u8 cmd:7; - __u8 is_response:1; -} __attribute__((packed)); - - -struct heci_bus_message { - struct hbm_cmd cmd; - __u8 command_specific_data[]; -} __attribute__((packed)); - -struct hbm_version { - __u8 minor_version; - __u8 major_version; -} __attribute__((packed)); - -struct hbm_host_version_request { - struct hbm_cmd cmd; - __u8 reserved; - struct hbm_version host_version; -} __attribute__((packed)); - -struct hbm_host_version_response { - struct hbm_cmd cmd; - int host_version_supported; - struct hbm_version me_max_version; -} __attribute__((packed)); - -struct hbm_host_stop_request { - struct hbm_cmd cmd; - __u8 reason; - __u8 reserved[2]; -} __attribute__((packed)); - -struct hbm_host_stop_response { - struct hbm_cmd cmd; - __u8 reserved[3]; -} __attribute__((packed)); - -struct hbm_me_stop_request { - struct hbm_cmd cmd; - __u8 reason; - __u8 reserved[2]; -} __attribute__((packed)); - -struct hbm_host_enum_request { - struct hbm_cmd cmd; - __u8 reserved[3]; -} __attribute__((packed)); - -struct hbm_host_enum_response { - struct hbm_cmd cmd; - __u8 reserved[3]; - __u8 valid_addresses[32]; -} __attribute__((packed)); - -struct heci_client_properties { - struct guid protocol_name; - __u8 protocol_version; - __u8 max_number_of_connections; - __u8 fixed_address; - __u8 single_recv_buf; - __u32 max_msg_length; -} __attribute__((packed)); - -struct hbm_props_request { - struct hbm_cmd cmd; - __u8 address; - __u8 reserved[2]; -} __attribute__((packed)); - - -struct hbm_props_response { - struct hbm_cmd cmd; - __u8 address; - __u8 status; - __u8 reserved[1]; - struct heci_client_properties client_properties; -} __attribute__((packed)); - -struct hbm_client_connect_request { - struct hbm_cmd cmd; - __u8 me_addr; - __u8 host_addr; - __u8 reserved; -} __attribute__((packed)); - -struct hbm_client_connect_response { - struct hbm_cmd cmd; - __u8 me_addr; - __u8 host_addr; - __u8 status; -} __attribute__((packed)); - -struct hbm_client_disconnect_request { - struct hbm_cmd cmd; - __u8 me_addr; - __u8 host_addr; - __u8 reserved[1]; -} __attribute__((packed)); - -struct hbm_flow_control { - struct hbm_cmd cmd; - __u8 me_addr; - __u8 host_addr; - __u8 reserved[HECI_FC_MESSAGE_RESERVED_LENGTH]; -} __attribute__((packed)); - -struct heci_me_client { - struct heci_client_properties props; - __u8 client_id; - __u8 flow_ctrl_creds; -} __attribute__((packed)); - -/* private device struct */ -struct iamt_heci_device { - struct pci_dev *pdev; /* pointer to pci device struct */ - /* - * lists of queues - */ - /* array of pointers to aio lists */ - struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER]; - struct io_heci_list read_list; /* driver read queue */ - struct io_heci_list write_list; /* driver write queue */ - struct io_heci_list write_waiting_list; /* write waiting queue */ - struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */ - struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */ - struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */ - - /* driver managed PTHI list for reading completed pthi cmd data */ - struct io_heci_list pthi_read_complete_list; - /* - * list of files - */ - struct list_head file_list; - /* - * memory of device - */ - unsigned int mem_base; - unsigned int mem_length; - void __iomem *mem_addr; - /* - * lock for the device - */ - spinlock_t device_lock; /* device lock*/ - struct work_struct work; - int recvd_msg; - - struct task_struct *reinit_tsk; - - struct timer_list wd_timer; - /* - * hw states of host and fw(ME) - */ - __u32 host_hw_state; - __u32 me_hw_state; - /* - * waiting queue for receive message from FW - */ - wait_queue_head_t wait_recvd_msg; - wait_queue_head_t wait_stop_wd; - /* - * heci device states - */ - enum heci_states heci_state; - int stop; - - __u32 extra_write_index; - __u32 rd_msg_buf[128]; /* used for control messages */ - __u32 wr_msg_buf[128]; /* used for control messages */ - __u32 ext_msg_buf[8]; /* for control responses */ - __u32 rd_msg_hdr; - - struct hbm_version version; - - int host_buffer_is_empty; - struct heci_file_private wd_file_ext; - struct heci_me_client *me_clients; /* Note: memory has to be allocated*/ - __u8 heci_me_clients[32]; /* list of existing clients */ - __u8 num_heci_me_clients; - __u8 heci_host_clients[32]; /* list of existing clients */ - __u8 current_host_client_id; - - int wd_pending; - int wd_stoped; - __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ - unsigned char wd_data[HECI_START_WD_DATA_SIZE]; - - - __u16 wd_due_counter; - int asf_mode; - int wd_bypass; /* if 1, don't refresh watchdog ME client */ - - struct file *iamthif_file_object; - struct heci_file_private iamthif_file_ext; - int iamthif_ioctl; - int iamthif_canceled; - __u32 iamthif_timer; - __u32 iamthif_stall_timer; - unsigned char iamthif_msg_buf[IAMTHIF_MTU]; - __u32 iamthif_msg_buf_size; - __u32 iamthif_msg_buf_index; - int iamthif_flow_control_pending; - enum iamthif_states iamthif_state; - - struct heci_cb_private *iamthif_current_cb; - __u8 write_hang; - int need_reset; - long open_handle_count; - -}; - -/** - * read_heci_register - Read a byte from the heci device - * - * @dev: the device structure - * @offset: offset from which to read the data - * - * returns the byte read. - */ -static inline __u32 read_heci_register(struct iamt_heci_device *dev, - unsigned long offset) -{ - return readl(dev->mem_addr + offset); -} - -/** - * write_heci_register - Write 4 bytes to the heci device - * - * @dev: the device structure - * @offset: offset from which to write the data - * @value: the byte to write - */ -static inline void write_heci_register(struct iamt_heci_device *dev, - unsigned long offset, __u32 value) -{ - writel(value, dev->mem_addr + offset); -} - -#endif /* _HECI_DATA_STRUCTURES_H_ */ diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c deleted file mode 100644 index 31fd891c099..00000000000 --- a/drivers/staging/heci/heci_init.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "heci_data_structures.h" -#include "heci_interface.h" -#include "heci.h" - - -const __u8 heci_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -const __u8 heci_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; - -const __u8 heci_wd_state_independence_msg[3][4] = { - {0x05, 0x02, 0x51, 0x10}, - {0x05, 0x02, 0x52, 0x10}, - {0x07, 0x02, 0x01, 0x10} -}; - -static const struct guid heci_asf_guid = { - 0x75B30CD6, 0xA29E, 0x4AF7, - {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6} -}; -const struct guid heci_wd_guid = { - 0x05B79A6F, 0x4628, 0x4D7F, - {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB} -}; -const struct guid heci_pthi_guid = { - 0x12f80028, 0xb4b7, 0x4b2d, - {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c} -}; - - -/* - * heci init function prototypes - */ -static void heci_check_asf_mode(struct iamt_heci_device *dev); -static int host_start_message(struct iamt_heci_device *dev); -static int host_enum_clients_message(struct iamt_heci_device *dev); -static int allocate_me_clients_storage(struct iamt_heci_device *dev); -static void host_init_wd(struct iamt_heci_device *dev); -static void host_init_iamthif(struct iamt_heci_device *dev); -static int heci_wait_event_int_timeout(struct iamt_heci_device *dev, - long timeout); - - -/** - * heci_initialize_list - Sets up a queue list. - * - * @list: An instance of our list structure - * @dev: Device object for our driver - */ -void heci_initialize_list(struct io_heci_list *list, - struct iamt_heci_device *dev) -{ - /* initialize our queue list */ - INIT_LIST_HEAD(&list->heci_cb.cb_list); - list->status = 0; - list->device_extension = dev; -} - -/** - * heci_flush_queues - flush our queues list belong to file_ext. - * - * @dev: Device object for our driver - * @file_ext: private data of the file object - */ -void heci_flush_queues(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - int i; - - if (!dev || !file_ext) - return; - - /* flush our queue list belong to file_ext */ - for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) { - DBG("remove list entry belong to file_ext\n"); - heci_flush_list(dev->io_list_array[i], file_ext); - } -} - - -/** - * heci_flush_list - remove list entry belong to file_ext. - * - * @list: An instance of our list structure - * @file_ext: private data of the file object - */ -void heci_flush_list(struct io_heci_list *list, - struct heci_file_private *file_ext) -{ - struct heci_file_private *file_ext_tmp; - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - - if (!list || !file_ext) - return; - - if (list->status != 0) - return; - - if (list_empty(&list->heci_cb.cb_list)) - return; - - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &list->heci_cb.cb_list, cb_list) { - if (priv_cb_pos) { - file_ext_tmp = (struct heci_file_private *) - priv_cb_pos->file_private; - if (file_ext_tmp) { - if (heci_fe_same_id(file_ext, file_ext_tmp)) - list_del(&priv_cb_pos->cb_list); - } - } - } -} - -/** - * heci_reset_iamthif_params - initializes heci device iamthif - * - * @dev: The heci device structure - */ -static void heci_reset_iamthif_params(struct iamt_heci_device *dev) -{ - /* reset iamthif parameters. */ - dev->iamthif_current_cb = NULL; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_file_ext.file = NULL; - dev->iamthif_ioctl = 0; - dev->iamthif_state = HECI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; -} - -/** - * init_heci_device - allocates and initializes the heci device structure - * - * @pdev: The pci device structure - * - * returns The heci_device_device pointer on success, NULL on failure. - */ -struct iamt_heci_device *init_heci_device(struct pci_dev *pdev) -{ - int i; - struct iamt_heci_device *dev; - - dev = kzalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); - if (!dev) - return NULL; - - /* setup our list array */ - dev->io_list_array[0] = &dev->read_list; - dev->io_list_array[1] = &dev->write_list; - dev->io_list_array[2] = &dev->write_waiting_list; - dev->io_list_array[3] = &dev->ctrl_wr_list; - dev->io_list_array[4] = &dev->ctrl_rd_list; - dev->io_list_array[5] = &dev->pthi_cmd_list; - dev->io_list_array[6] = &dev->pthi_read_complete_list; - INIT_LIST_HEAD(&dev->file_list); - INIT_LIST_HEAD(&dev->wd_file_ext.link); - INIT_LIST_HEAD(&dev->iamthif_file_ext.link); - spin_lock_init(&dev->device_lock); - init_waitqueue_head(&dev->wait_recvd_msg); - init_waitqueue_head(&dev->wait_stop_wd); - dev->heci_state = HECI_INITIALIZING; - dev->iamthif_state = HECI_IAMTHIF_IDLE; - - /* init work for schedule work */ - INIT_WORK(&dev->work, NULL); - for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) - heci_initialize_list(dev->io_list_array[i], dev); - dev->pdev = pdev; - return dev; -} - - - - -static int heci_wait_event_int_timeout(struct iamt_heci_device *dev, - long timeout) -{ - return wait_event_interruptible_timeout(dev->wait_recvd_msg, - (dev->recvd_msg), timeout); -} - -/** - * heci_hw_init - init host and fw to start work. - * - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -int heci_hw_init(struct iamt_heci_device *dev) -{ - int err = 0; - - dev->host_hw_state = read_heci_register(dev, H_CSR); - dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); - DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if ((dev->host_hw_state & H_IS) == H_IS) { - /* acknowledge interrupt and stop interupts */ - heci_csr_clear_his(dev); - } - dev->recvd_msg = 0; - DBG("reset in start the heci device.\n"); - - heci_reset(dev, 1); - - DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - /* wait for ME to turn on ME_RDY */ - if (!dev->recvd_msg) - err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT); - - if (!err && !dev->recvd_msg) { - dev->heci_state = HECI_DISABLED; - DBG("wait_event_interruptible_timeout failed" - "on wait for ME to turn on ME_RDY.\n"); - return -ENODEV; - } else { - if (!(((dev->host_hw_state & H_RDY) == H_RDY) - && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { - dev->heci_state = HECI_DISABLED; - DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, - dev->me_hw_state); - - if (!(dev->host_hw_state & H_RDY) != H_RDY) - DBG("host turn off H_RDY.\n"); - - if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - DBG("ME turn off ME_RDY.\n"); - - printk(KERN_ERR - "heci: link layer initialization failed.\n"); - return -ENODEV; - } - } - dev->recvd_msg = 0; - DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - DBG("ME turn on ME_RDY and host turn on H_RDY.\n"); - printk(KERN_INFO "heci: link layer has been established.\n"); - return 0; -} - -/** - * heci_hw_reset - reset fw via heci csr register. - * - * @dev: Device object for our driver - * @interrupts: if interrupt should be enable after reset. - */ -static void heci_hw_reset(struct iamt_heci_device *dev, int interrupts) -{ - dev->host_hw_state |= (H_RST | H_IG); - - if (interrupts) - heci_csr_enable_interrupts(dev); - else - heci_csr_disable_interrupts(dev); - - BUG_ON((dev->host_hw_state & H_RST) != H_RST); - BUG_ON((dev->host_hw_state & H_RDY) != 0); -} - -/** - * heci_reset - reset host and fw. - * - * @dev: Device object for our driver - * @interrupts: if interrupt should be enable after reset. - */ -void heci_reset(struct iamt_heci_device *dev, int interrupts) -{ - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - int unexpected = 0; - - if (dev->heci_state == HECI_RECOVERING_FROM_RESET) { - dev->need_reset = 1; - return; - } - - if (dev->heci_state != HECI_INITIALIZING && - dev->heci_state != HECI_DISABLED && - dev->heci_state != HECI_POWER_DOWN && - dev->heci_state != HECI_POWER_UP) - unexpected = 1; - - if (dev->reinit_tsk != NULL) { - kthread_stop(dev->reinit_tsk); - dev->reinit_tsk = NULL; - } - - dev->host_hw_state = read_heci_register(dev, H_CSR); - - DBG("before reset host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - heci_hw_reset(dev, interrupts); - - dev->host_hw_state &= ~H_RST; - dev->host_hw_state |= H_IG; - - heci_set_csr_register(dev); - - DBG("currently saved host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - dev->need_reset = 0; - - if (dev->heci_state != HECI_INITIALIZING) { - if ((dev->heci_state != HECI_DISABLED) && - (dev->heci_state != HECI_POWER_DOWN)) - dev->heci_state = HECI_RESETING; - - list_for_each_entry_safe(file_pos, - file_next, &dev->file_list, link) { - file_pos->state = HECI_FILE_DISCONNECTED; - file_pos->flow_ctrl_creds = 0; - file_pos->read_cb = NULL; - file_pos->timer_count = 0; - } - /* remove entry if already in list */ - DBG("list del iamthif and wd file list.\n"); - heci_remove_client_from_file_list(dev, - dev->wd_file_ext.host_client_id); - - heci_remove_client_from_file_list(dev, - dev->iamthif_file_ext.host_client_id); - - heci_reset_iamthif_params(dev); - dev->wd_due_counter = 0; - dev->extra_write_index = 0; - } - - dev->num_heci_me_clients = 0; - dev->rd_msg_hdr = 0; - dev->stop = 0; - dev->wd_pending = 0; - - /* update the state of the registers after reset */ - dev->host_hw_state = read_heci_register(dev, H_CSR); - dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); - - DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if (unexpected) - printk(KERN_WARNING "heci: unexpected reset.\n"); - - /* Wake up all readings so they can be interrupted */ - list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) { - if (&file_pos->rx_wait && - waitqueue_active(&file_pos->rx_wait)) { - printk(KERN_INFO "heci: Waking up client!\n"); - wake_up_interruptible(&file_pos->rx_wait); - } - } - /* remove all waiting requests */ - if (dev->write_list.status == 0 && - !list_empty(&dev->write_list.heci_cb.cb_list)) { - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->write_list.heci_cb.cb_list, cb_list) { - if (priv_cb_pos) { - list_del(&priv_cb_pos->cb_list); - heci_free_cb_private(priv_cb_pos); - } - } - } -} - -/** - * heci_initialize_clients - heci communication initialization. - * - * @dev: Device object for our driver - */ -int heci_initialize_clients(struct iamt_heci_device *dev) -{ - int status; - - msleep(100); /* FW needs time to be ready to talk with us */ - DBG("link is established start sending messages.\n"); - /* link is established start sending messages. */ - status = host_start_message(dev); - if (status != 0) { - spin_lock_bh(&dev->device_lock); - dev->heci_state = HECI_DISABLED; - spin_unlock_bh(&dev->device_lock); - DBG("start sending messages failed.\n"); - return status; - } - - /* enumerate clients */ - status = host_enum_clients_message(dev); - if (status != 0) { - spin_lock_bh(&dev->device_lock); - dev->heci_state = HECI_DISABLED; - spin_unlock_bh(&dev->device_lock); - DBG("enum clients failed.\n"); - return status; - } - /* allocate storage for ME clients representation */ - status = allocate_me_clients_storage(dev); - if (status != 0) { - spin_lock_bh(&dev->device_lock); - dev->num_heci_me_clients = 0; - dev->heci_state = HECI_DISABLED; - spin_unlock_bh(&dev->device_lock); - DBG("allocate clients failed.\n"); - return status; - } - - heci_check_asf_mode(dev); - /*heci initialization wd */ - host_init_wd(dev); - /*heci initialization iamthif client */ - host_init_iamthif(dev); - - spin_lock_bh(&dev->device_lock); - if (dev->need_reset) { - dev->need_reset = 0; - dev->heci_state = HECI_DISABLED; - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - - memset(dev->heci_host_clients, 0, sizeof(dev->heci_host_clients)); - dev->open_handle_count = 0; - dev->heci_host_clients[0] |= 7; - dev->current_host_client_id = 3; - dev->heci_state = HECI_ENABLED; - spin_unlock_bh(&dev->device_lock); - DBG("initialization heci clients successful.\n"); - return 0; -} - -/** - * heci_task_initialize_clients - heci reinitialization task - * - * @data: Device object for our driver - */ -int heci_task_initialize_clients(void *data) -{ - int ret; - struct iamt_heci_device *dev = (struct iamt_heci_device *) data; - - spin_lock_bh(&dev->device_lock); - if (dev->reinit_tsk != NULL) { - spin_unlock_bh(&dev->device_lock); - DBG("reinit task already started.\n"); - return 0; - } - dev->reinit_tsk = current; - current->flags |= PF_NOFREEZE; - spin_unlock_bh(&dev->device_lock); - - ret = heci_initialize_clients(dev); - - spin_lock_bh(&dev->device_lock); - dev->reinit_tsk = NULL; - spin_unlock_bh(&dev->device_lock); - - return ret; -} - -/** - * host_start_message - heci host send start message. - * - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -static int host_start_message(struct iamt_heci_device *dev) -{ - long timeout = 60; /* 60 second */ - - struct heci_msg_hdr *heci_hdr; - struct hbm_host_version_request *host_start_req; - struct hbm_host_stop_request *host_stop_req; - int err = 0; - - /* host start message */ - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_host_version_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - host_start_req = - (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; - memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); - host_start_req->cmd.cmd = HOST_START_REQ_CMD; - host_start_req->host_version.major_version = HBM_MAJOR_VERSION; - host_start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->recvd_msg = 0; - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) (host_start_req), - heci_hdr->length)) { - DBG("send version to fw fail.\n"); - return -ENODEV; - } - DBG("call wait_event_interruptible_timeout for response message.\n"); - /* wait for response */ - err = heci_wait_event_int_timeout(dev, timeout * HZ); - if (!err && !dev->recvd_msg) { - DBG("wait_timeout failed on host start response message.\n"); - return -ENODEV; - } - dev->recvd_msg = 0; - DBG("wait_timeout successful on host start response message.\n"); - if ((dev->version.major_version != HBM_MAJOR_VERSION) || - (dev->version.minor_version != HBM_MINOR_VERSION)) { - /* send stop message */ - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_host_stop_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - host_stop_req = - (struct hbm_host_stop_request *) &dev->wr_msg_buf[1]; - - memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); - host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - heci_write_message(dev, heci_hdr, - (unsigned char *) (host_stop_req), - heci_hdr->length); - DBG("version mismatch.\n"); - return -ENODEV; - } - - return 0; -} - -/** - * host_enum_clients_message - host send enumeration client request message. - * - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -static int host_enum_clients_message(struct iamt_heci_device *dev) -{ - long timeout = 5; /*5 second */ - struct heci_msg_hdr *heci_hdr; - struct hbm_host_enum_request *host_enum_req; - int err = 0; - int i, j; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - /* enumerate clients */ - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_host_enum_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; - memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); - host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD; - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) (host_enum_req), - heci_hdr->length)) { - DBG("send enumeration request failed.\n"); - return -ENODEV; - } - /* wait for response */ - dev->recvd_msg = 0; - err = heci_wait_event_int_timeout(dev, timeout * HZ); - if (!err && !dev->recvd_msg) { - DBG("wait_event_interruptible_timeout failed " - "on enumeration clients response message.\n"); - return -ENODEV; - } - dev->recvd_msg = 0; - - spin_lock_bh(&dev->device_lock); - /* count how many ME clients we have */ - for (i = 0; i < sizeof(dev->heci_me_clients); i++) { - for (j = 0; j < 8; j++) { - if ((dev->heci_me_clients[i] & (1 << j)) != 0) - dev->num_heci_me_clients++; - - } - } - spin_unlock_bh(&dev->device_lock); - - return 0; -} - -/** - * host_client_properties - reads properties for client - * - * @dev: Device object for our driver - * @idx: client index in me client array - * @client_id: id of the client - * - * returns 0 on success, <0 on failure. - */ -static int host_client_properties(struct iamt_heci_device *dev, - struct heci_me_client *client) -{ - struct heci_msg_hdr *heci_hdr; - struct hbm_props_request *host_cli_req; - int err; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_props_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - host_cli_req = (struct hbm_props_request *) &dev->wr_msg_buf[1]; - memset(host_cli_req, 0, sizeof(struct hbm_props_request)); - host_cli_req->cmd.cmd = HOST_CLIENT_PROPERTEIS_REQ_CMD; - host_cli_req->address = client->client_id; - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) (host_cli_req), - heci_hdr->length)) { - DBG("send props request failed.\n"); - return -ENODEV; - } - /* wait for response */ - dev->recvd_msg = 0; - err = heci_wait_event_int_timeout(dev, 10 * HZ); - if (!err && !dev->recvd_msg) { - DBG("wait failed on props resp msg.\n"); - return -ENODEV; - } - dev->recvd_msg = 0; - return 0; -} - -/** - * allocate_me_clients_storage - allocate storage for me clients - * - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -static int allocate_me_clients_storage(struct iamt_heci_device *dev) -{ - struct heci_me_client *clients; - struct heci_me_client *client; - __u8 num, i, j; - int err; - - if (dev->num_heci_me_clients <= 0) - return 0; - - spin_lock_bh(&dev->device_lock); - kfree(dev->me_clients); - dev->me_clients = NULL; - spin_unlock_bh(&dev->device_lock); - - /* allocate storage for ME clients representation */ - clients = kcalloc(dev->num_heci_me_clients, - sizeof(struct heci_me_client), GFP_KERNEL); - if (!clients) { - DBG("memory allocation for ME clients failed.\n"); - return -ENOMEM; - } - - spin_lock_bh(&dev->device_lock); - dev->me_clients = clients; - spin_unlock_bh(&dev->device_lock); - - num = 0; - for (i = 0; i < sizeof(dev->heci_me_clients); i++) { - for (j = 0; j < 8; j++) { - if ((dev->heci_me_clients[i] & (1 << j)) != 0) { - client = &dev->me_clients[num]; - client->client_id = (i * 8) + j; - client->flow_ctrl_creds = 0; - err = host_client_properties(dev, client); - if (err != 0) { - spin_lock_bh(&dev->device_lock); - kfree(dev->me_clients); - dev->me_clients = NULL; - spin_unlock_bh(&dev->device_lock); - return err; - } - num++; - } - } - } - - return 0; -} - -/** - * heci_init_file_private - initializes private file structure. - * - * @priv: private file structure to be initialized - * @file: the file structure - */ -static void heci_init_file_private(struct heci_file_private *priv, - struct file *file) -{ - memset(priv, 0, sizeof(struct heci_file_private)); - spin_lock_init(&priv->file_lock); - spin_lock_init(&priv->read_io_lock); - spin_lock_init(&priv->write_io_lock); - init_waitqueue_head(&priv->wait); - init_waitqueue_head(&priv->rx_wait); - DBG("priv->rx_wait =%p\n", &priv->rx_wait); - init_waitqueue_head(&priv->tx_wait); - INIT_LIST_HEAD(&priv->link); - priv->reading_state = HECI_IDLE; - priv->writing_state = HECI_IDLE; -} - -/** - * heci_find_me_client - search for ME client guid - * sets client_id in heci_file_private if found - * @dev: Device object for our driver - * @priv: private file structure to set client_id in - * @cguid: searched guid of ME client - * @client_id: id of host client to be set in file private structure - * - * returns ME client index - */ -static __u8 heci_find_me_client(struct iamt_heci_device *dev, - struct heci_file_private *priv, - const struct guid *cguid, __u8 client_id) -{ - __u8 i; - - if ((dev == NULL) || (priv == NULL) || (cguid == NULL)) - return 0; - - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (memcmp(cguid, - &dev->me_clients[i].props.protocol_name, - sizeof(struct guid)) == 0) { - priv->me_client_id = dev->me_clients[i].client_id; - priv->state = HECI_FILE_CONNECTING; - priv->host_client_id = client_id; - - list_add_tail(&priv->link, &dev->file_list); - return i; - } - } - return 0; -} - -/** - * heci_check_asf_mode - check for ASF client - * - * @dev: Device object for our driver - */ -static void heci_check_asf_mode(struct iamt_heci_device *dev) -{ - __u8 i; - - spin_lock_bh(&dev->device_lock); - dev->asf_mode = 0; - /* find ME ASF client - otherwise assume AMT mode */ - DBG("find ME ASF client - otherwise assume AMT mode.\n"); - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (memcmp(&heci_asf_guid, - &dev->me_clients[i].props.protocol_name, - sizeof(struct guid)) == 0) { - dev->asf_mode = 1; - spin_unlock_bh(&dev->device_lock); - DBG("found ME ASF client.\n"); - return; - } - } - spin_unlock_bh(&dev->device_lock); - DBG("assume AMT mode.\n"); -} - -/** - * heci_connect_me_client - connect ME client - * @dev: Device object for our driver - * @priv: private file structure - * @timeout: connect timeout in seconds - * - * returns 1 - if connected, 0 - if not - */ -static __u8 heci_connect_me_client(struct iamt_heci_device *dev, - struct heci_file_private *priv, - long timeout) -{ - int err = 0; - - if ((dev == NULL) || (priv == NULL)) - return 0; - - if (!heci_connect(dev, priv)) { - DBG("failed to call heci_connect for client_id=%d.\n", - priv->host_client_id); - spin_lock_bh(&dev->device_lock); - heci_remove_client_from_file_list(dev, priv->host_client_id); - priv->state = HECI_FILE_DISCONNECTED; - spin_unlock_bh(&dev->device_lock); - return 0; - } - - err = wait_event_timeout(dev->wait_recvd_msg, - (HECI_FILE_CONNECTED == priv->state || - HECI_FILE_DISCONNECTED == priv->state), - timeout * HZ); - if (HECI_FILE_CONNECTED != priv->state) { - spin_lock_bh(&dev->device_lock); - heci_remove_client_from_file_list(dev, priv->host_client_id); - DBG("failed to connect client_id=%d state=%d.\n", - priv->host_client_id, priv->state); - if (err) - DBG("failed connect err=%08x\n", err); - priv->state = HECI_FILE_DISCONNECTED; - spin_unlock_bh(&dev->device_lock); - return 0; - } - DBG("successfully connected client_id=%d.\n", - priv->host_client_id); - return 1; -} - -/** - * host_init_wd - heci initialization wd. - * - * @dev: Device object for our driver - */ -static void host_init_wd(struct iamt_heci_device *dev) -{ - spin_lock_bh(&dev->device_lock); - - heci_init_file_private(&dev->wd_file_ext, NULL); - - /* look for WD client and connect to it */ - dev->wd_file_ext.state = HECI_FILE_DISCONNECTED; - dev->wd_timeout = 0; - - if (dev->asf_mode) { - memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE); - } else { - /* AMT mode */ - dev->wd_timeout = AMT_WD_VALUE; - DBG("dev->wd_timeout=%d.\n", dev->wd_timeout); - memcpy(dev->wd_data, heci_start_wd_params, HECI_WD_PARAMS_SIZE); - memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE, - &dev->wd_timeout, sizeof(__u16)); - } - - /* find ME WD client */ - heci_find_me_client(dev, &dev->wd_file_ext, - &heci_wd_guid, HECI_WD_HOST_CLIENT_ID); - spin_unlock_bh(&dev->device_lock); - - DBG("check wd_file_ext\n"); - if (HECI_FILE_CONNECTING == dev->wd_file_ext.state) { - if (heci_connect_me_client(dev, &dev->wd_file_ext, 15) == 1) { - DBG("dev->wd_timeout=%d.\n", dev->wd_timeout); - if (dev->wd_timeout != 0) - dev->wd_due_counter = 1; - else - dev->wd_due_counter = 0; - DBG("successfully connected to WD client.\n"); - } - } else - DBG("failed to find WD client.\n"); - - - spin_lock_bh(&dev->device_lock); - dev->wd_timer.function = &heci_wd_timer; - dev->wd_timer.data = (unsigned long) dev; - spin_unlock_bh(&dev->device_lock); -} - - -/** - * host_init_iamthif - heci initialization iamthif client. - * - * @dev: Device object for our driver - * - */ -static void host_init_iamthif(struct iamt_heci_device *dev) -{ - __u8 i; - - spin_lock_bh(&dev->device_lock); - - heci_init_file_private(&dev->iamthif_file_ext, NULL); - dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTED; - - /* find ME PTHI client */ - i = heci_find_me_client(dev, &dev->iamthif_file_ext, - &heci_pthi_guid, HECI_IAMTHIF_HOST_CLIENT_ID); - if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTING) { - DBG("failed to find iamthif client.\n"); - spin_unlock_bh(&dev->device_lock); - return; - } - - BUG_ON(dev->me_clients[i].props.max_msg_length != IAMTHIF_MTU); - - spin_unlock_bh(&dev->device_lock); - if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) { - DBG("connected to iamthif client.\n"); - dev->iamthif_state = HECI_IAMTHIF_IDLE; - } -} - -/** - * heci_alloc_file_private - allocates a private file structure and set it up. - * @file: the file structure - * - * returns The allocated file or NULL on failure - */ -struct heci_file_private *heci_alloc_file_private(struct file *file) -{ - struct heci_file_private *priv; - - priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL); - if (!priv) - return NULL; - - heci_init_file_private(priv, file); - - return priv; -} - - - -/** - * heci_disconnect_host_client - send disconnect message to fw from host client. - * - * @dev: Device object for our driver - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_disconnect_host_client(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - int rets, err; - long timeout = 15; /* 15 seconds */ - struct heci_cb_private *priv_cb; - - if ((!dev) || (!file_ext)) - return -ENODEV; - - spin_lock_bh(&dev->device_lock); - if (file_ext->state != HECI_FILE_DISCONNECTING) { - spin_unlock_bh(&dev->device_lock); - return 0; - } - spin_unlock_bh(&dev->device_lock); - - priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); - if (!priv_cb) - return -ENOMEM; - - INIT_LIST_HEAD(&priv_cb->cb_list); - priv_cb->file_private = file_ext; - priv_cb->major_file_operations = HECI_CLOSE; - spin_lock_bh(&dev->device_lock); - if (dev->host_buffer_is_empty) { - dev->host_buffer_is_empty = 0; - if (heci_disconnect(dev, file_ext)) { - mdelay(10); /* Wait for hardware disconnection ready */ - list_add_tail(&priv_cb->cb_list, - &dev->ctrl_rd_list.heci_cb.cb_list); - } else { - spin_unlock_bh(&dev->device_lock); - rets = -ENODEV; - DBG("failed to call heci_disconnect.\n"); - goto free; - } - } else { - DBG("add disconnect cb to control write list\n"); - list_add_tail(&priv_cb->cb_list, - &dev->ctrl_wr_list.heci_cb.cb_list); - } - spin_unlock_bh(&dev->device_lock); - - err = wait_event_timeout(dev->wait_recvd_msg, - (HECI_FILE_DISCONNECTED == file_ext->state), - timeout * HZ); - - spin_lock_bh(&dev->device_lock); - if (HECI_FILE_DISCONNECTED == file_ext->state) { - rets = 0; - DBG("successfully disconnected from fw client.\n"); - } else { - rets = -ENODEV; - if (HECI_FILE_DISCONNECTED != file_ext->state) - DBG("wrong status client disconnect.\n"); - - if (err) - DBG("wait failed disconnect err=%08x\n", err); - - DBG("failed to disconnect from fw client.\n"); - } - - heci_flush_list(&dev->ctrl_rd_list, file_ext); - heci_flush_list(&dev->ctrl_wr_list, file_ext); - spin_unlock_bh(&dev->device_lock); -free: - heci_free_cb_private(priv_cb); - return rets; -} - -/** - * heci_remove_client_from_file_list - - * remove file private data from device file list - * - * @dev: Device object for our driver - * @host_client_id: host client id to be removed - */ -void heci_remove_client_from_file_list(struct iamt_heci_device *dev, - __u8 host_client_id) -{ - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) { - if (host_client_id == file_pos->host_client_id) { - DBG("remove host client = %d, ME client = %d\n", - file_pos->host_client_id, - file_pos->me_client_id); - list_del_init(&file_pos->link); - break; - } - } -} diff --git a/drivers/staging/heci/heci_interface.c b/drivers/staging/heci/heci_interface.c deleted file mode 100644 index 03e1df1a88a..00000000000 --- a/drivers/staging/heci/heci_interface.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - - -#include "heci.h" -#include "heci_interface.h" - - -/** - * heci_set_csr_register - write H_CSR register to the heci device, - * and ignore the H_IS bit for it is write-one-to-zero. - * - * @dev: device object for our driver - */ -void heci_set_csr_register(struct iamt_heci_device *dev) -{ - if ((dev->host_hw_state & H_IS) == H_IS) - dev->host_hw_state &= ~H_IS; - write_heci_register(dev, H_CSR, dev->host_hw_state); - dev->host_hw_state = read_heci_register(dev, H_CSR); -} - -/** - * heci_csr_enable_interrupts - enable heci device interrupts - * - * @dev: device object for our driver - */ -void heci_csr_enable_interrupts(struct iamt_heci_device *dev) -{ - dev->host_hw_state |= H_IE; - heci_set_csr_register(dev); -} - -/** - * heci_csr_disable_interrupts - disable heci device interrupts - * - * @dev: device object for our driver - */ -void heci_csr_disable_interrupts(struct iamt_heci_device *dev) -{ - dev->host_hw_state &= ~H_IE; - heci_set_csr_register(dev); -} - -/** - * heci_csr_clear_his - clear H_IS bit in H_CSR - * - * @dev: device object for our driver - */ -void heci_csr_clear_his(struct iamt_heci_device *dev) -{ - write_heci_register(dev, H_CSR, dev->host_hw_state); - dev->host_hw_state = read_heci_register(dev, H_CSR); -} - -/** - * _host_get_filled_slots - get number of device filled buffer slots - * - * @device: the device structure - * - * returns numer of filled slots - */ -static unsigned char _host_get_filled_slots(const struct iamt_heci_device *dev) -{ - char read_ptr, write_ptr; - - read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); - write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); - - return (unsigned char) (write_ptr - read_ptr); -} - -/** - * host_buffer_is_empty - check if host buffer is empty. - * - * @dev: device object for our driver - * - * returns 1 if empty, 0 - otherwise. - */ -int host_buffer_is_empty(struct iamt_heci_device *dev) -{ - unsigned char filled_slots; - - dev->host_hw_state = read_heci_register(dev, H_CSR); - filled_slots = _host_get_filled_slots(dev); - - if (filled_slots > 0) - return 0; - - return 1; -} - -/** - * count_empty_write_slots - count write empty slots. - * - * @dev: device object for our driver - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count - */ -__s32 count_empty_write_slots(const struct iamt_heci_device *dev) -{ - unsigned char buffer_depth, filled_slots, empty_slots; - - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - - if (filled_slots > buffer_depth) { - /* overflow */ - return -ESLOTS_OVERFLOW; - } - - return (__s32) empty_slots; -} - -/** - * heci_write_message - write a message to heci device. - * - * @dev: device object for our driver - * @heci_hdr: header of message - * @write_buffer: message buffer will be write - * @write_length: message size will be write - * - * returns 1 if success, 0 - otherwise. - */ -int heci_write_message(struct iamt_heci_device *dev, - struct heci_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length) -{ - __u32 temp_msg = 0; - unsigned long bytes_written = 0; - unsigned char buffer_depth, filled_slots, empty_slots; - unsigned long dw_to_write; - - dev->host_hw_state = read_heci_register(dev, H_CSR); - DBG("host_hw_state = 0x%08x.\n", dev->host_hw_state); - DBG("heci_write_message header=%08x.\n", *((__u32 *) header)); - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots); - - dw_to_write = ((write_length + 3) / 4); - - if (dw_to_write > empty_slots) - return 0; - - write_heci_register(dev, H_CB_WW, *((__u32 *) header)); - - while (write_length >= 4) { - write_heci_register(dev, H_CB_WW, - *(__u32 *) (write_buffer + bytes_written)); - bytes_written += 4; - write_length -= 4; - } - - if (write_length > 0) { - memcpy(&temp_msg, &write_buffer[bytes_written], write_length); - write_heci_register(dev, H_CB_WW, temp_msg); - } - - dev->host_hw_state |= H_IG; - heci_set_csr_register(dev); - dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); - if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - return 0; - - dev->write_hang = 0; - return 1; -} - -/** - * count_full_read_slots - count read full slots. - * - * @dev: device object for our driver - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count - */ -__s32 count_full_read_slots(struct iamt_heci_device *dev) -{ - char read_ptr, write_ptr; - unsigned char buffer_depth, filled_slots; - - dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); - buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); - read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); - write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); - filled_slots = (unsigned char) (write_ptr - read_ptr); - - if (filled_slots > buffer_depth) { - /* overflow */ - return -ESLOTS_OVERFLOW; - } - - DBG("filled_slots =%08x \n", filled_slots); - return (__s32) filled_slots; -} - -/** - * heci_read_slots - read a message from heci device. - * - * @dev: device object for our driver - * @buffer: message buffer will be write - * @buffer_length: message size will be read - */ -void heci_read_slots(struct iamt_heci_device *dev, - unsigned char *buffer, unsigned long buffer_length) -{ - __u32 i = 0; - unsigned char temp_buf[sizeof(__u32)]; - - while (buffer_length >= sizeof(__u32)) { - ((__u32 *) buffer)[i] = read_heci_register(dev, ME_CB_RW); - DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]); - i++; - buffer_length -= sizeof(__u32); - } - - if (buffer_length > 0) { - *((__u32 *) &temp_buf) = read_heci_register(dev, ME_CB_RW); - memcpy(&buffer[i * 4], temp_buf, buffer_length); - } - - dev->host_hw_state |= H_IG; - heci_set_csr_register(dev); -} - -/** - * flow_ctrl_creds - check flow_control credentials. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - * - * returns 1 if flow_ctrl_creds >0, 0 - otherwise. - */ -int flow_ctrl_creds(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - __u8 i; - - if (!dev->num_heci_me_clients) - return 0; - - if (file_ext == NULL) - return 0; - - if (file_ext->flow_ctrl_creds > 0) - return 1; - - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == file_ext->me_client_id) { - if (dev->me_clients[i].flow_ctrl_creds > 0) { - BUG_ON(dev->me_clients[i].props.single_recv_buf - == 0); - return 1; - } - return 0; - } - } - BUG(); - return 0; -} - -/** - * flow_ctrl_reduce - reduce flow_control. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - */ -void flow_ctrl_reduce(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - __u8 i; - - if (!dev->num_heci_me_clients) - return; - - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == file_ext->me_client_id) { - if (dev->me_clients[i].props.single_recv_buf != 0) { - BUG_ON(dev->me_clients[i].flow_ctrl_creds <= 0); - dev->me_clients[i].flow_ctrl_creds--; - } else { - BUG_ON(file_ext->flow_ctrl_creds <= 0); - file_ext->flow_ctrl_creds--; - } - return; - } - } - BUG(); -} - -/** - * heci_send_flow_control - send flow control to fw. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - * - * returns 1 if success, 0 - otherwise. - */ -int heci_send_flow_control(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - struct heci_msg_hdr *heci_hdr; - struct hbm_flow_control *heci_flow_control; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_flow_control); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - heci_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1]; - memset(heci_flow_control, 0, sizeof(heci_flow_control)); - heci_flow_control->host_addr = file_ext->host_client_id; - heci_flow_control->me_addr = file_ext->me_client_id; - heci_flow_control->cmd.cmd = HECI_FLOW_CONTROL_CMD; - memset(heci_flow_control->reserved, 0, - sizeof(heci_flow_control->reserved)); - DBG("sending flow control host client = %d, me client = %d\n", - file_ext->host_client_id, file_ext->me_client_id); - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) heci_flow_control, - sizeof(struct hbm_flow_control))) - return 0; - - return 1; - -} - -/** - * other_client_is_connecting - check if other - * client with the same client id is connected. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - * - * returns 1 if other client is connected, 0 - otherwise. - */ -int other_client_is_connecting(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - - list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) { - if ((file_pos->state == HECI_FILE_CONNECTING) - && (file_pos != file_ext) - && file_ext->me_client_id == file_pos->me_client_id) - return 1; - - } - return 0; -} - -/** - * heci_send_wd - send watch dog message to fw. - * - * @dev: device object for our driver - * - * returns 1 if success, 0 - otherwise. - */ -int heci_send_wd(struct iamt_heci_device *dev) -{ - struct heci_msg_hdr *heci_hdr; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = dev->wd_file_ext.host_client_id; - heci_hdr->me_addr = dev->wd_file_ext.me_client_id; - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - if (!memcmp(dev->wd_data, heci_start_wd_params, - HECI_WD_PARAMS_SIZE)) { - heci_hdr->length = HECI_START_WD_DATA_SIZE; - } else { - BUG_ON(memcmp(dev->wd_data, heci_stop_wd_params, - HECI_WD_PARAMS_SIZE)); - heci_hdr->length = HECI_WD_PARAMS_SIZE; - } - - if (!heci_write_message(dev, heci_hdr, dev->wd_data, heci_hdr->length)) - return 0; - - return 1; -} - -/** - * heci_disconnect - send disconnect message to fw. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - * - * returns 1 if success, 0 - otherwise. - */ -int heci_disconnect(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - struct heci_msg_hdr *heci_hdr; - struct hbm_client_disconnect_request *heci_cli_disconnect; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_client_disconnect_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - heci_cli_disconnect = - (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1]; - memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect)); - heci_cli_disconnect->host_addr = file_ext->host_client_id; - heci_cli_disconnect->me_addr = file_ext->me_client_id; - heci_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD; - heci_cli_disconnect->reserved[0] = 0; - - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) heci_cli_disconnect, - sizeof(struct hbm_client_disconnect_request))) - return 0; - - return 1; -} - -/** - * heci_connect - send connect message to fw. - * - * @dev: device object for our driver - * @file_ext: private data of the file object - * - * returns 1 if success, 0 - otherwise. - */ -int heci_connect(struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - struct heci_msg_hdr *heci_hdr; - struct hbm_client_connect_request *heci_cli_connect; - - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_client_connect_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - heci_cli_connect = - (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; - heci_cli_connect->host_addr = file_ext->host_client_id; - heci_cli_connect->me_addr = file_ext->me_client_id; - heci_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD; - heci_cli_connect->reserved = 0; - - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) heci_cli_connect, - sizeof(struct hbm_client_connect_request))) - return 0; - - return 1; -} diff --git a/drivers/staging/heci/heci_interface.h b/drivers/staging/heci/heci_interface.h deleted file mode 100644 index 34db7e52b8e..00000000000 --- a/drivers/staging/heci/heci_interface.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - - -#ifndef _HECI_INTERFACE_H_ -#define _HECI_INTERFACE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "heci_data_structures.h" - - -#define HBM_MINOR_VERSION 0 -#define HBM_MAJOR_VERSION 1 -#define HBM_TIMEOUT 1 /* 1 second */ - - -#define HOST_START_REQ_CMD 0x01 -#define HOST_START_RES_CMD 0x81 - -#define HOST_STOP_REQ_CMD 0x02 -#define HOST_STOP_RES_CMD 0x82 - -#define ME_STOP_REQ_CMD 0x03 - -#define HOST_ENUM_REQ_CMD 0x04 -#define HOST_ENUM_RES_CMD 0x84 - -#define HOST_CLIENT_PROPERTEIS_REQ_CMD 0x05 -#define HOST_CLIENT_PROPERTEIS_RES_CMD 0x85 - -#define CLIENT_CONNECT_REQ_CMD 0x06 -#define CLIENT_CONNECT_RES_CMD 0x86 - -#define CLIENT_DISCONNECT_REQ_CMD 0x07 -#define CLIENT_DISCONNECT_RES_CMD 0x87 - -#define HECI_FLOW_CONTROL_CMD 0x08 - - -#define AMT_WD_VALUE 120 /* seconds */ - -#define HECI_WATCHDOG_DATA_SIZE 16 -#define HECI_START_WD_DATA_SIZE 20 -#define HECI_WD_PARAMS_SIZE 4 - -/* IOCTL commands */ -#define IOCTL_HECI_GET_VERSION \ - _IOWR('H' , 0x0, struct heci_message_data) -#define IOCTL_HECI_CONNECT_CLIENT \ - _IOWR('H' , 0x01, struct heci_message_data) -#define IOCTL_HECI_WD \ - _IOWR('H' , 0x02, struct heci_message_data) -#define IOCTL_HECI_BYPASS_WD \ - _IOWR('H' , 0x10, struct heci_message_data) - -enum heci_stop_reason_types{ - DRIVER_STOP_REQUEST = 0x00, - DEVICE_D1_ENTRY = 0x01, - DEVICE_D2_ENTRY = 0x02, - DEVICE_D3_ENTRY = 0x03, - SYSTEM_S1_ENTRY = 0x04, - SYSTEM_S2_ENTRY = 0x05, - SYSTEM_S3_ENTRY = 0x06, - SYSTEM_S4_ENTRY = 0x07, - SYSTEM_S5_ENTRY = 0x08 -}; - -enum me_stop_reason_types{ - FW_UPDATE = 0x00 -}; - -enum client_connect_status_types{ - CCS_SUCCESS = 0x00, - CCS_NOT_FOUND = 0x01, - CCS_ALREADY_STARTED = 0x02, - CCS_OUT_OF_RESOURCES = 0x03, - CCS_MESSAGE_SMALL = 0x04 -}; - -enum client_disconnect_status_types{ - CDS_SUCCESS = 0x00 -}; - - -/* - * heci interface function prototypes - */ -void heci_set_csr_register(struct iamt_heci_device *dev); -void heci_csr_enable_interrupts(struct iamt_heci_device *dev); -void heci_csr_disable_interrupts(struct iamt_heci_device *dev); -void heci_csr_clear_his(struct iamt_heci_device *dev); - -void heci_read_slots(struct iamt_heci_device *dev, - unsigned char *buffer, unsigned long buffer_length); - -int heci_write_message(struct iamt_heci_device *dev, - struct heci_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length); - -int host_buffer_is_empty(struct iamt_heci_device *dev); - -__s32 count_full_read_slots(struct iamt_heci_device *dev); - -__s32 count_empty_write_slots(const struct iamt_heci_device *dev); - -int flow_ctrl_creds(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); - -int heci_send_wd(struct iamt_heci_device *dev); - -void flow_ctrl_reduce(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); - -int heci_send_flow_control(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); - -int heci_disconnect(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); -int other_client_is_connecting(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); -int heci_connect(struct iamt_heci_device *dev, - struct heci_file_private *file_ext); - -#endif /* _HECI_INTERFACE_H_ */ diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c deleted file mode 100644 index ddf48227e35..00000000000 --- a/drivers/staging/heci/heci_main.c +++ /dev/null @@ -1,1576 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "heci.h" -#include "heci_interface.h" -#include "heci_version.h" - - -#define HECI_READ_TIMEOUT 45 - -#define HECI_DRIVER_NAME "heci" - -/* - * heci driver strings - */ -static char heci_driver_name[] = HECI_DRIVER_NAME; -static char heci_driver_string[] = "Intel(R) Management Engine Interface"; -static char heci_driver_version[] = HECI_DRIVER_VERSION; -static char heci_copyright[] = "Copyright (c) 2003 - 2008 Intel Corporation."; - - -#ifdef HECI_DEBUG -int heci_debug = 1; -#else -int heci_debug; -#endif -MODULE_PARM_DESC(heci_debug, "Debug enabled or not"); -module_param(heci_debug, int, 0644); - - -#define HECI_DEV_NAME "heci" - -/* heci char device for registration */ -static struct cdev heci_cdev; - -/* major number for device */ -static int heci_major; -/* The device pointer */ -static struct pci_dev *heci_device; - -static struct class *heci_class; - - -/* heci_pci_tbl - PCI Device ID Table */ -static struct pci_device_id heci_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82946GZ)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82Q965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GM965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GME965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82G33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82X38)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_3200)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_6)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_7)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_8)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_10)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_4)}, - /* required last entry */ - {0, } -}; - -MODULE_DEVICE_TABLE(pci, heci_pci_tbl); - -/* - * Local Function Prototypes - */ -static int __init heci_init_module(void); -static void __exit heci_exit_module(void); -static int __devinit heci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void __devexit heci_remove(struct pci_dev *pdev); -static int heci_open(struct inode *inode, struct file *file); -static int heci_release(struct inode *inode, struct file *file); -static ssize_t heci_read(struct file *file, char __user *ubuf, - size_t length, loff_t *offset); -static int heci_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long data); -static ssize_t heci_write(struct file *file, const char __user *ubuf, - size_t length, loff_t *offset); -static unsigned int heci_poll(struct file *file, poll_table *wait); -static struct heci_cb_private *find_read_list_entry( - struct iamt_heci_device *dev, - struct heci_file_private *file_ext); -#ifdef CONFIG_PM -static int heci_suspend(struct pci_dev *pdev, pm_message_t state); -static int heci_resume(struct pci_dev *pdev); -static __u16 g_sus_wd_timeout; -#else -#define heci_suspend NULL -#define heci_resume NULL -#endif -/* - * PCI driver structure - */ -static struct pci_driver heci_driver = { - .name = heci_driver_name, - .id_table = heci_pci_tbl, - .probe = heci_probe, - .remove = __devexit_p(heci_remove), - .shutdown = __devexit_p(heci_remove), - .suspend = heci_suspend, - .resume = heci_resume -}; - -/* - * file operations structure will be use heci char device. - */ -static const struct file_operations heci_fops = { - .owner = THIS_MODULE, - .read = heci_read, - .ioctl = heci_ioctl, - .open = heci_open, - .release = heci_release, - .write = heci_write, - .poll = heci_poll, -}; - -/** - * heci_registration_cdev - set up the cdev structure for heci device. - * - * @dev: char device struct - * @hminor: minor number for registration char device - * @fops: file operations structure - * - * returns 0 on success, <0 on failure. - */ -static int heci_registration_cdev(struct cdev *dev, int hminor, - const struct file_operations *fops) -{ - int ret, devno = MKDEV(heci_major, hminor); - - cdev_init(dev, fops); - dev->owner = THIS_MODULE; - ret = cdev_add(dev, devno, 1); - /* Fail gracefully if need be */ - if (ret) { - printk(KERN_ERR "heci: Error %d registering heci device %d\n", - ret, hminor); - } - return ret; -} - -/* Display the version of heci driver. */ -static ssize_t version_show(struct class *dev, char *buf) -{ - return sprintf(buf, "%s %s.\n", - heci_driver_string, heci_driver_version); -} - -static CLASS_ATTR(version, S_IRUGO, version_show, NULL); - -/** - * heci_register_cdev - registers heci char device - * - * returns 0 on success, <0 on failure. - */ -static int heci_register_cdev(void) -{ - int ret; - dev_t dev; - - /* registration of char devices */ - ret = alloc_chrdev_region(&dev, HECI_MINORS_BASE, HECI_MINORS_COUNT, - HECI_DRIVER_NAME); - if (ret) { - printk(KERN_ERR "heci: Error allocating char device region.\n"); - return ret; - } - - heci_major = MAJOR(dev); - - ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER, - &heci_fops); - if (ret) - unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE), - HECI_MINORS_COUNT); - - return ret; -} - -/** - * heci_unregister_cdev - unregisters heci char device - */ -static void heci_unregister_cdev(void) -{ - cdev_del(&heci_cdev); - unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE), - HECI_MINORS_COUNT); -} - -#ifndef HECI_DEVICE_CREATE -#define HECI_DEVICE_CREATE device_create -#endif -/** - * heci_sysfs_device_create - adds device entry to sysfs - * - * returns 0 on success, <0 on failure. - */ -static int heci_sysfs_device_create(void) -{ - struct class *class; - void *tmphdev; - int err = 0; - - class = class_create(THIS_MODULE, HECI_DRIVER_NAME); - if (IS_ERR(class)) { - err = PTR_ERR(class); - printk(KERN_ERR "heci: Error creating heci class.\n"); - goto err_out; - } - - err = class_create_file(class, &class_attr_version); - if (err) { - class_destroy(class); - printk(KERN_ERR "heci: Error creating heci class file.\n"); - goto err_out; - } - - tmphdev = HECI_DEVICE_CREATE(class, NULL, heci_cdev.dev, NULL, - HECI_DEV_NAME); - if (IS_ERR(tmphdev)) { - err = PTR_ERR(tmphdev); - class_remove_file(class, &class_attr_version); - class_destroy(class); - goto err_out; - } - - heci_class = class; -err_out: - return err; -} - -/** - * heci_sysfs_device_remove - unregisters the device entry on sysfs - */ -static void heci_sysfs_device_remove(void) -{ - if ((heci_class == NULL) || (IS_ERR(heci_class))) - return; - - device_destroy(heci_class, heci_cdev.dev); - class_remove_file(heci_class, &class_attr_version); - class_destroy(heci_class); -} - -/** - * heci_init_module - Driver Registration Routine - * - * heci_init_module is the first routine called when the driver is - * loaded. All it does is register with the PCI subsystem. - * - * returns 0 on success, <0 on failure. - */ -static int __init heci_init_module(void) -{ - int ret = 0; - - printk(KERN_INFO "heci: %s - version %s\n", heci_driver_string, - heci_driver_version); - printk(KERN_INFO "heci: %s\n", heci_copyright); - - /* init pci module */ - ret = pci_register_driver(&heci_driver); - if (ret < 0) { - printk(KERN_ERR "heci: Error registering driver.\n"); - goto end; - } - - ret = heci_register_cdev(); - if (ret) - goto unregister_pci; - - ret = heci_sysfs_device_create(); - if (ret) - goto unregister_cdev; - - return ret; - -unregister_cdev: - heci_unregister_cdev(); -unregister_pci: - pci_unregister_driver(&heci_driver); -end: - return ret; -} - -module_init(heci_init_module); - - -/** - * heci_exit_module - Driver Exit Cleanup Routine - * - * heci_exit_module is called just before the driver is removed - * from memory. - */ -static void __exit heci_exit_module(void) -{ - pci_unregister_driver(&heci_driver); - heci_sysfs_device_remove(); - heci_unregister_cdev(); -} - -module_exit(heci_exit_module); - - -/** - * heci_probe - Device Initialization Routine - * - * @pdev: PCI device information struct - * @ent: entry in kcs_pci_tbl - * - * returns 0 on success, <0 on failure. - */ -static int __devinit heci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct iamt_heci_device *dev = NULL; - int i, err = 0; - - if (heci_device) { - err = -EEXIST; - goto end; - } - /* enable pci dev */ - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "heci: Failed to enable pci device.\n"); - goto end; - } - /* set PCI host mastering */ - pci_set_master(pdev); - /* pci request regions for heci driver */ - err = pci_request_regions(pdev, heci_driver_name); - if (err) { - printk(KERN_ERR "heci: Failed to get pci regions.\n"); - goto disable_device; - } - /* allocates and initializes the heci dev structure */ - dev = init_heci_device(pdev); - if (!dev) { - err = -ENOMEM; - goto release_regions; - } - /* mapping IO device memory */ - for (i = 0; i <= 5; i++) { - if (pci_resource_len(pdev, i) == 0) - continue; - if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { - printk(KERN_ERR "heci: heci has IO ports.\n"); - goto free_device; - } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { - if (dev->mem_base) { - printk(KERN_ERR - "heci: Too many mem addresses.\n"); - goto free_device; - } - dev->mem_base = pci_resource_start(pdev, i); - dev->mem_length = pci_resource_len(pdev, i); - } - } - if (!dev->mem_base) { - printk(KERN_ERR "heci: No address to use.\n"); - err = -ENODEV; - goto free_device; - } - dev->mem_addr = ioremap_nocache(dev->mem_base, - dev->mem_length); - if (!dev->mem_addr) { - printk(KERN_ERR "heci: Remap IO device memory failure.\n"); - err = -ENOMEM; - goto free_device; - } - /* request and enable interrupt */ - err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED, - heci_driver_name, dev); - if (err) { - printk(KERN_ERR "heci: Request_irq failure. irq = %d \n", - pdev->irq); - goto unmap_memory; - } - - if (heci_hw_init(dev)) { - printk(KERN_ERR "heci: Init hw failure.\n"); - err = -ENODEV; - goto release_irq; - } - init_timer(&dev->wd_timer); - - heci_initialize_clients(dev); - if (dev->heci_state != HECI_ENABLED) { - err = -ENODEV; - goto release_hw; - } - - spin_lock_bh(&dev->device_lock); - heci_device = pdev; - pci_set_drvdata(pdev, dev); - spin_unlock_bh(&dev->device_lock); - - if (dev->wd_timeout) - mod_timer(&dev->wd_timer, jiffies); - -#ifdef CONFIG_PM - g_sus_wd_timeout = 0; -#endif - printk(KERN_INFO "heci driver initialization successful.\n"); - return 0; - -release_hw: - /* disable interrupts */ - dev->host_hw_state = read_heci_register(dev, H_CSR); - heci_csr_disable_interrupts(dev); - - del_timer_sync(&dev->wd_timer); - - flush_scheduled_work(); - -release_irq: - free_irq(pdev->irq, dev); -unmap_memory: - if (dev->mem_addr) - iounmap(dev->mem_addr); -free_device: - kfree(dev); -release_regions: - pci_release_regions(pdev); -disable_device: - pci_disable_device(pdev); -end: - printk(KERN_ERR "heci driver initialization failed.\n"); - return err; -} - -/** - * heci_remove - Device Removal Routine - * - * @pdev: PCI device information struct - * - * heci_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. - */ -static void __devexit heci_remove(struct pci_dev *pdev) -{ - struct iamt_heci_device *dev = pci_get_drvdata(pdev); - - if (heci_device != pdev) - return; - - if (dev == NULL) - return; - - spin_lock_bh(&dev->device_lock); - if (heci_device != pdev) { - spin_unlock_bh(&dev->device_lock); - return; - } - - if (dev->reinit_tsk != NULL) { - kthread_stop(dev->reinit_tsk); - dev->reinit_tsk = NULL; - } - - del_timer_sync(&dev->wd_timer); - if (dev->wd_file_ext.state == HECI_FILE_CONNECTED - && dev->wd_timeout) { - dev->wd_timeout = 0; - dev->wd_due_counter = 0; - memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE); - dev->stop = 1; - if (dev->host_buffer_is_empty && - flow_ctrl_creds(dev, &dev->wd_file_ext)) { - dev->host_buffer_is_empty = 0; - - if (!heci_send_wd(dev)) - DBG("send stop WD failed\n"); - else - flow_ctrl_reduce(dev, &dev->wd_file_ext); - - dev->wd_pending = 0; - } else { - dev->wd_pending = 1; - } - dev->wd_stoped = 0; - spin_unlock_bh(&dev->device_lock); - - wait_event_interruptible_timeout(dev->wait_stop_wd, - (dev->wd_stoped), 10 * HZ); - spin_lock_bh(&dev->device_lock); - if (!dev->wd_stoped) - DBG("stop wd failed to complete.\n"); - else - DBG("stop wd complete.\n"); - - } - - heci_device = NULL; - spin_unlock_bh(&dev->device_lock); - - if (dev->iamthif_file_ext.state == HECI_FILE_CONNECTED) { - dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTING; - heci_disconnect_host_client(dev, - &dev->iamthif_file_ext); - } - if (dev->wd_file_ext.state == HECI_FILE_CONNECTED) { - dev->wd_file_ext.state = HECI_FILE_DISCONNECTING; - heci_disconnect_host_client(dev, - &dev->wd_file_ext); - } - - spin_lock_bh(&dev->device_lock); - - /* remove entry if already in list */ - DBG("list del iamthif and wd file list.\n"); - heci_remove_client_from_file_list(dev, dev->wd_file_ext. - host_client_id); - heci_remove_client_from_file_list(dev, - dev->iamthif_file_ext.host_client_id); - - dev->iamthif_current_cb = NULL; - dev->iamthif_file_ext.file = NULL; - dev->num_heci_me_clients = 0; - - spin_unlock_bh(&dev->device_lock); - - flush_scheduled_work(); - - /* disable interrupts */ - heci_csr_disable_interrupts(dev); - - free_irq(pdev->irq, dev); - pci_set_drvdata(pdev, NULL); - - if (dev->mem_addr) - iounmap(dev->mem_addr); - - kfree(dev); - - pci_release_regions(pdev); - pci_disable_device(pdev); -} - -/** - * heci_clear_list - remove all callbacks associated with file - * from heci_cb_list - * - * @file: file information struct - * @heci_cb_list: callbacks list - * - * heci_clear_list is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns 1 if callback removed from the list, 0 otherwise - */ -static int heci_clear_list(struct iamt_heci_device *dev, - struct file *file, struct list_head *heci_cb_list) -{ - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - struct file *file_temp; - int rets = 0; - - /* list all list member */ - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - heci_cb_list, cb_list) { - file_temp = (struct file *)priv_cb_pos->file_object; - /* check if list member associated with a file */ - if (file_temp == file) { - /* remove member from the list */ - list_del(&priv_cb_pos->cb_list); - /* check if cb equal to current iamthif cb */ - if (dev->iamthif_current_cb == priv_cb_pos) { - dev->iamthif_current_cb = NULL; - /* send flow control to iamthif client */ - heci_send_flow_control(dev, - &dev->iamthif_file_ext); - } - /* free all allocated buffers */ - heci_free_cb_private(priv_cb_pos); - rets = 1; - } - } - return rets; -} - -/** - * heci_clear_lists - remove all callbacks associated with file - * - * @dev: device information struct - * @file: file information struct - * - * heci_clear_lists is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns 1 if callback removed from the list, 0 otherwise - */ -static int heci_clear_lists(struct iamt_heci_device *dev, struct file *file) -{ - int rets = 0; - - /* remove callbacks associated with a file */ - heci_clear_list(dev, file, &dev->pthi_cmd_list.heci_cb.cb_list); - if (heci_clear_list(dev, file, - &dev->pthi_read_complete_list.heci_cb.cb_list)) - rets = 1; - - heci_clear_list(dev, file, &dev->ctrl_rd_list.heci_cb.cb_list); - - if (heci_clear_list(dev, file, &dev->ctrl_wr_list.heci_cb.cb_list)) - rets = 1; - - if (heci_clear_list(dev, file, - &dev->write_waiting_list.heci_cb.cb_list)) - rets = 1; - - if (heci_clear_list(dev, file, &dev->write_list.heci_cb.cb_list)) - rets = 1; - - /* check if iamthif_current_cb not NULL */ - if (dev->iamthif_current_cb && (!rets)) { - /* check file and iamthif current cb association */ - if (dev->iamthif_current_cb->file_object == file) { - /* remove cb */ - heci_free_cb_private(dev->iamthif_current_cb); - dev->iamthif_current_cb = NULL; - rets = 1; - } - } - return rets; -} - -/** - * heci_open - the open function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int heci_open(struct inode *inode, struct file *file) -{ - struct heci_file_private *file_ext; - int if_num = iminor(inode); - struct iamt_heci_device *dev; - - if (!heci_device) - return -ENODEV; - - dev = pci_get_drvdata(heci_device); - if ((if_num != HECI_MINOR_NUMBER) || (!dev)) - return -ENODEV; - - file_ext = heci_alloc_file_private(file); - if (file_ext == NULL) - return -ENOMEM; - - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - kfree(file_ext); - return -ENODEV; - } - if (dev->open_handle_count >= HECI_MAX_OPEN_HANDLE_COUNT) { - spin_unlock_bh(&dev->device_lock); - kfree(file_ext); - return -ENFILE; - }; - dev->open_handle_count++; - list_add_tail(&file_ext->link, &dev->file_list); - while ((dev->heci_host_clients[dev->current_host_client_id / 8] - & (1 << (dev->current_host_client_id % 8))) != 0) { - - dev->current_host_client_id++; /* allow overflow */ - DBG("current_host_client_id = %d\n", - dev->current_host_client_id); - DBG("dev->open_handle_count = %lu\n", - dev->open_handle_count); - } - DBG("current_host_client_id = %d\n", dev->current_host_client_id); - file_ext->host_client_id = dev->current_host_client_id; - dev->heci_host_clients[file_ext->host_client_id / 8] |= - (1 << (file_ext->host_client_id % 8)); - spin_unlock_bh(&dev->device_lock); - spin_lock(&file_ext->file_lock); - spin_lock_bh(&dev->device_lock); - file_ext->state = HECI_FILE_INITIALIZING; - spin_unlock_bh(&dev->device_lock); - file_ext->sm_state = 0; - - file->private_data = file_ext; - spin_unlock(&file_ext->file_lock); - - return 0; -} - -/** - * heci_release - the release function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int heci_release(struct inode *inode, struct file *file) -{ - int rets = 0; - int if_num = iminor(inode); - struct heci_file_private *file_ext = file->private_data; - struct heci_cb_private *priv_cb = NULL; - struct iamt_heci_device *dev; - - if (!heci_device) - return -ENODEV; - - dev = pci_get_drvdata(heci_device); - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) - return -ENODEV; - - if (file_ext != &dev->iamthif_file_ext) { - spin_lock(&file_ext->file_lock); - spin_lock_bh(&dev->device_lock); - if (file_ext->state == HECI_FILE_CONNECTED) { - file_ext->state = HECI_FILE_DISCONNECTING; - spin_unlock_bh(&dev->device_lock); - spin_unlock(&file_ext->file_lock); - DBG("disconnecting client host client = %d, " - "ME client = %d\n", - file_ext->host_client_id, - file_ext->me_client_id); - rets = heci_disconnect_host_client(dev, file_ext); - spin_lock(&file_ext->file_lock); - spin_lock_bh(&dev->device_lock); - } - heci_flush_queues(dev, file_ext); - DBG("remove client host client = %d, ME client = %d\n", - file_ext->host_client_id, - file_ext->me_client_id); - - if (dev->open_handle_count > 0) { - dev->heci_host_clients[file_ext->host_client_id / 8] &= - ~(1 << (file_ext->host_client_id % 8)); - dev->open_handle_count--; - } - heci_remove_client_from_file_list(dev, - file_ext->host_client_id); - - /* free read cb */ - if (file_ext->read_cb != NULL) { - priv_cb = find_read_list_entry(dev, file_ext); - /* Remove entry from read list */ - if (priv_cb != NULL) - list_del(&priv_cb->cb_list); - - priv_cb = file_ext->read_cb; - file_ext->read_cb = NULL; - } - - spin_unlock_bh(&dev->device_lock); - file->private_data = NULL; - spin_unlock(&file_ext->file_lock); - - if (priv_cb != NULL) - heci_free_cb_private(priv_cb); - - kfree(file_ext); - } else { - spin_lock_bh(&dev->device_lock); - - if (dev->open_handle_count > 0) - dev->open_handle_count--; - - if (dev->iamthif_file_object == file - && dev->iamthif_state != HECI_IAMTHIF_IDLE) { - DBG("pthi canceled iamthif state %d\n", - dev->iamthif_state); - dev->iamthif_canceled = 1; - if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE) { - DBG("run next pthi iamthif cb\n"); - run_next_iamthif_cmd(dev); - } - } - - if (heci_clear_lists(dev, file)) - dev->iamthif_state = HECI_IAMTHIF_IDLE; - - spin_unlock_bh(&dev->device_lock); - } - return rets; -} - -static struct heci_cb_private *find_read_list_entry( - struct iamt_heci_device *dev, - struct heci_file_private *file_ext) -{ - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - struct heci_file_private *file_ext_list_temp; - - if (dev->read_list.status == 0 - && !list_empty(&dev->read_list.heci_cb.cb_list)) { - DBG("remove read_list CB \n"); - list_for_each_entry_safe(priv_cb_pos, - priv_cb_next, - &dev->read_list.heci_cb.cb_list, cb_list) { - - file_ext_list_temp = (struct heci_file_private *) - priv_cb_pos->file_private; - - if ((file_ext_list_temp != NULL) && - heci_fe_same_id(file_ext, file_ext_list_temp)) - return priv_cb_pos; - - } - } - return NULL; -} - -/** - * heci_read - the read client message function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t heci_read(struct file *file, char __user *ubuf, - size_t length, loff_t *offset) -{ - int i; - int rets = 0, err = 0; - int if_num = iminor(file->f_dentry->d_inode); - struct heci_file_private *file_ext = file->private_data; - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb = NULL; - struct iamt_heci_device *dev; - - if (!heci_device) - return -ENODEV; - - dev = pci_get_drvdata(heci_device); - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) - return -ENODEV; - - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - spin_unlock_bh(&dev->device_lock); - - spin_lock(&file_ext->file_lock); - if ((file_ext->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { - spin_unlock(&file_ext->file_lock); - /* Do not allow to read watchdog client */ - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (memcmp(&heci_wd_guid, - &dev->me_clients[i].props.protocol_name, - sizeof(struct guid)) == 0) { - if (file_ext->me_client_id == - dev->me_clients[i].client_id) - return -EBADF; - } - } - } else { - file_ext->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT; - spin_unlock(&file_ext->file_lock); - } - - if (file_ext == &dev->iamthif_file_ext) { - rets = pthi_read(dev, if_num, file, ubuf, length, offset); - goto out; - } - - if (file_ext->read_cb && file_ext->read_cb->information > *offset) { - priv_cb = file_ext->read_cb; - goto copy_buffer; - } else if (file_ext->read_cb && file_ext->read_cb->information > 0 && - file_ext->read_cb->information <= *offset) { - priv_cb = file_ext->read_cb; - rets = 0; - goto free; - } else if ((!file_ext->read_cb || file_ext->read_cb->information == 0) - && *offset > 0) { - /*Offset needs to be cleaned for contingous reads*/ - *offset = 0; - rets = 0; - goto out; - } - - err = heci_start_read(dev, if_num, file_ext); - spin_lock_bh(&file_ext->read_io_lock); - if (err != 0 && err != -EBUSY) { - DBG("heci start read failure with status = %d\n", err); - spin_unlock_bh(&file_ext->read_io_lock); - rets = err; - goto out; - } - if (HECI_READ_COMPLETE != file_ext->reading_state - && !waitqueue_active(&file_ext->rx_wait)) { - if (file->f_flags & O_NONBLOCK) { - rets = -EAGAIN; - spin_unlock_bh(&file_ext->read_io_lock); - goto out; - } - spin_unlock_bh(&file_ext->read_io_lock); - - if (wait_event_interruptible(file_ext->rx_wait, - (HECI_READ_COMPLETE == file_ext->reading_state - || HECI_FILE_INITIALIZING == file_ext->state - || HECI_FILE_DISCONNECTED == file_ext->state - || HECI_FILE_DISCONNECTING == file_ext->state))) { - if (signal_pending(current)) { - rets = -EINTR; - goto out; - } - return -ERESTARTSYS; - } - - spin_lock_bh(&dev->device_lock); - if (HECI_FILE_INITIALIZING == file_ext->state || - HECI_FILE_DISCONNECTED == file_ext->state || - HECI_FILE_DISCONNECTING == file_ext->state) { - spin_unlock_bh(&dev->device_lock); - rets = -EBUSY; - goto out; - } - spin_unlock_bh(&dev->device_lock); - spin_lock_bh(&file_ext->read_io_lock); - } - - priv_cb = file_ext->read_cb; - - if (!priv_cb) { - spin_unlock_bh(&file_ext->read_io_lock); - return -ENODEV; - } - if (file_ext->reading_state != HECI_READ_COMPLETE) { - spin_unlock_bh(&file_ext->read_io_lock); - return 0; - } - spin_unlock_bh(&file_ext->read_io_lock); - /* now copy the data to user space */ -copy_buffer: - DBG("priv_cb->response_buffer size - %d\n", - priv_cb->response_buffer.size); - DBG("priv_cb->information - %lu\n", - priv_cb->information); - if (length == 0 || ubuf == NULL || - *offset > priv_cb->information) { - rets = -EMSGSIZE; - goto free; - } - - /* length is being turncated to PAGE_SIZE, however, */ - /* information size may be longer */ - length = (length < (priv_cb->information - *offset) ? - length : (priv_cb->information - *offset)); - - if (copy_to_user(ubuf, - priv_cb->response_buffer.data + *offset, - length)) { - rets = -EFAULT; - goto free; - } - - rets = length; - *offset += length; - if ((unsigned long)*offset < priv_cb->information) - goto out; - -free: - spin_lock_bh(&dev->device_lock); - priv_cb_pos = find_read_list_entry(dev, file_ext); - /* Remove entry from read list */ - if (priv_cb_pos != NULL) - list_del(&priv_cb_pos->cb_list); - spin_unlock_bh(&dev->device_lock); - heci_free_cb_private(priv_cb); - spin_lock_bh(&file_ext->read_io_lock); - file_ext->reading_state = HECI_IDLE; - file_ext->read_cb = NULL; - file_ext->read_pending = 0; - spin_unlock_bh(&file_ext->read_io_lock); -out: DBG("end heci read rets= %d\n", rets); - return rets; -} - -/** - * heci_write - the write function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t heci_write(struct file *file, const char __user *ubuf, - size_t length, loff_t *offset) -{ - int rets = 0; - __u8 i; - int if_num = iminor(file->f_dentry->d_inode); - struct heci_file_private *file_ext = file->private_data; - struct heci_cb_private *priv_write_cb = NULL; - struct heci_msg_hdr heci_hdr; - struct iamt_heci_device *dev; - unsigned long currtime = get_seconds(); - - if (!heci_device) - return -ENODEV; - - dev = pci_get_drvdata(heci_device); - - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) - return -ENODEV; - - spin_lock_bh(&dev->device_lock); - - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - if (file_ext == &dev->iamthif_file_ext) { - priv_write_cb = find_pthi_read_list_entry(dev, file); - if ((priv_write_cb != NULL) && - (((currtime - priv_write_cb->read_time) >= - IAMTHIF_READ_TIMER) || - (file_ext->reading_state == HECI_READ_COMPLETE))) { - (*offset) = 0; - list_del(&priv_write_cb->cb_list); - heci_free_cb_private(priv_write_cb); - priv_write_cb = NULL; - } - } - - /* free entry used in read */ - if (file_ext->reading_state == HECI_READ_COMPLETE) { - *offset = 0; - priv_write_cb = find_read_list_entry(dev, file_ext); - if (priv_write_cb != NULL) { - list_del(&priv_write_cb->cb_list); - heci_free_cb_private(priv_write_cb); - priv_write_cb = NULL; - spin_lock_bh(&file_ext->read_io_lock); - file_ext->reading_state = HECI_IDLE; - file_ext->read_cb = NULL; - file_ext->read_pending = 0; - spin_unlock_bh(&file_ext->read_io_lock); - } - } else if (file_ext->reading_state == HECI_IDLE && - file_ext->read_pending == 0) - (*offset) = 0; - - spin_unlock_bh(&dev->device_lock); - - priv_write_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); - if (!priv_write_cb) - return -ENOMEM; - - priv_write_cb->file_object = file; - priv_write_cb->file_private = file_ext; - priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); - if (!priv_write_cb->request_buffer.data) { - kfree(priv_write_cb); - return -ENOMEM; - } - DBG("length =%d\n", (int) length); - - if (copy_from_user(priv_write_cb->request_buffer.data, - ubuf, length)) { - rets = -EFAULT; - goto fail; - } - - spin_lock(&file_ext->file_lock); - file_ext->sm_state = 0; - if ((length == 4) && - ((memcmp(heci_wd_state_independence_msg[0], - priv_write_cb->request_buffer.data, 4) == 0) || - (memcmp(heci_wd_state_independence_msg[1], - priv_write_cb->request_buffer.data, 4) == 0) || - (memcmp(heci_wd_state_independence_msg[2], - priv_write_cb->request_buffer.data, 4) == 0))) - file_ext->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT; - spin_unlock(&file_ext->file_lock); - - INIT_LIST_HEAD(&priv_write_cb->cb_list); - if (file_ext == &dev->iamthif_file_ext) { - priv_write_cb->response_buffer.data = - kmalloc(IAMTHIF_MTU, GFP_KERNEL); - if (!priv_write_cb->response_buffer.data) { - rets = -ENOMEM; - goto fail; - } - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - rets = -ENODEV; - goto fail; - } - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_file_ext.me_client_id) - break; - } - - BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); - if ((i == dev->num_heci_me_clients) || - (dev->me_clients[i].client_id != - dev->iamthif_file_ext.me_client_id)) { - - spin_unlock_bh(&dev->device_lock); - rets = -ENODEV; - goto fail; - } else if ((length > dev->me_clients[i].props.max_msg_length) - || (length <= 0)) { - spin_unlock_bh(&dev->device_lock); - rets = -EMSGSIZE; - goto fail; - } - - - priv_write_cb->response_buffer.size = IAMTHIF_MTU; - priv_write_cb->major_file_operations = HECI_IOCTL; - priv_write_cb->information = 0; - priv_write_cb->request_buffer.size = length; - if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) { - spin_unlock_bh(&dev->device_lock); - rets = -ENODEV; - goto fail; - } - - if (!list_empty(&dev->pthi_cmd_list.heci_cb.cb_list) - || dev->iamthif_state != HECI_IAMTHIF_IDLE) { - DBG("pthi_state = %d\n", (int) dev->iamthif_state); - DBG("add PTHI cb to pthi cmd waiting list\n"); - list_add_tail(&priv_write_cb->cb_list, - &dev->pthi_cmd_list.heci_cb.cb_list); - rets = length; - } else { - DBG("call pthi write\n"); - rets = pthi_write(dev, priv_write_cb); - - if (rets != 0) { - DBG("pthi write failed with status = %d\n", - rets); - spin_unlock_bh(&dev->device_lock); - goto fail; - } - rets = length; - } - spin_unlock_bh(&dev->device_lock); - return rets; - } - - priv_write_cb->major_file_operations = HECI_WRITE; - /* make sure information is zero before we start */ - - priv_write_cb->information = 0; - priv_write_cb->request_buffer.size = length; - - spin_lock(&file_ext->write_io_lock); - spin_lock_bh(&dev->device_lock); - DBG("host client = %d, ME client = %d\n", - file_ext->host_client_id, file_ext->me_client_id); - if (file_ext->state != HECI_FILE_CONNECTED) { - rets = -ENODEV; - DBG("host client = %d, is not connected to ME client = %d", - file_ext->host_client_id, - file_ext->me_client_id); - spin_unlock_bh(&dev->device_lock); - goto unlock; - } - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == - file_ext->me_client_id) - break; - } - BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); - if (i == dev->num_heci_me_clients) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - goto unlock; - } - if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { - rets = -EINVAL; - spin_unlock_bh(&dev->device_lock); - goto unlock; - } - priv_write_cb->file_private = file_ext; - - if (flow_ctrl_creds(dev, file_ext) && - dev->host_buffer_is_empty) { - spin_unlock_bh(&dev->device_lock); - dev->host_buffer_is_empty = 0; - if (length > ((((dev->host_hw_state & H_CBD) >> 24) * - sizeof(__u32)) - sizeof(struct heci_msg_hdr))) { - - heci_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(__u32)) - - sizeof(struct heci_msg_hdr); - heci_hdr.msg_complete = 0; - } else { - heci_hdr.length = length; - heci_hdr.msg_complete = 1; - } - heci_hdr.host_addr = file_ext->host_client_id; - heci_hdr.me_addr = file_ext->me_client_id; - heci_hdr.reserved = 0; - DBG("call heci_write_message header=%08x.\n", - *((__u32 *) &heci_hdr)); - spin_unlock(&file_ext->write_io_lock); - /* protect heci low level write */ - spin_lock_bh(&dev->device_lock); - if (!heci_write_message(dev, &heci_hdr, - (unsigned char *) (priv_write_cb->request_buffer.data), - heci_hdr.length)) { - - spin_unlock_bh(&dev->device_lock); - heci_free_cb_private(priv_write_cb); - rets = -ENODEV; - priv_write_cb->information = 0; - return rets; - } - file_ext->writing_state = HECI_WRITING; - priv_write_cb->information = heci_hdr.length; - if (heci_hdr.msg_complete) { - flow_ctrl_reduce(dev, file_ext); - list_add_tail(&priv_write_cb->cb_list, - &dev->write_waiting_list.heci_cb.cb_list); - } else { - list_add_tail(&priv_write_cb->cb_list, - &dev->write_list.heci_cb.cb_list); - } - spin_unlock_bh(&dev->device_lock); - - } else { - - spin_unlock_bh(&dev->device_lock); - priv_write_cb->information = 0; - file_ext->writing_state = HECI_WRITING; - spin_unlock(&file_ext->write_io_lock); - list_add_tail(&priv_write_cb->cb_list, - &dev->write_list.heci_cb.cb_list); - } - return length; - -unlock: - spin_unlock(&file_ext->write_io_lock); -fail: - heci_free_cb_private(priv_write_cb); - return rets; - -} - -/** - * heci_ioctl - the IOCTL function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * @cmd: ioctl command - * @data: pointer to heci message structure - * - * returns 0 on success , <0 on error - */ -static int heci_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long data) -{ - int rets = 0; - int if_num = iminor(inode); - struct heci_file_private *file_ext = file->private_data; - /* in user space */ - struct heci_message_data __user *u_msg; - struct heci_message_data k_msg; /* all in kernel on the stack */ - struct iamt_heci_device *dev; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!heci_device) - return -ENODEV; - - dev = pci_get_drvdata(heci_device); - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) - return -ENODEV; - - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - spin_unlock_bh(&dev->device_lock); - - /* first copy from user all data needed */ - u_msg = (struct heci_message_data __user *)data; - if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) { - DBG("first copy from user all data needed filled\n"); - return -EFAULT; - } - DBG("user message size is %d\n", k_msg.size); - - switch (cmd) { - case IOCTL_HECI_GET_VERSION: - DBG(": IOCTL_HECI_GET_VERSION\n"); - rets = heci_ioctl_get_version(dev, if_num, u_msg, k_msg, - file_ext); - break; - - case IOCTL_HECI_CONNECT_CLIENT: - DBG(": IOCTL_HECI_CONNECT_CLIENT.\n"); - rets = heci_ioctl_connect_client(dev, if_num, u_msg, k_msg, - file); - break; - - case IOCTL_HECI_WD: - DBG(": IOCTL_HECI_WD.\n"); - rets = heci_ioctl_wd(dev, if_num, k_msg, file_ext); - break; - - case IOCTL_HECI_BYPASS_WD: - DBG(": IOCTL_HECI_BYPASS_WD.\n"); - rets = heci_ioctl_bypass_wd(dev, if_num, k_msg, file_ext); - break; - - default: - rets = -EINVAL; - break; - } - return rets; -} - -/** - * heci_poll - the poll function - * - * @file: pointer to file structure - * @wait: pointer to poll_table structure - * - * returns poll mask - */ -static unsigned int heci_poll(struct file *file, poll_table *wait) -{ - int if_num = iminor(file->f_dentry->d_inode); - unsigned int mask = 0; - struct heci_file_private *file_ext = file->private_data; - struct iamt_heci_device *dev; - - if (!heci_device) - return mask; - - dev = pci_get_drvdata(heci_device); - - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) - return mask; - - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - return mask; - } - spin_unlock_bh(&dev->device_lock); - - if (file_ext == &dev->iamthif_file_ext) { - poll_wait(file, &dev->iamthif_file_ext.wait, wait); - spin_lock(&dev->iamthif_file_ext.file_lock); - if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE - && dev->iamthif_file_object == file) { - mask |= (POLLIN | POLLRDNORM); - spin_lock_bh(&dev->device_lock); - DBG("run next pthi cb\n"); - run_next_iamthif_cmd(dev); - spin_unlock_bh(&dev->device_lock); - } - spin_unlock(&dev->iamthif_file_ext.file_lock); - - } else{ - poll_wait(file, &file_ext->tx_wait, wait); - spin_lock(&file_ext->write_io_lock); - if (HECI_WRITE_COMPLETE == file_ext->writing_state) - mask |= (POLLIN | POLLRDNORM); - - spin_unlock(&file_ext->write_io_lock); - } - - return mask; -} - -#ifdef CONFIG_PM -static int heci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct iamt_heci_device *dev = pci_get_drvdata(pdev); - int err = 0; - - spin_lock_bh(&dev->device_lock); - if (dev->reinit_tsk != NULL) { - kthread_stop(dev->reinit_tsk); - dev->reinit_tsk = NULL; - } - spin_unlock_bh(&dev->device_lock); - - /* Stop watchdog if exists */ - del_timer_sync(&dev->wd_timer); - if (dev->wd_file_ext.state == HECI_FILE_CONNECTED - && dev->wd_timeout) { - spin_lock_bh(&dev->device_lock); - g_sus_wd_timeout = dev->wd_timeout; - dev->wd_timeout = 0; - dev->wd_due_counter = 0; - memcpy(dev->wd_data, heci_stop_wd_params, - HECI_WD_PARAMS_SIZE); - dev->stop = 1; - if (dev->host_buffer_is_empty && - flow_ctrl_creds(dev, &dev->wd_file_ext)) { - dev->host_buffer_is_empty = 0; - if (!heci_send_wd(dev)) - DBG("send stop WD failed\n"); - else - flow_ctrl_reduce(dev, &dev->wd_file_ext); - - dev->wd_pending = 0; - } else { - dev->wd_pending = 1; - } - spin_unlock_bh(&dev->device_lock); - dev->wd_stoped = 0; - - err = wait_event_interruptible_timeout(dev->wait_stop_wd, - (dev->wd_stoped), - 10 * HZ); - if (!dev->wd_stoped) - DBG("stop wd failed to complete.\n"); - else { - DBG("stop wd complete %d.\n", err); - err = 0; - } - } - /* Set new heci state */ - spin_lock_bh(&dev->device_lock); - if (dev->heci_state == HECI_ENABLED || - dev->heci_state == HECI_RECOVERING_FROM_RESET) { - dev->heci_state = HECI_POWER_DOWN; - heci_reset(dev, 0); - } - spin_unlock_bh(&dev->device_lock); - - pci_save_state(pdev); - - pci_disable_device(pdev); - free_irq(pdev->irq, dev); - - pci_set_power_state(pdev, PCI_D3hot); - - return err; -} - -static int heci_resume(struct pci_dev *pdev) -{ - struct iamt_heci_device *dev; - int err = 0; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - dev = pci_get_drvdata(pdev); - if (!dev) - return -ENODEV; - - /* request and enable interrupt */ - err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED, - heci_driver_name, dev); - if (err) { - printk(KERN_ERR "heci: Request_irq failure. irq = %d \n", - pdev->irq); - return err; - } - - spin_lock_bh(&dev->device_lock); - dev->heci_state = HECI_POWER_UP; - heci_reset(dev, 1); - spin_unlock_bh(&dev->device_lock); - - /* Start watchdog if stopped in suspend */ - if (g_sus_wd_timeout != 0) { - dev->wd_timeout = g_sus_wd_timeout; - - memcpy(dev->wd_data, heci_start_wd_params, - HECI_WD_PARAMS_SIZE); - memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE, - &dev->wd_timeout, sizeof(__u16)); - dev->wd_due_counter = 1; - - if (dev->wd_timeout) - mod_timer(&dev->wd_timer, jiffies); - - g_sus_wd_timeout = 0; - } - return err; -} -#endif - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION(HECI_DRIVER_VERSION); diff --git a/drivers/staging/heci/heci_version.h b/drivers/staging/heci/heci_version.h deleted file mode 100644 index 3007aa6e17d..00000000000 --- a/drivers/staging/heci/heci_version.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#ifndef HECI_VERSION_H -#define HECI_VERSION_H - -#define MAJOR_VERSION 5 -#define MINOR_VERSION 0 -#define QUICK_FIX_NUMBER 0 -#define VER_BUILD 31 - -#define HECI_DRV_VER1 __stringify(MAJOR_VERSION) "." __stringify(MINOR_VERSION) -#define HECI_DRV_VER2 __stringify(QUICK_FIX_NUMBER) "." __stringify(VER_BUILD) - -#define HECI_DRIVER_VERSION HECI_DRV_VER1 "." HECI_DRV_VER2 - -#endif diff --git a/drivers/staging/heci/interrupt.c b/drivers/staging/heci/interrupt.c deleted file mode 100644 index 2a3a01a62bb..00000000000 --- a/drivers/staging/heci/interrupt.c +++ /dev/null @@ -1,1555 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#include - -#include "heci.h" -#include "heci_interface.h" - -/* - * interrupt function prototypes - */ -static void heci_bh_handler(struct work_struct *work); -static int heci_bh_read_handler(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - __s32 *slots); -static int heci_bh_write_handler(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - __s32 *slots); -static void heci_bh_read_bus_message(struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr); -static int heci_bh_read_pthi_message(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr); -static int heci_bh_read_client_message(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr); -static void heci_client_connect_response(struct iamt_heci_device *dev, - struct hbm_client_connect_response *connect_res); -static void heci_client_disconnect_response(struct iamt_heci_device *dev, - struct hbm_client_connect_response *disconnect_res); -static void heci_client_flow_control_response(struct iamt_heci_device *dev, - struct hbm_flow_control *flow_control); -static void heci_client_disconnect_request(struct iamt_heci_device *dev, - struct hbm_client_disconnect_request *disconnect_req); - - -/** - * heci_isr_interrupt - The ISR of the HECI device - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - */ -irqreturn_t heci_isr_interrupt(int irq, void *dev_id) -{ - int err; - struct iamt_heci_device *dev = (struct iamt_heci_device *) dev_id; - - dev->host_hw_state = read_heci_register(dev, H_CSR); - - if ((dev->host_hw_state & H_IS) != H_IS) - return IRQ_NONE; - - /* disable interrupts */ - heci_csr_disable_interrupts(dev); - - /* clear H_IS bit in H_CSR */ - heci_csr_clear_his(dev); - - /* - * Our device interrupted, schedule work the heci_bh_handler - * to handle the interrupt processing. This needs to be a - * workqueue item since the handler can sleep. - */ - PREPARE_WORK(&dev->work, heci_bh_handler); - DBG("schedule work the heci_bh_handler.\n"); - err = schedule_work(&dev->work); - if (!err) - DBG("heci_bh_handler was already on the workqueue.\n"); - return IRQ_HANDLED; -} - -/** - * _heci_cmpl - process completed operation. - * - * @file_ext: private data of the file object. - * @priv_cb_pos: callback block. - */ -static void _heci_cmpl(struct heci_file_private *file_ext, - struct heci_cb_private *priv_cb_pos) -{ - if (priv_cb_pos->major_file_operations == HECI_WRITE) { - heci_free_cb_private(priv_cb_pos); - DBG("completing write call back.\n"); - file_ext->writing_state = HECI_WRITE_COMPLETE; - if ((&file_ext->tx_wait) && - waitqueue_active(&file_ext->tx_wait)) - wake_up_interruptible(&file_ext->tx_wait); - - } else if (priv_cb_pos->major_file_operations == HECI_READ - && HECI_READING == file_ext->reading_state) { - DBG("completing read call back information= %lu\n", - priv_cb_pos->information); - file_ext->reading_state = HECI_READ_COMPLETE; - if ((&file_ext->rx_wait) && - waitqueue_active(&file_ext->rx_wait)) - wake_up_interruptible(&file_ext->rx_wait); - - } -} - -/** - * _heci_cmpl_iamthif - process completed iamthif operation. - * - * @dev: Device object for our driver. - * @priv_cb_pos: callback block. - */ -static void _heci_cmpl_iamthif(struct iamt_heci_device *dev, - struct heci_cb_private *priv_cb_pos) -{ - if (dev->iamthif_canceled != 1) { - dev->iamthif_state = HECI_IAMTHIF_READ_COMPLETE; - dev->iamthif_stall_timer = 0; - memcpy(priv_cb_pos->response_buffer.data, - dev->iamthif_msg_buf, - dev->iamthif_msg_buf_index); - list_add_tail(&priv_cb_pos->cb_list, - &dev->pthi_read_complete_list.heci_cb.cb_list); - DBG("pthi read completed.\n"); - } else { - run_next_iamthif_cmd(dev); - } - if (&dev->iamthif_file_ext.wait) { - DBG("completing pthi call back.\n"); - wake_up_interruptible(&dev->iamthif_file_ext.wait); - } -} -/** - * heci_bh_handler - function called after ISR to handle the interrupt - * processing. - * - * @work: pointer to the work structure - * - * NOTE: This function is called by schedule work - */ -static void heci_bh_handler(struct work_struct *work) -{ - struct iamt_heci_device *dev = - container_of(work, struct iamt_heci_device, work); - struct io_heci_list complete_list; - __s32 slots; - int rets; - struct heci_cb_private *cb_pos = NULL, *cb_next = NULL; - struct heci_file_private *file_ext; - int bus_message_received = 0; - struct task_struct *tsk; - - DBG("function called after ISR to handle the interrupt processing.\n"); - /* initialize our complete list */ - spin_lock_bh(&dev->device_lock); - heci_initialize_list(&complete_list, dev); - dev->host_hw_state = read_heci_register(dev, H_CSR); - dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); - - /* check if ME wants a reset */ - if (((dev->me_hw_state & ME_RDY_HRA) == 0) - && (dev->heci_state != HECI_RESETING) - && (dev->heci_state != HECI_INITIALIZING)) { - DBG("FW not ready.\n"); - heci_reset(dev, 1); - spin_unlock_bh(&dev->device_lock); - return; - } - - /* check if we need to start the dev */ - if ((dev->host_hw_state & H_RDY) == 0) { - if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { - DBG("we need to start the dev.\n"); - dev->host_hw_state |= (H_IE | H_IG | H_RDY); - heci_set_csr_register(dev); - if (dev->heci_state == HECI_INITIALIZING) { - dev->recvd_msg = 1; - spin_unlock_bh(&dev->device_lock); - wake_up_interruptible(&dev->wait_recvd_msg); - return; - - } else { - spin_unlock_bh(&dev->device_lock); - tsk = kthread_run(heci_task_initialize_clients, - dev, "heci_reinit"); - if (IS_ERR(tsk)) { - int rc = PTR_ERR(tsk); - printk(KERN_WARNING "heci: Unable to" - "start the heci thread: %d\n", rc); - } - return; - } - } else { - DBG("enable interrupt FW not ready.\n"); - heci_csr_enable_interrupts(dev); - spin_unlock_bh(&dev->device_lock); - return; - } - } - /* check slots avalable for reading */ - slots = count_full_read_slots(dev); - DBG("slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - while ((slots > 0) && (!dev->extra_write_index)) { - DBG("slots =%08x extra_write_index =%08x.\n", slots, - dev->extra_write_index); - DBG("call heci_bh_read_handler.\n"); - rets = heci_bh_read_handler(&complete_list, dev, &slots); - if (rets != 0) - goto end; - } - rets = heci_bh_write_handler(&complete_list, dev, &slots); -end: - DBG("end of bottom half function.\n"); - dev->host_hw_state = read_heci_register(dev, H_CSR); - dev->host_buffer_is_empty = host_buffer_is_empty(dev); - - if ((dev->host_hw_state & H_IS) == H_IS) { - /* acknowledge interrupt and disable interrupts */ - heci_csr_disable_interrupts(dev); - - /* clear H_IS bit in H_CSR */ - heci_csr_clear_his(dev); - - PREPARE_WORK(&dev->work, heci_bh_handler); - DBG("schedule work the heci_bh_handler.\n"); - rets = schedule_work(&dev->work); - if (!rets) - DBG("heci_bh_handler was already queued.\n"); - } else { - heci_csr_enable_interrupts(dev); - } - - if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { - DBG("received waiting bus message\n"); - bus_message_received = 1; - } - spin_unlock_bh(&dev->device_lock); - if (bus_message_received) { - DBG("wake up dev->wait_recvd_msg\n"); - wake_up_interruptible(&dev->wait_recvd_msg); - bus_message_received = 0; - } - if ((complete_list.status != 0) - || list_empty(&complete_list.heci_cb.cb_list)) - return; - - - list_for_each_entry_safe(cb_pos, cb_next, - &complete_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *)cb_pos->file_private; - list_del(&cb_pos->cb_list); - if (file_ext != NULL) { - if (file_ext != &dev->iamthif_file_ext) { - DBG("completing call back.\n"); - _heci_cmpl(file_ext, cb_pos); - cb_pos = NULL; - } else if (file_ext == &dev->iamthif_file_ext) { - _heci_cmpl_iamthif(dev, cb_pos); - } - } - } -} - - -/** - * heci_bh_read_handler - bottom half read routine after ISR to - * handle the read processing. - * - * @cmpl_list: An instance of our list structure - * @dev: Device object for our driver - * @slots: slots to read. - * - * returns 0 on success, <0 on failure. - */ -static int heci_bh_read_handler(struct io_heci_list *cmpl_list, - struct iamt_heci_device *dev, - __s32 *slots) -{ - struct heci_msg_hdr *heci_hdr; - int ret = 0; - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - - if (!dev->rd_msg_hdr) { - dev->rd_msg_hdr = read_heci_register(dev, ME_CB_RW); - DBG("slots=%08x.\n", *slots); - (*slots)--; - DBG("slots=%08x.\n", *slots); - } - heci_hdr = (struct heci_msg_hdr *) &dev->rd_msg_hdr; - DBG("heci_hdr->length =%d\n", heci_hdr->length); - - if ((heci_hdr->reserved) || !(dev->rd_msg_hdr)) { - DBG("corrupted message header.\n"); - ret = -ECORRUPTED_MESSAGE_HEADER; - goto end; - } - - if ((heci_hdr->host_addr) || (heci_hdr->me_addr)) { - list_for_each_entry_safe(file_pos, file_next, - &dev->file_list, link) { - DBG("list_for_each_entry_safe read host" - " client = %d, ME client = %d\n", - file_pos->host_client_id, - file_pos->me_client_id); - if ((file_pos->host_client_id == heci_hdr->host_addr) - && (file_pos->me_client_id == heci_hdr->me_addr)) - break; - } - - if (&file_pos->link == &dev->file_list) { - DBG("corrupted message header\n"); - ret = -ECORRUPTED_MESSAGE_HEADER; - goto end; - } - } - if (((*slots) * sizeof(__u32)) < heci_hdr->length) { - DBG("we can't read the message slots=%08x.\n", *slots); - /* we can't read the message */ - ret = -ERANGE; - goto end; - } - - /* decide where to read the message too */ - if (!heci_hdr->host_addr) { - DBG("call heci_bh_read_bus_message.\n"); - heci_bh_read_bus_message(dev, heci_hdr); - DBG("end heci_bh_read_bus_message.\n"); - } else if ((heci_hdr->host_addr == dev->iamthif_file_ext.host_client_id) - && (HECI_FILE_CONNECTED == dev->iamthif_file_ext.state) - && (dev->iamthif_state == HECI_IAMTHIF_READING)) { - DBG("call heci_bh_read_iamthif_message.\n"); - DBG("heci_hdr->length =%d\n", heci_hdr->length); - ret = heci_bh_read_pthi_message(cmpl_list, dev, heci_hdr); - if (ret != 0) - goto end; - - } else { - DBG("call heci_bh_read_client_message.\n"); - ret = heci_bh_read_client_message(cmpl_list, dev, heci_hdr); - if (ret != 0) - goto end; - - } - - /* reset the number of slots and header */ - *slots = count_full_read_slots(dev); - dev->rd_msg_hdr = 0; - - if (*slots == -ESLOTS_OVERFLOW) { - /* overflow - reset */ - DBG("reseting due to slots overflow.\n"); - /* set the event since message has been read */ - ret = -ERANGE; - goto end; - } -end: - return ret; -} - - -/** - * heci_bh_read_bus_message - bottom half read routine after ISR to - * handle the read bus message cmd processing. - * - * @dev: Device object for our driver - * @heci_hdr: header of bus message - */ -static void heci_bh_read_bus_message(struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr) -{ - struct heci_bus_message *heci_msg; - struct hbm_host_version_response *version_res; - struct hbm_client_connect_response *connect_res; - struct hbm_client_connect_response *disconnect_res; - struct hbm_flow_control *flow_control; - struct hbm_props_response *props_res; - struct hbm_host_enum_response *enum_res; - struct hbm_client_disconnect_request *disconnect_req; - struct hbm_host_stop_request *h_stop_req; - int i; - unsigned char *buffer; - - /* read the message to our buffer */ - buffer = (unsigned char *) dev->rd_msg_buf; - BUG_ON(heci_hdr->length >= sizeof(dev->rd_msg_buf)); - heci_read_slots(dev, buffer, heci_hdr->length); - heci_msg = (struct heci_bus_message *) buffer; - - switch (*(__u8 *) heci_msg) { - case HOST_START_RES_CMD: - version_res = (struct hbm_host_version_response *) heci_msg; - if (version_res->host_version_supported) { - dev->version.major_version = HBM_MAJOR_VERSION; - dev->version.minor_version = HBM_MINOR_VERSION; - } else { - dev->version = version_res->me_max_version; - } - dev->recvd_msg = 1; - DBG("host start response message received.\n"); - break; - - case CLIENT_CONNECT_RES_CMD: - connect_res = - (struct hbm_client_connect_response *) heci_msg; - heci_client_connect_response(dev, connect_res); - DBG("client connect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case CLIENT_DISCONNECT_RES_CMD: - disconnect_res = - (struct hbm_client_connect_response *) heci_msg; - heci_client_disconnect_response(dev, disconnect_res); - DBG("client disconnect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case HECI_FLOW_CONTROL_CMD: - flow_control = (struct hbm_flow_control *) heci_msg; - heci_client_flow_control_response(dev, flow_control); - DBG("client flow control response message received.\n"); - break; - - case HOST_CLIENT_PROPERTEIS_RES_CMD: - props_res = (struct hbm_props_response *) heci_msg; - if (props_res->status != 0) { - BUG(); - break; - } - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == - props_res->address) { - dev->me_clients[i].props = - props_res->client_properties; - break; - } - - } - dev->recvd_msg = 1; - break; - - case HOST_ENUM_RES_CMD: - enum_res = (struct hbm_host_enum_response *) heci_msg; - memcpy(dev->heci_me_clients, enum_res->valid_addresses, 32); - dev->recvd_msg = 1; - break; - - case HOST_STOP_RES_CMD: - dev->heci_state = HECI_DISABLED; - DBG("reseting because of FW stop response.\n"); - heci_reset(dev, 1); - break; - - case CLIENT_DISCONNECT_REQ_CMD: - /* search for client */ - disconnect_req = - (struct hbm_client_disconnect_request *) heci_msg; - heci_client_disconnect_request(dev, disconnect_req); - break; - - case ME_STOP_REQ_CMD: - /* prepare stop request */ - heci_hdr = (struct heci_msg_hdr *) &dev->ext_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = sizeof(struct hbm_host_stop_request); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - h_stop_req = - (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; - memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request)); - h_stop_req->cmd.cmd = HOST_STOP_REQ_CMD; - h_stop_req->reason = DRIVER_STOP_REQUEST; - h_stop_req->reserved[0] = 0; - h_stop_req->reserved[1] = 0; - dev->extra_write_index = 2; - break; - - default: - BUG(); - break; - - } -} - -/** - * heci_bh_read_pthi_message - bottom half read routine after ISR to - * handle the read pthi message data processing. - * - * @complete_list: An instance of our list structure - * @dev: Device object for our driver - * @heci_hdr: header of pthi message - * - * returns 0 on success, <0 on failure. - */ -static int heci_bh_read_pthi_message(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr) -{ - struct heci_file_private *file_ext; - struct heci_cb_private *priv_cb; - unsigned char *buffer; - - BUG_ON(heci_hdr->me_addr != dev->iamthif_file_ext.me_client_id); - BUG_ON(dev->iamthif_state != HECI_IAMTHIF_READING); - - buffer = (unsigned char *) (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index); - BUG_ON(sizeof(dev->iamthif_msg_buf) < - (dev->iamthif_msg_buf_index + heci_hdr->length)); - - heci_read_slots(dev, buffer, heci_hdr->length); - - dev->iamthif_msg_buf_index += heci_hdr->length; - - if (!(heci_hdr->msg_complete)) - return 0; - - DBG("pthi_message_buffer_index=%d\n", heci_hdr->length); - DBG("completed pthi read.\n "); - if (!dev->iamthif_current_cb) - return -ENODEV; - - priv_cb = dev->iamthif_current_cb; - dev->iamthif_current_cb = NULL; - - file_ext = (struct heci_file_private *)priv_cb->file_private; - if (!file_ext) - return -ENODEV; - - dev->iamthif_stall_timer = 0; - priv_cb->information = dev->iamthif_msg_buf_index; - priv_cb->read_time = get_seconds(); - if ((dev->iamthif_ioctl) && (file_ext == &dev->iamthif_file_ext)) { - /* found the iamthif cb */ - DBG("complete the pthi read cb.\n "); - if (&dev->iamthif_file_ext) { - DBG("add the pthi read cb to complete.\n "); - list_add_tail(&priv_cb->cb_list, - &complete_list->heci_cb.cb_list); - } - } - return 0; -} - -/** - * _heci_bh_state_ok - check if heci header matches file private data - * - * @file_ext: private data of the file object - * @heci_hdr: header of heci client message - * - * returns !=0 if matches, 0 if no match. - */ -static int _heci_bh_state_ok(struct heci_file_private *file_ext, - struct heci_msg_hdr *heci_hdr) -{ - return ((file_ext->host_client_id == heci_hdr->host_addr) - && (file_ext->me_client_id == heci_hdr->me_addr) - && (file_ext->state == HECI_FILE_CONNECTED) - && (HECI_READ_COMPLETE != file_ext->reading_state)); -} - -/** - * heci_bh_read_client_message - bottom half read routine after ISR to - * handle the read heci client message data processing. - * - * @complete_list: An instance of our list structure - * @dev: Device object for our driver - * @heci_hdr: header of heci client message - * - * returns 0 on success, <0 on failure. - */ -static int heci_bh_read_client_message(struct io_heci_list *complete_list, - struct iamt_heci_device *dev, - struct heci_msg_hdr *heci_hdr) -{ - struct heci_file_private *file_ext; - struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL; - unsigned char *buffer = NULL; - - DBG("start client msg\n"); - if (!((dev->read_list.status == 0) && - !list_empty(&dev->read_list.heci_cb.cb_list))) - goto quit; - - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->read_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - if ((file_ext != NULL) && - (_heci_bh_state_ok(file_ext, heci_hdr))) { - spin_lock_bh(&file_ext->read_io_lock); - file_ext->reading_state = HECI_READING; - buffer = (unsigned char *) - (priv_cb_pos->response_buffer.data + - priv_cb_pos->information); - BUG_ON(priv_cb_pos->response_buffer.size < - heci_hdr->length + - priv_cb_pos->information); - - if (priv_cb_pos->response_buffer.size < - heci_hdr->length + - priv_cb_pos->information) { - DBG("message overflow.\n"); - list_del(&priv_cb_pos->cb_list); - spin_unlock_bh(&file_ext->read_io_lock); - return -ENOMEM; - } - if (buffer) { - heci_read_slots(dev, buffer, - heci_hdr->length); - } - priv_cb_pos->information += heci_hdr->length; - if (heci_hdr->msg_complete) { - file_ext->status = 0; - list_del(&priv_cb_pos->cb_list); - spin_unlock_bh(&file_ext->read_io_lock); - DBG("completed read host client = %d," - "ME client = %d, " - "data length = %lu\n", - file_ext->host_client_id, - file_ext->me_client_id, - priv_cb_pos->information); - - *(priv_cb_pos->response_buffer.data + - priv_cb_pos->information) = '\0'; - DBG("priv_cb_pos->res_buffer - %s\n", - priv_cb_pos->response_buffer.data); - list_add_tail(&priv_cb_pos->cb_list, - &complete_list->heci_cb.cb_list); - } else { - spin_unlock_bh(&file_ext->read_io_lock); - } - - break; - } - - } - -quit: - DBG("message read\n"); - if (!buffer) { - heci_read_slots(dev, (unsigned char *) dev->rd_msg_buf, - heci_hdr->length); - DBG("discarding message, header=%08x.\n", - *(__u32 *) dev->rd_msg_buf); - } - - return 0; -} - -/** - * _heci_bh_iamthif_read - prepare to read iamthif data. - * - * @dev: Device object for our driver. - * @slots: free slots. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_iamthif_read(struct iamt_heci_device *dev, __s32 *slots) -{ - - if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) - + sizeof(struct hbm_flow_control))) { - *slots -= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (!heci_send_flow_control(dev, &dev->iamthif_file_ext)) { - DBG("iamthif flow control failed\n"); - } else { - DBG("iamthif flow control success\n"); - dev->iamthif_state = HECI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; - dev->host_buffer_is_empty = host_buffer_is_empty(dev); - } - return 0; - } else { - return -ECOMPLETE_MESSAGE; - } -} - -/** - * _heci_bh_close - process close related operation. - * - * @dev: Device object for our driver. - * @slots: free slots. - * @priv_cb_pos: callback block. - * @file_ext: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_close(struct iamt_heci_device *dev, __s32 *slots, - struct heci_cb_private *priv_cb_pos, - struct heci_file_private *file_ext, - struct io_heci_list *cmpl_list) -{ - if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_client_disconnect_request))) { - *slots -= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_client_disconnect_request) + 3) / 4; - - if (!heci_disconnect(dev, file_ext)) { - file_ext->status = 0; - priv_cb_pos->information = 0; - list_move_tail(&priv_cb_pos->cb_list, - &cmpl_list->heci_cb.cb_list); - return -ECOMPLETE_MESSAGE; - } else { - file_ext->state = HECI_FILE_DISCONNECTING; - file_ext->status = 0; - priv_cb_pos->information = 0; - list_move_tail(&priv_cb_pos->cb_list, - &dev->ctrl_rd_list.heci_cb.cb_list); - file_ext->timer_count = HECI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - return -ECORRUPTED_MESSAGE_HEADER; - } - - return 0; -} - -/** - * _heci_hb_close - process read related operation. - * - * @dev: Device object for our driver. - * @slots: free slots. - * @priv_cb_pos: callback block. - * @file_ext: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_read(struct iamt_heci_device *dev, __s32 *slots, - struct heci_cb_private *priv_cb_pos, - struct heci_file_private *file_ext, - struct io_heci_list *cmpl_list) -{ - if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_flow_control))) { - *slots -= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (!heci_send_flow_control(dev, file_ext)) { - file_ext->status = -ENODEV; - priv_cb_pos->information = 0; - list_move_tail(&priv_cb_pos->cb_list, - &cmpl_list->heci_cb.cb_list); - return -ENODEV; - } else { - list_move_tail(&priv_cb_pos->cb_list, - &dev->read_list.heci_cb.cb_list); - } - } else { - /* return the cancel routine */ - list_del(&priv_cb_pos->cb_list); - return -ECORRUPTED_MESSAGE_HEADER; - } - - return 0; -} - - -/** - * _heci_bh_ioctl - process ioctl related operation. - * - * @dev: Device object for our driver. - * @slots: free slots. - * @priv_cb_pos: callback block. - * @file_ext: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_ioctl(struct iamt_heci_device *dev, __s32 *slots, - struct heci_cb_private *priv_cb_pos, - struct heci_file_private *file_ext, - struct io_heci_list *cmpl_list) -{ - if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_client_connect_request))) { - file_ext->state = HECI_FILE_CONNECTING; - *slots -= (sizeof(struct heci_msg_hdr) + - sizeof(struct hbm_client_connect_request) + 3) / 4; - if (!heci_connect(dev, file_ext)) { - file_ext->status = -ENODEV; - priv_cb_pos->information = 0; - list_del(&priv_cb_pos->cb_list); - return -ENODEV; - } else { - list_move_tail(&priv_cb_pos->cb_list, - &dev->ctrl_rd_list.heci_cb.cb_list); - file_ext->timer_count = HECI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - list_del(&priv_cb_pos->cb_list); - return -ECORRUPTED_MESSAGE_HEADER; - } - - return 0; -} - -/** - * _heci_bh_cmpl - process completed and no-iamthif operation. - * - * @dev: Device object for our driver. - * @slots: free slots. - * @priv_cb_pos: callback block. - * @file_ext: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_cmpl(struct iamt_heci_device *dev, __s32 *slots, - struct heci_cb_private *priv_cb_pos, - struct heci_file_private *file_ext, - struct io_heci_list *cmpl_list) -{ - struct heci_msg_hdr *heci_hdr; - - if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) + - (priv_cb_pos->request_buffer.size - - priv_cb_pos->information))) { - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = file_ext->host_client_id; - heci_hdr->me_addr = file_ext->me_client_id; - heci_hdr->length = ((priv_cb_pos->request_buffer.size) - - (priv_cb_pos->information)); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - DBG("priv_cb_pos->request_buffer.size =%d" - "heci_hdr->msg_complete= %d\n", - priv_cb_pos->request_buffer.size, - heci_hdr->msg_complete); - DBG("priv_cb_pos->information =%lu\n", - priv_cb_pos->information); - DBG("heci_hdr->length =%d\n", - heci_hdr->length); - *slots -= (sizeof(struct heci_msg_hdr) + - heci_hdr->length + 3) / 4; - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) - (priv_cb_pos->request_buffer.data + - priv_cb_pos->information), - heci_hdr->length)) { - file_ext->status = -ENODEV; - list_move_tail(&priv_cb_pos->cb_list, - &cmpl_list->heci_cb.cb_list); - return -ENODEV; - } else { - flow_ctrl_reduce(dev, file_ext); - file_ext->status = 0; - priv_cb_pos->information += heci_hdr->length; - list_move_tail(&priv_cb_pos->cb_list, - &dev->write_waiting_list.heci_cb.cb_list); - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = file_ext->host_client_id; - heci_hdr->me_addr = file_ext->me_client_id; - heci_hdr->length = - (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr); - heci_hdr->msg_complete = 0; - heci_hdr->reserved = 0; - - (*slots) -= (sizeof(struct heci_msg_hdr) + - heci_hdr->length + 3) / 4; - if (!heci_write_message(dev, heci_hdr, - (unsigned char *) - (priv_cb_pos->request_buffer.data + - priv_cb_pos->information), - heci_hdr->length)) { - file_ext->status = -ENODEV; - list_move_tail(&priv_cb_pos->cb_list, - &cmpl_list->heci_cb.cb_list); - return -ENODEV; - } else { - priv_cb_pos->information += heci_hdr->length; - DBG("priv_cb_pos->request_buffer.size =%d" - " heci_hdr->msg_complete= %d\n", - priv_cb_pos->request_buffer.size, - heci_hdr->msg_complete); - DBG("priv_cb_pos->information =%lu\n", - priv_cb_pos->information); - DBG("heci_hdr->length =%d\n", heci_hdr->length); - } - return -ECOMPLETE_MESSAGE; - } else { - return -ECORRUPTED_MESSAGE_HEADER; - } - - return 0; -} - -/** - * _heci_bh_cmpl_iamthif - process completed iamthif operation. - * - * @dev: Device object for our driver. - * @slots: free slots. - * @priv_cb_pos: callback block. - * @file_ext: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _heci_bh_cmpl_iamthif(struct iamt_heci_device *dev, __s32 *slots, - struct heci_cb_private *priv_cb_pos, - struct heci_file_private *file_ext, - struct io_heci_list *cmpl_list) -{ - struct heci_msg_hdr *heci_hdr; - - if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) + - dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index)) { - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = file_ext->host_client_id; - heci_hdr->me_addr = file_ext->me_client_id; - heci_hdr->length = dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index; - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - *slots -= (sizeof(struct heci_msg_hdr) + - heci_hdr->length + 3) / 4; - - if (!heci_write_message(dev, heci_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - heci_hdr->length)) { - dev->iamthif_state = HECI_IAMTHIF_IDLE; - file_ext->status = -ENODEV; - list_del(&priv_cb_pos->cb_list); - return -ENODEV; - } else { - flow_ctrl_reduce(dev, file_ext); - dev->iamthif_msg_buf_index += heci_hdr->length; - priv_cb_pos->information = dev->iamthif_msg_buf_index; - file_ext->status = 0; - dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = 1; - /* save iamthif cb sent to pthi client */ - dev->iamthif_current_cb = priv_cb_pos; - list_move_tail(&priv_cb_pos->cb_list, - &dev->write_waiting_list.heci_cb.cb_list); - - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; - heci_hdr->host_addr = file_ext->host_client_id; - heci_hdr->me_addr = file_ext->me_client_id; - heci_hdr->length = - (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr); - heci_hdr->msg_complete = 0; - heci_hdr->reserved = 0; - - *slots -= (sizeof(struct heci_msg_hdr) + - heci_hdr->length + 3) / 4; - - if (!heci_write_message(dev, heci_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - heci_hdr->length)) { - file_ext->status = -ENODEV; - list_del(&priv_cb_pos->cb_list); - } else { - dev->iamthif_msg_buf_index += heci_hdr->length; - } - return -ECOMPLETE_MESSAGE; - } else { - return -ECORRUPTED_MESSAGE_HEADER; - } - - return 0; -} - -/** - * heci_bh_write_handler - bottom half write routine after - * ISR to handle the write processing. - * - * @cmpl_list: An instance of our list structure - * @dev: Device object for our driver - * @slots: slots to write. - * - * returns 0 on success, <0 on failure. - */ -static int heci_bh_write_handler(struct io_heci_list *cmpl_list, - struct iamt_heci_device *dev, - __s32 *slots) -{ - - struct heci_file_private *file_ext; - struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL; - struct io_heci_list *list; - int ret; - - if (!host_buffer_is_empty(dev)) { - DBG("host buffer is not empty.\n"); - return 0; - } - dev->write_hang = -1; - *slots = count_empty_write_slots(dev); - /* complete all waiting for write CB */ - DBG("complete all waiting for write cb.\n"); - - list = &dev->write_waiting_list; - if ((list->status == 0) - && !list_empty(&list->heci_cb.cb_list)) { - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &list->heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - if (file_ext != NULL) { - file_ext->status = 0; - list_del(&priv_cb_pos->cb_list); - if ((HECI_WRITING == file_ext->writing_state) && - (priv_cb_pos->major_file_operations == - HECI_WRITE) && - (file_ext != &dev->iamthif_file_ext)) { - DBG("HECI WRITE COMPLETE\n"); - file_ext->writing_state = - HECI_WRITE_COMPLETE; - list_add_tail(&priv_cb_pos->cb_list, - &cmpl_list->heci_cb.cb_list); - } - if (file_ext == &dev->iamthif_file_ext) { - DBG("check iamthif flow control.\n"); - if (dev->iamthif_flow_control_pending) { - ret = _heci_bh_iamthif_read(dev, - slots); - if (ret != 0) - return ret; - } - } - } - - } - } - - if ((dev->stop) && (!dev->wd_pending)) { - dev->wd_stoped = 1; - wake_up_interruptible(&dev->wait_stop_wd); - return 0; - } - - if (dev->extra_write_index != 0) { - DBG("extra_write_index =%d.\n", dev->extra_write_index); - heci_write_message(dev, - (struct heci_msg_hdr *) &dev->ext_msg_buf[0], - (unsigned char *) &dev->ext_msg_buf[1], - (dev->extra_write_index - 1) * sizeof(__u32)); - *slots -= dev->extra_write_index; - dev->extra_write_index = 0; - } - if (dev->heci_state == HECI_ENABLED) { - if ((dev->wd_pending) - && flow_ctrl_creds(dev, &dev->wd_file_ext)) { - if (!heci_send_wd(dev)) - DBG("wd send failed.\n"); - else - flow_ctrl_reduce(dev, &dev->wd_file_ext); - - dev->wd_pending = 0; - - if (dev->wd_timeout != 0) { - *slots -= (sizeof(struct heci_msg_hdr) + - HECI_START_WD_DATA_SIZE + 3) / 4; - dev->wd_due_counter = 2; - } else { - *slots -= (sizeof(struct heci_msg_hdr) + - HECI_WD_PARAMS_SIZE + 3) / 4; - dev->wd_due_counter = 0; - } - - } - } - if (dev->stop) - return ~ENODEV; - - /* complete control write list CB */ - if (dev->ctrl_wr_list.status == 0) { - /* complete control write list CB */ - DBG("complete control write list cb.\n"); - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->ctrl_wr_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - if (file_ext == NULL) { - list_del(&priv_cb_pos->cb_list); - return -ENODEV; - } - switch (priv_cb_pos->major_file_operations) { - case HECI_CLOSE: - /* send disconnect message */ - ret = _heci_bh_close(dev, slots, - priv_cb_pos, - file_ext, cmpl_list); - if (ret != 0) - return ret; - - break; - case HECI_READ: - /* send flow control message */ - ret = _heci_bh_read(dev, slots, - priv_cb_pos, - file_ext, cmpl_list); - if (ret != 0) - return ret; - - break; - case HECI_IOCTL: - /* connect message */ - if (!other_client_is_connecting(dev, file_ext)) - continue; - ret = _heci_bh_ioctl(dev, slots, - priv_cb_pos, - file_ext, cmpl_list); - if (ret != 0) - return ret; - - break; - - default: - BUG(); - } - - } - } - /* complete write list CB */ - if ((dev->write_list.status == 0) - && !list_empty(&dev->write_list.heci_cb.cb_list)) { - DBG("complete write list cb.\n"); - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->write_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - - if (file_ext != NULL) { - if (file_ext != &dev->iamthif_file_ext) { - if (!flow_ctrl_creds(dev, file_ext)) { - DBG("No flow control" - " credentials for client" - " %d, not sending.\n", - file_ext->host_client_id); - continue; - } - ret = _heci_bh_cmpl(dev, slots, - priv_cb_pos, - file_ext, - cmpl_list); - if (ret != 0) - return ret; - - } else if (file_ext == &dev->iamthif_file_ext) { - /* IAMTHIF IOCTL */ - DBG("complete pthi write cb.\n"); - if (!flow_ctrl_creds(dev, file_ext)) { - DBG("No flow control" - " credentials for pthi" - " client %d.\n", - file_ext->host_client_id); - continue; - } - ret = _heci_bh_cmpl_iamthif(dev, slots, - priv_cb_pos, - file_ext, - cmpl_list); - if (ret != 0) - return ret; - - } - } - - } - } - return 0; -} - - -/** - * is_treat_specially_client - check if the message belong - * to the file private data. - * - * @file_ext: private data of the file object - * @rs: connect response bus message - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -static int is_treat_specially_client(struct heci_file_private *file_ext, - struct hbm_client_connect_response *rs) -{ - int ret = 0; - - if ((file_ext->host_client_id == rs->host_addr) && - (file_ext->me_client_id == rs->me_addr)) { - if (rs->status == 0) { - DBG("client connect status = 0x%08x.\n", rs->status); - file_ext->state = HECI_FILE_CONNECTED; - file_ext->status = 0; - } else { - DBG("client connect status = 0x%08x.\n", rs->status); - file_ext->state = HECI_FILE_DISCONNECTED; - file_ext->status = -ENODEV; - } - ret = 1; - } - DBG("client state = %d.\n", file_ext->state); - return ret; -} - -/** - * heci_client_connect_response - connect response bh routine - * - * @dev: Device object for our driver - * @rs: connect response bus message - */ -static void heci_client_connect_response(struct iamt_heci_device *dev, - struct hbm_client_connect_response *rs) -{ - - struct heci_file_private *file_ext; - struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL; - - /* if WD or iamthif client treat specially */ - - if ((is_treat_specially_client(&(dev->wd_file_ext), rs)) || - (is_treat_specially_client(&(dev->iamthif_file_ext), rs))) - return; - - if (dev->ctrl_rd_list.status == 0 - && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) { - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - if (file_ext == NULL) { - list_del(&priv_cb_pos->cb_list); - return; - } - if (HECI_IOCTL == priv_cb_pos->major_file_operations) { - if (is_treat_specially_client(file_ext, rs)) { - list_del(&priv_cb_pos->cb_list); - file_ext->status = 0; - file_ext->timer_count = 0; - break; - } - } - } - } -} - -/** - * heci_client_disconnect_response - disconnect response bh routine - * - * @dev: Device object for our driver - * @rs: disconnect response bus message - */ -static void heci_client_disconnect_response(struct iamt_heci_device *dev, - struct hbm_client_connect_response *rs) -{ - struct heci_file_private *file_ext; - struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL; - - if (dev->ctrl_rd_list.status == 0 - && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) { - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) { - file_ext = (struct heci_file_private *) - priv_cb_pos->file_private; - - if (file_ext == NULL) { - list_del(&priv_cb_pos->cb_list); - return; - } - - DBG("list_for_each_entry_safe in ctrl_rd_list.\n"); - if ((file_ext->host_client_id == rs->host_addr) && - (file_ext->me_client_id == rs->me_addr)) { - - list_del(&priv_cb_pos->cb_list); - if (rs->status == 0) { - file_ext->state = - HECI_FILE_DISCONNECTED; - } - - file_ext->status = 0; - file_ext->timer_count = 0; - break; - } - } - } -} - -/** - * same_flow_addr - tell they have same address. - * - * @file: private data of the file object. - * @flow: flow control. - * - * returns !=0, same; 0,not. - */ -static int same_flow_addr(struct heci_file_private *file, - struct hbm_flow_control *flow) -{ - return ((file->host_client_id == flow->host_addr) - && (file->me_client_id == flow->me_addr)); -} - -/** - * add_single_flow_creds - add single buffer credentials. - * - * @file: private data ot the file object. - * @flow: flow control. - */ -static void add_single_flow_creds(struct iamt_heci_device *dev, - struct hbm_flow_control *flow) -{ - struct heci_me_client *client; - int i; - - for (i = 0; i < dev->num_heci_me_clients; i++) { - client = &dev->me_clients[i]; - if ((client != NULL) && - (flow->me_addr == client->client_id)) { - if (client->props.single_recv_buf != 0) { - client->flow_ctrl_creds++; - DBG("recv flow ctrl msg ME %d (single).\n", - flow->me_addr); - DBG("flow control credentials=%d.\n", - client->flow_ctrl_creds); - } else { - BUG(); /* error in flow control */ - } - } - } -} - -/** - * heci_client_flow_control_response - flow control response bh routine - * - * @dev: Device object for our driver - * @flow_control: flow control response bus message - */ -static void heci_client_flow_control_response(struct iamt_heci_device *dev, - struct hbm_flow_control *flow_control) -{ - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - - if (flow_control->host_addr == 0) { - /* single receive buffer */ - add_single_flow_creds(dev, flow_control); - } else { - /* normal connection */ - list_for_each_entry_safe(file_pos, file_next, - &dev->file_list, link) { - DBG("list_for_each_entry_safe in file_list\n"); - - DBG("file_ext of host client %d ME client %d.\n", - file_pos->host_client_id, - file_pos->me_client_id); - DBG("flow ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - if (same_flow_addr(file_pos, flow_control)) { - DBG("recv ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - file_pos->flow_ctrl_creds++; - DBG("flow control credentials=%d.\n", - file_pos->flow_ctrl_creds); - break; - } - } - } -} - -/** - * same_disconn_addr - tell they have same address - * - * @file: private data of the file object. - * @disconn: disconnection request. - * - * returns !=0, same; 0,not. - */ -static int same_disconn_addr(struct heci_file_private *file, - struct hbm_client_disconnect_request *disconn) -{ - return ((file->host_client_id == disconn->host_addr) - && (file->me_client_id == disconn->me_addr)); -} - -/** - * heci_client_disconnect_request - disconnect request bh routine - * - * @dev: Device object for our driver. - * @disconnect_req: disconnect request bus message. - */ -static void heci_client_disconnect_request(struct iamt_heci_device *dev, - struct hbm_client_disconnect_request *disconnect_req) -{ - struct heci_msg_hdr *heci_hdr; - struct hbm_client_connect_response *disconnect_res; - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - - list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) { - if (same_disconn_addr(file_pos, disconnect_req)) { - DBG("disconnect request host client %d ME client %d.\n", - disconnect_req->host_addr, - disconnect_req->me_addr); - file_pos->state = HECI_FILE_DISCONNECTED; - file_pos->timer_count = 0; - if (file_pos == &dev->wd_file_ext) { - dev->wd_due_counter = 0; - dev->wd_pending = 0; - } else if (file_pos == &dev->iamthif_file_ext) - dev->iamthif_timer = 0; - - /* prepare disconnect response */ - heci_hdr = - (struct heci_msg_hdr *) &dev->ext_msg_buf[0]; - heci_hdr->host_addr = 0; - heci_hdr->me_addr = 0; - heci_hdr->length = - sizeof(struct hbm_client_connect_response); - heci_hdr->msg_complete = 1; - heci_hdr->reserved = 0; - - disconnect_res = - (struct hbm_client_connect_response *) - &dev->ext_msg_buf[1]; - disconnect_res->host_addr = file_pos->host_client_id; - disconnect_res->me_addr = file_pos->me_client_id; - *(__u8 *) (&disconnect_res->cmd) = - CLIENT_DISCONNECT_RES_CMD; - disconnect_res->status = 0; - dev->extra_write_index = 2; - break; - } - } -} - -/** - * heci_timer - timer function. - * - * @data: pointer to the device structure - * - * NOTE: This function is called by timer interrupt work - */ -void heci_wd_timer(unsigned long data) -{ - struct iamt_heci_device *dev = (struct iamt_heci_device *) data; - - DBG("send watchdog.\n"); - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ)); - spin_unlock_bh(&dev->device_lock); - return; - } - if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) { - mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ)); - spin_unlock_bh(&dev->device_lock); - return; - } - /* Watchdog */ - if ((dev->wd_due_counter != 0) && (dev->wd_bypass == 0)) { - if (--dev->wd_due_counter == 0) { - if (dev->host_buffer_is_empty && - flow_ctrl_creds(dev, &dev->wd_file_ext)) { - dev->host_buffer_is_empty = 0; - if (!heci_send_wd(dev)) { - DBG("wd send failed.\n"); - } else { - flow_ctrl_reduce(dev, - &dev->wd_file_ext); - } - - if (dev->wd_timeout != 0) - dev->wd_due_counter = 2; - else - dev->wd_due_counter = 0; - - } else - dev->wd_pending = 1; - - } - } - if (dev->iamthif_stall_timer != 0) { - if (--dev->iamthif_stall_timer == 0) { - DBG("reseting because of hang to PTHI.\n"); - heci_reset(dev, 1); - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; - dev->iamthif_state = HECI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - spin_unlock_bh(&dev->device_lock); - - if (dev->iamthif_current_cb) - heci_free_cb_private(dev->iamthif_current_cb); - - spin_lock_bh(&dev->device_lock); - dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; - run_next_iamthif_cmd(dev); - } - } - mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ)); - spin_unlock_bh(&dev->device_lock); -} diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c deleted file mode 100644 index 1a6faf88e16..00000000000 --- a/drivers/staging/heci/io_heci.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * Part of Intel(R) Manageability Engine Interface Linux driver - * - * Copyright (c) 2003 - 2008 Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "heci_data_structures.h" -#include "heci.h" -#include "heci_interface.h" -#include "heci_version.h" - - -/** - * heci_ioctl_get_version - the get driver version IOCTL function - * - * @dev: Device object for our driver - * @if_num: minor number - * @*u_msg: pointer to user data struct in user space - * @k_msg: data in kernel on the stack - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num, - struct heci_message_data __user *u_msg, - struct heci_message_data k_msg, - struct heci_file_private *file_ext) -{ - int rets = 0; - struct heci_driver_version *version; - struct heci_message_data res_msg; - - if ((if_num != HECI_MINOR_NUMBER) || (!dev) - || (!file_ext)) - return -ENODEV; - - if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) { - DBG("user buffer less than heci_driver_version.\n"); - return -EMSGSIZE; - } - - res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL); - if (!res_msg.data) { - DBG("failed allocation response buffer size = %d.\n", - (int) sizeof(struct heci_driver_version)); - return -ENOMEM; - } - - version = (struct heci_driver_version *) res_msg.data; - version->major = MAJOR_VERSION; - version->minor = MINOR_VERSION; - version->hotfix = QUICK_FIX_NUMBER; - version->build = VER_BUILD; - res_msg.size = sizeof(struct heci_driver_version); - if (k_msg.size < sizeof(struct heci_driver_version)) - res_msg.size -= 2; - - rets = file_ext->status; - /* now copy the data to user space */ - if (copy_to_user((void __user *)k_msg.data, res_msg.data, res_msg.size)) { - rets = -EFAULT; - goto end; - } - if (put_user(res_msg.size, &u_msg->size)) { - rets = -EFAULT; - goto end; - } -end: - kfree(res_msg.data); - return rets; -} - -/** - * heci_ioctl_connect_client - the connect to fw client IOCTL function - * - * @dev: Device object for our driver - * @if_num: minor number - * @*u_msg: pointer to user data struct in user space - * @k_msg: data in kernel on the stack - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, - struct heci_message_data __user *u_msg, - struct heci_message_data k_msg, - struct file *file) -{ - int rets = 0; - struct heci_message_data req_msg, res_msg; - struct heci_cb_private *priv_cb = NULL; - struct heci_client *client; - struct heci_file_private *file_ext; - struct heci_file_private *file_pos = NULL; - struct heci_file_private *file_next = NULL; - long timeout = 15; /*15 second */ - __u8 i; - int err = 0; - - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file)) - return -ENODEV; - - file_ext = file->private_data; - if (!file_ext) - return -ENODEV; - - if (k_msg.size != sizeof(struct guid)) { - DBG("user buffer size is not equal to size of struct " - "guid(16).\n"); - return -EMSGSIZE; - } - - if (!k_msg.data) - return -EIO; - - req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL); - res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL); - - if (!res_msg.data) { - DBG("failed allocation response buffer size = %d.\n", - (int) sizeof(struct heci_client)); - kfree(req_msg.data); - return -ENOMEM; - } - if (!req_msg.data) { - DBG("failed allocation request buffer size = %d.\n", - (int) sizeof(struct guid)); - kfree(res_msg.data); - return -ENOMEM; - } - req_msg.size = sizeof(struct guid); - res_msg.size = sizeof(struct heci_client); - - /* copy the message to kernel space - - * use a pointer already copied into kernel space - */ - if (copy_from_user(req_msg.data, (void __user *)k_msg.data, k_msg.size)) { - rets = -EFAULT; - goto end; - } - /* buffered ioctl cb */ - priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); - if (!priv_cb) { - rets = -ENOMEM; - goto end; - } - INIT_LIST_HEAD(&priv_cb->cb_list); - priv_cb->response_buffer.data = res_msg.data; - priv_cb->response_buffer.size = res_msg.size; - priv_cb->request_buffer.data = req_msg.data; - priv_cb->request_buffer.size = req_msg.size; - priv_cb->major_file_operations = HECI_IOCTL; - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - goto end; - } - if ((file_ext->state != HECI_FILE_INITIALIZING) && - (file_ext->state != HECI_FILE_DISCONNECTED)) { - rets = -EBUSY; - spin_unlock_bh(&dev->device_lock); - goto end; - } - - /* find ME client we're trying to connect to */ - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (memcmp((struct guid *)req_msg.data, - &dev->me_clients[i].props.protocol_name, - sizeof(struct guid)) == 0) { - if (dev->me_clients[i].props.fixed_address == 0) { - file_ext->me_client_id = - dev->me_clients[i].client_id; - file_ext->state = HECI_FILE_CONNECTING; - } - break; - } - } - /* if we're connecting to PTHI client so we will use the exist - * connection - */ - if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid, - sizeof(struct guid)) == 0) { - if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - goto end; - } - dev->heci_host_clients[file_ext->host_client_id / 8] &= - ~(1 << (file_ext->host_client_id % 8)); - list_for_each_entry_safe(file_pos, - file_next, &dev->file_list, link) { - if (heci_fe_same_id(file_ext, file_pos)) { - DBG("remove file private data node host" - " client = %d, ME client = %d.\n", - file_pos->host_client_id, - file_pos->me_client_id); - list_del(&file_pos->link); - } - - } - DBG("free file private data memory.\n"); - kfree(file_ext); - file_ext = NULL; - file->private_data = &dev->iamthif_file_ext; - client = (struct heci_client *) res_msg.data; - client->max_msg_length = - dev->me_clients[i].props.max_msg_length; - client->protocol_version = - dev->me_clients[i].props.protocol_version; - rets = dev->iamthif_file_ext.status; - spin_unlock_bh(&dev->device_lock); - - /* now copy the data to user space */ - if (copy_to_user((void __user *)k_msg.data, - res_msg.data, res_msg.size)) { - rets = -EFAULT; - goto end; - } - if (put_user(res_msg.size, &u_msg->size)) { - rets = -EFAULT; - goto end; - } - goto end; - } - spin_unlock_bh(&dev->device_lock); - - spin_lock(&file_ext->file_lock); - spin_lock_bh(&dev->device_lock); - if (file_ext->state != HECI_FILE_CONNECTING) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - spin_unlock(&file_ext->file_lock); - goto end; - } - /* prepare the output buffer */ - client = (struct heci_client *) res_msg.data; - client->max_msg_length = dev->me_clients[i].props.max_msg_length; - client->protocol_version = dev->me_clients[i].props.protocol_version; - if (dev->host_buffer_is_empty - && !other_client_is_connecting(dev, file_ext)) { - dev->host_buffer_is_empty = 0; - if (!heci_connect(dev, file_ext)) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - spin_unlock(&file_ext->file_lock); - goto end; - } else { - file_ext->timer_count = HECI_CONNECT_TIMEOUT; - priv_cb->file_private = file_ext; - list_add_tail(&priv_cb->cb_list, - &dev->ctrl_rd_list.heci_cb. - cb_list); - } - - - } else { - priv_cb->file_private = file_ext; - DBG("add connect cb to control write list.\n"); - list_add_tail(&priv_cb->cb_list, - &dev->ctrl_wr_list.heci_cb.cb_list); - } - spin_unlock_bh(&dev->device_lock); - spin_unlock(&file_ext->file_lock); - err = wait_event_timeout(dev->wait_recvd_msg, - (HECI_FILE_CONNECTED == file_ext->state - || HECI_FILE_DISCONNECTED == file_ext->state), - timeout * HZ); - - spin_lock_bh(&dev->device_lock); - if (HECI_FILE_CONNECTED == file_ext->state) { - spin_unlock_bh(&dev->device_lock); - DBG("successfully connected to FW client.\n"); - rets = file_ext->status; - /* now copy the data to user space */ - if (copy_to_user((void __user *)k_msg.data, - res_msg.data, res_msg.size)) { - rets = -EFAULT; - goto end; - } - if (put_user(res_msg.size, &u_msg->size)) { - rets = -EFAULT; - goto end; - } - goto end; - } else { - DBG("failed to connect to FW client.file_ext->state = %d.\n", - file_ext->state); - spin_unlock_bh(&dev->device_lock); - if (!err) { - DBG("wait_event_interruptible_timeout failed on client" - " connect message fw response message.\n"); - } - rets = -EFAULT; - goto remove_list; - } - -remove_list: - if (priv_cb) { - spin_lock_bh(&dev->device_lock); - heci_flush_list(&dev->ctrl_rd_list, file_ext); - heci_flush_list(&dev->ctrl_wr_list, file_ext); - spin_unlock_bh(&dev->device_lock); - } -end: - DBG("free connect cb memory."); - kfree(req_msg.data); - kfree(res_msg.data); - kfree(priv_cb); - return rets; -} - -/** - * heci_ioctl_wd - the wd IOCTL function - * - * @dev: Device object for our driver - * @if_num: minor number - * @k_msg: data in kernel on the stack - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num, - struct heci_message_data k_msg, - struct heci_file_private *file_ext) -{ - int rets = 0; - struct heci_message_data req_msg; /*in kernel on the stack */ - - if (if_num != HECI_MINOR_NUMBER) - return -ENODEV; - - spin_lock(&file_ext->file_lock); - if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) { - DBG("user buffer has invalid size.\n"); - spin_unlock(&file_ext->file_lock); - return -EMSGSIZE; - } - spin_unlock(&file_ext->file_lock); - - req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL); - if (!req_msg.data) { - DBG("failed allocation request buffer size = %d.\n", - HECI_WATCHDOG_DATA_SIZE); - return -ENOMEM; - } - req_msg.size = HECI_WATCHDOG_DATA_SIZE; - - /* copy the message to kernel space - use a pointer already - * copied into kernel space - */ - if (copy_from_user(req_msg.data, - (void __user *)k_msg.data, req_msg.size)) { - rets = -EFAULT; - goto end; - } - spin_lock_bh(&dev->device_lock); - if (dev->heci_state != HECI_ENABLED) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - goto end; - } - - if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) { - rets = -ENODEV; - spin_unlock_bh(&dev->device_lock); - goto end; - } - if (!dev->asf_mode) { - rets = -EIO; - spin_unlock_bh(&dev->device_lock); - goto end; - } - - memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data, - HECI_WATCHDOG_DATA_SIZE); - - dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0]; - dev->wd_pending = 0; - dev->wd_due_counter = 1; /* next timer */ - if (dev->wd_timeout == 0) { - memcpy(dev->wd_data, heci_stop_wd_params, - HECI_WD_PARAMS_SIZE); - } else { - memcpy(dev->wd_data, heci_start_wd_params, - HECI_WD_PARAMS_SIZE); - mod_timer(&dev->wd_timer, jiffies); - } - spin_unlock_bh(&dev->device_lock); -end: - kfree(req_msg.data); - return rets; -} - - -/** - * heci_ioctl_bypass_wd - the bypass_wd IOCTL function - * - * @dev: Device object for our driver - * @if_num: minor number - * @k_msg: data in kernel on the stack - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num, - struct heci_message_data k_msg, - struct heci_file_private *file_ext) -{ - __u8 flag = 0; - int rets = 0; - - if (if_num != HECI_MINOR_NUMBER) - return -ENODEV; - - spin_lock(&file_ext->file_lock); - if (k_msg.size < 1) { - DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n"); - spin_unlock(&file_ext->file_lock); - return -EMSGSIZE; - } - spin_unlock(&file_ext->file_lock); - if (copy_from_user(&flag, (void __user *)k_msg.data, 1)) { - rets = -EFAULT; - goto end; - } - - spin_lock_bh(&dev->device_lock); - flag = flag ? (1) : (0); - dev->wd_bypass = flag; - spin_unlock_bh(&dev->device_lock); -end: - return rets; -} - -/** - * find_pthi_read_list_entry - finds a PTHIlist entry for current file - * - * @dev: Device object for our driver - * @file: pointer to file object - * - * returns returned a list entry on success, NULL on failure. - */ -struct heci_cb_private *find_pthi_read_list_entry( - struct iamt_heci_device *dev, - struct file *file) -{ - struct heci_file_private *file_ext_temp; - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - - if ((dev->pthi_read_complete_list.status == 0) && - !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) { - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list) { - file_ext_temp = (struct heci_file_private *) - priv_cb_pos->file_private; - if ((file_ext_temp != NULL) && - (file_ext_temp == &dev->iamthif_file_ext) && - (priv_cb_pos->file_object == file)) - return priv_cb_pos; - } - } - return NULL; -} - -/** - * pthi_read - read data from pthi client - * - * @dev: Device object for our driver - * @if_num: minor number - * @file: pointer to file object - * @*ubuf: pointer to user data in user space - * @length: data length to read - * @offset: data read offset - * - * returns - * returned data length on success, - * zero if no data to read, - * negative on failure. - */ -int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file, - char __user *ubuf, size_t length, loff_t *offset) -{ - int rets = 0; - struct heci_cb_private *priv_cb = NULL; - struct heci_file_private *file_ext = file->private_data; - __u8 i; - unsigned long currtime = get_seconds(); - - if ((if_num != HECI_MINOR_NUMBER) || (!dev)) - return -ENODEV; - - if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext)) - return -ENODEV; - - spin_lock_bh(&dev->device_lock); - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_file_ext.me_client_id) - break; - } - BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); - if ((i == dev->num_heci_me_clients) - || (dev->me_clients[i].client_id != - dev->iamthif_file_ext.me_client_id)) { - DBG("PTHI client not found.\n"); - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - priv_cb = find_pthi_read_list_entry(dev, file); - if (!priv_cb) { - spin_unlock_bh(&dev->device_lock); - return 0; /* No more data to read */ - } else { - if (priv_cb && - (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) { - /* 15 sec for the message has expired */ - list_del(&priv_cb->cb_list); - spin_unlock_bh(&dev->device_lock); - rets = -ETIMEDOUT; - goto free; - } - /* if the whole message will fit remove it from the list */ - if ((priv_cb->information >= *offset) && - (length >= (priv_cb->information - *offset))) - list_del(&priv_cb->cb_list); - else if ((priv_cb->information > 0) && - (priv_cb->information <= *offset)) { - /* end of the message has been reached */ - list_del(&priv_cb->cb_list); - rets = 0; - spin_unlock_bh(&dev->device_lock); - goto free; - } - /* else means that not full buffer will be read and do not - * remove message from deletion list - */ - } - DBG("pthi priv_cb->response_buffer size - %d\n", - priv_cb->response_buffer.size); - DBG("pthi priv_cb->information - %lu\n", - priv_cb->information); - spin_unlock_bh(&dev->device_lock); - - /* length is being turncated to PAGE_SIZE, however, - * the information may be longer */ - length = length < (priv_cb->information - *offset) ? - length : (priv_cb->information - *offset); - - if (copy_to_user(ubuf, - priv_cb->response_buffer.data + *offset, - length)) - rets = -EFAULT; - else { - rets = length; - if ((*offset + length) < priv_cb->information) { - *offset += length; - goto out; - } - } -free: - DBG("free pthi cb memory.\n"); - *offset = 0; - heci_free_cb_private(priv_cb); -out: - return rets; -} - -/** - * heci_start_read - the start read client message function. - * - * @dev: Device object for our driver - * @if_num: minor number - * @file_ext: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int heci_start_read(struct iamt_heci_device *dev, int if_num, - struct heci_file_private *file_ext) -{ - int rets = 0; - __u8 i; - struct heci_cb_private *priv_cb = NULL; - - if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) { - DBG("received wrong function input param.\n"); - return -ENODEV; - } - - spin_lock_bh(&dev->device_lock); - if (file_ext->state != HECI_FILE_CONNECTED) { - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - - if (dev->heci_state != HECI_ENABLED) { - spin_unlock_bh(&dev->device_lock); - return -ENODEV; - } - spin_unlock_bh(&dev->device_lock); - DBG("check if read is pending.\n"); - spin_lock_bh(&file_ext->read_io_lock); - if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) { - DBG("read is pending.\n"); - spin_unlock_bh(&file_ext->read_io_lock); - return -EBUSY; - } - spin_unlock_bh(&file_ext->read_io_lock); - - priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); - if (!priv_cb) - return -ENOMEM; - - spin_lock_bh(&file_ext->read_io_lock); - DBG("allocation call back success\n" - "host client = %d, ME client = %d\n", - file_ext->host_client_id, file_ext->me_client_id); - spin_unlock_bh(&file_ext->read_io_lock); - - spin_lock_bh(&dev->device_lock); - spin_lock_bh(&file_ext->read_io_lock); - for (i = 0; i < dev->num_heci_me_clients; i++) { - if (dev->me_clients[i].client_id == file_ext->me_client_id) - break; - - } - - BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); - spin_unlock_bh(&file_ext->read_io_lock); - if (i == dev->num_heci_me_clients) { - rets = -ENODEV; - goto unlock; - } - - priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length; - spin_unlock_bh(&dev->device_lock); - priv_cb->response_buffer.data = - kmalloc(priv_cb->response_buffer.size, GFP_KERNEL); - if (!priv_cb->response_buffer.data) { - rets = -ENOMEM; - goto fail; - } - DBG("allocation call back data success.\n"); - priv_cb->major_file_operations = HECI_READ; - /* make sure information is zero before we start */ - priv_cb->information = 0; - priv_cb->file_private = (void *) file_ext; - spin_lock_bh(&dev->device_lock); - spin_lock_bh(&file_ext->read_io_lock); - file_ext->read_cb = priv_cb; - if (dev->host_buffer_is_empty) { - dev->host_buffer_is_empty = 0; - if (!heci_send_flow_control(dev, file_ext)) { - rets = -ENODEV; - spin_unlock_bh(&file_ext->read_io_lock); - goto unlock; - } else { - list_add_tail(&priv_cb->cb_list, - &dev->read_list.heci_cb.cb_list); - } - } else { - list_add_tail(&priv_cb->cb_list, - &dev->ctrl_wr_list.heci_cb.cb_list); - } - spin_unlock_bh(&file_ext->read_io_lock); - spin_unlock_bh(&dev->device_lock); - return rets; -unlock: - spin_unlock_bh(&dev->device_lock); -fail: - heci_free_cb_private(priv_cb); - return rets; -} - -/** - * pthi_write - write iamthif data to pthi client - * - * @dev: Device object for our driver - * @priv_cb: heci call back struct - * - * returns 0 on success, <0 on failure. - */ -int pthi_write(struct iamt_heci_device *dev, - struct heci_cb_private *priv_cb) -{ - int rets = 0; - struct heci_msg_hdr heci_hdr; - - if ((!dev) || (!priv_cb)) - return -ENODEV; - - DBG("write data to pthi client.\n"); - - dev->iamthif_state = HECI_IAMTHIF_WRITING; - dev->iamthif_current_cb = priv_cb; - dev->iamthif_file_object = priv_cb->file_object; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; - dev->iamthif_msg_buf_size = priv_cb->request_buffer.size; - memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data, - priv_cb->request_buffer.size); - - if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) && - dev->host_buffer_is_empty) { - dev->host_buffer_is_empty = 0; - if (priv_cb->request_buffer.size > - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(__u32)) - sizeof(struct heci_msg_hdr)) { - heci_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(__u32)) - sizeof(struct heci_msg_hdr); - heci_hdr.msg_complete = 0; - } else { - heci_hdr.length = priv_cb->request_buffer.size; - heci_hdr.msg_complete = 1; - } - - heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id; - heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id; - heci_hdr.reserved = 0; - dev->iamthif_msg_buf_index += heci_hdr.length; - if (!heci_write_message(dev, &heci_hdr, - (unsigned char *)(dev->iamthif_msg_buf), - heci_hdr.length)) - return -ENODEV; - - if (heci_hdr.msg_complete) { - flow_ctrl_reduce(dev, &dev->iamthif_file_ext); - dev->iamthif_flow_control_pending = 1; - dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL; - DBG("add pthi cb to write waiting list\n"); - dev->iamthif_current_cb = priv_cb; - dev->iamthif_file_object = priv_cb->file_object; - list_add_tail(&priv_cb->cb_list, - &dev->write_waiting_list.heci_cb.cb_list); - } else { - DBG("message does not complete, " - "so add pthi cb to write list.\n"); - list_add_tail(&priv_cb->cb_list, - &dev->write_list.heci_cb.cb_list); - } - } else { - if (!(dev->host_buffer_is_empty)) - DBG("host buffer is not empty"); - - DBG("No flow control credentials, " - "so add iamthif cb to write list.\n"); - list_add_tail(&priv_cb->cb_list, - &dev->write_list.heci_cb.cb_list); - } - return rets; -} - -/** - * iamthif_ioctl_send_msg - send cmd data to pthi client - * - * @dev: Device object for our driver - * - * returns 0 on success, <0 on failure. - */ -void run_next_iamthif_cmd(struct iamt_heci_device *dev) -{ - struct heci_file_private *file_ext_tmp; - struct heci_cb_private *priv_cb_pos = NULL; - struct heci_cb_private *priv_cb_next = NULL; - int status = 0; - - if (!dev) - return; - - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; - dev->iamthif_state = HECI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - dev->iamthif_file_object = NULL; - - if (dev->pthi_cmd_list.status == 0 && - !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) { - DBG("complete pthi cmd_list cb.\n"); - - list_for_each_entry_safe(priv_cb_pos, priv_cb_next, - &dev->pthi_cmd_list.heci_cb.cb_list, cb_list) { - list_del(&priv_cb_pos->cb_list); - file_ext_tmp = (struct heci_file_private *) - priv_cb_pos->file_private; - - if ((file_ext_tmp != NULL) && - (file_ext_tmp == &dev->iamthif_file_ext)) { - status = pthi_write(dev, priv_cb_pos); - if (status != 0) { - DBG("pthi write failed status = %d\n", - status); - return; - } - break; - } - } - } -} - -/** - * heci_free_cb_private - free heci_cb_private related memory - * - * @priv_cb: heci callback struct - */ -void heci_free_cb_private(struct heci_cb_private *priv_cb) -{ - if (priv_cb == NULL) - return; - - kfree(priv_cb->request_buffer.data); - kfree(priv_cb->response_buffer.data); - kfree(priv_cb); -} - -- cgit v1.2.3 From e9d599220b97e7d52311f6011c75ba0cfcb356fe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 15 Sep 2009 10:09:27 -0700 Subject: Staging: remove sxg driver Unfortunatly, the upstream company has abandonded development of this driver. So it's best to just remove the driver from the tree. Cc: Christopher Harrer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/sxg/Kconfig | 11 - drivers/staging/sxg/Makefile | 3 - drivers/staging/sxg/README | 12 - drivers/staging/sxg/sxg.c | 4543 ---------------------------------- drivers/staging/sxg/sxg.h | 787 ------ drivers/staging/sxg/sxg_ethtool.c | 328 --- drivers/staging/sxg/sxg_os.h | 149 -- drivers/staging/sxg/sxgdbg.h | 184 -- drivers/staging/sxg/sxghif.h | 1014 -------- drivers/staging/sxg/sxghw.h | 1020 -------- drivers/staging/sxg/sxgphycode-1.2.h | 130 - 13 files changed, 8184 deletions(-) delete mode 100644 drivers/staging/sxg/Kconfig delete mode 100644 drivers/staging/sxg/Makefile delete mode 100644 drivers/staging/sxg/README delete mode 100644 drivers/staging/sxg/sxg.c delete mode 100644 drivers/staging/sxg/sxg.h delete mode 100644 drivers/staging/sxg/sxg_ethtool.c delete mode 100644 drivers/staging/sxg/sxg_os.h delete mode 100644 drivers/staging/sxg/sxgdbg.h delete mode 100644 drivers/staging/sxg/sxghif.h delete mode 100644 drivers/staging/sxg/sxghw.h delete mode 100644 drivers/staging/sxg/sxgphycode-1.2.h (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e86a6716156..10d3fcffe91 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -45,8 +45,6 @@ source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" -source "drivers/staging/sxg/Kconfig" - source "drivers/staging/go7007/Kconfig" source "drivers/staging/usbip/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fa5361664ba..c30093bae62 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_STAGING) += staging.o obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ -obj-$(CONFIG_SXG) += sxg/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig deleted file mode 100644 index c5cbdafee4d..00000000000 --- a/drivers/staging/sxg/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config SXG - tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support" - depends on PCI && NETDEV_10000 - depends on X86 - default n - help - This driver supports the Alacritech SLIC Technology Non-Accelerated - 10Gbe network cards. - - To compile this driver as a module, choose - M here: the module will be called sxg_nic. diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile deleted file mode 100644 index 8e053222c2a..00000000000 --- a/drivers/staging/sxg/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_SXG) += sxg_nic.o - -sxg_nic-y := sxg.o sxg_ethtool.o diff --git a/drivers/staging/sxg/README b/drivers/staging/sxg/README deleted file mode 100644 index e42f344ea5f..00000000000 --- a/drivers/staging/sxg/README +++ /dev/null @@ -1,12 +0,0 @@ -This is the rough cut at a driver for the Alacritech SLIC Technology -Non-Accelerated 10Gbe network driver. - -TODO: - - remove wrappers - - checkpatch.pl cleanups - - new functionality that the card needs - - remove reliance on x86 - -Please send patches to: - Greg Kroah-Hartman -for any cleanups that you do to this driver. diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c deleted file mode 100644 index 395e876c7dc..00000000000 --- a/drivers/staging/sxg/sxg.c +++ /dev/null @@ -1,4543 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - * Parts developed by LinSysSoft Sahara team - * - **************************************************************************/ - -/* - * FILENAME: sxg.c - * - * The SXG driver for Alacritech's 10Gbe products. - * - * NOTE: This is the standard, non-accelerated version of Alacritech's - * IS-NIC driver. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SLIC_GET_STATS_ENABLED 0 -#define LINUX_FREES_ADAPTER_RESOURCES 1 -#define SXG_OFFLOAD_IP_CHECKSUM 0 -#define SXG_POWER_MANAGEMENT_ENABLED 0 -#define VPCI 0 -#define ATK_DEBUG 1 -#define SXG_UCODE_DEBUG 0 - - -#include "sxg_os.h" -#include "sxghw.h" -#include "sxghif.h" -#include "sxg.h" -#include "sxgdbg.h" -#include "sxgphycode-1.2.h" - -static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size, - enum sxg_buffer_type BufferType); -static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter, - void *RcvBlock, - dma_addr_t PhysicalAddress, - u32 Length); -static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter, - struct sxg_scatter_gather *SxgSgl, - dma_addr_t PhysicalAddress, - u32 Length); - -static void sxg_mcast_init_crc32(void); -static int sxg_entry_open(struct net_device *dev); -static int sxg_second_open(struct net_device * dev); -static int sxg_entry_halt(struct net_device *dev); -static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev); -static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb); -static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, - struct sxg_scatter_gather *SxgSgl); - -static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done, - int budget); -static void sxg_interrupt(struct adapter_t *adapter); -static int sxg_poll(struct napi_struct *napi, int budget); -static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId); -static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId, - int *sxg_napi_continue, int *work_done, int budget); -static void sxg_complete_slow_send(struct adapter_t *adapter); -static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, - struct sxg_event *Event); -static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus); -static bool sxg_mac_filter(struct adapter_t *adapter, - struct ether_header *EtherHdr, ushort length); -static struct net_device_stats *sxg_get_stats(struct net_device * dev); -void sxg_free_resources(struct adapter_t *adapter); -void sxg_free_rcvblocks(struct adapter_t *adapter); -void sxg_free_sgl_buffers(struct adapter_t *adapter); -void sxg_unmap_resources(struct adapter_t *adapter); -void sxg_free_mcast_addrs(struct adapter_t *adapter); -void sxg_collect_statistics(struct adapter_t *adapter); -static int sxg_register_interrupt(struct adapter_t *adapter); -static void sxg_remove_isr(struct adapter_t *adapter); -static irqreturn_t sxg_isr(int irq, void *dev_id); - -static void sxg_watchdog(unsigned long data); -static void sxg_update_link_status (struct work_struct *work); - -#define XXXTODO 0 - -#if XXXTODO -static int sxg_mac_set_address(struct net_device *dev, void *ptr); -#endif -static void sxg_mcast_set_list(struct net_device *dev); - -static int sxg_adapter_set_hwaddr(struct adapter_t *adapter); - -static int sxg_initialize_adapter(struct adapter_t *adapter); -static void sxg_stock_rcv_buffers(struct adapter_t *adapter); -static void sxg_complete_descriptor_blocks(struct adapter_t *adapter, - unsigned char Index); -int sxg_change_mtu (struct net_device *netdev, int new_mtu); -static int sxg_initialize_link(struct adapter_t *adapter); -static int sxg_phy_init(struct adapter_t *adapter); -static void sxg_link_event(struct adapter_t *adapter); -static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter); -static void sxg_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState); -static int sxg_write_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 Value); -static int sxg_read_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 *pValue); -static void sxg_set_mcast_addr(struct adapter_t *adapter); - -static unsigned int sxg_first_init = 1; -static char *sxg_banner = - "Alacritech SLIC Technology(tm) Server and Storage \ - 10Gbe Accelerator (Non-Accelerated)\n"; - -static int sxg_debug = 1; -static int debug = -1; -static struct net_device *head_netdevice = NULL; - -static struct sxgbase_driver sxg_global = { - .dynamic_intagg = 1, -}; -static int intagg_delay = 100; -static u32 dynamic_intagg = 0; - -char sxg_driver_name[] = "sxg_nic"; -#define DRV_AUTHOR "Alacritech, Inc. Engineering" -#define DRV_DESCRIPTION \ - "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver" -#define DRV_COPYRIGHT \ - "Copyright 2000-2008 Alacritech, Inc. All rights reserved." - -MODULE_AUTHOR(DRV_AUTHOR); -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_LICENSE("GPL"); - -module_param(dynamic_intagg, int, 0); -MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting"); -module_param(intagg_delay, int, 0); -MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay"); - -static struct pci_device_id sxg_pci_tbl[] __devinitdata = { - {PCI_DEVICE(SXG_VENDOR_ID, SXG_DEVICE_ID)}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, sxg_pci_tbl); - -static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush) -{ - writel(value, reg); - if (flush) - mb(); -} - -static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg, - u64 value, u32 cpu) -{ - u32 value_high = (u32) (value >> 32); - u32 value_low = (u32) (value & 0x00000000FFFFFFFF); - unsigned long flags; - - spin_lock_irqsave(&adapter->Bit64RegLock, flags); - writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper)); - writel(value_low, reg); - spin_unlock_irqrestore(&adapter->Bit64RegLock, flags); -} - -static void sxg_init_driver(void) -{ - if (sxg_first_init) { - DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n", - __func__, jiffies); - sxg_first_init = 0; - spin_lock_init(&sxg_global.driver_lock); - } -} - -static void sxg_dbg_macaddrs(struct adapter_t *adapter) -{ - DBG_ERROR(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - DBG_ERROR(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - adapter->netdev->name, adapter->macaddr[0], - adapter->macaddr[1], adapter->macaddr[2], - adapter->macaddr[3], adapter->macaddr[4], - adapter->macaddr[5]); - return; -} - -/* SXG Globals */ -static struct sxg_driver SxgDriver; - -#ifdef ATKDBG -static struct sxg_trace_buffer LSxgTraceBuffer; -#endif /* ATKDBG */ -static struct sxg_trace_buffer *SxgTraceBuffer = NULL; - -/* - * MSI Related API's - */ -int sxg_register_intr(struct adapter_t *adapter); -int sxg_enable_msi_x(struct adapter_t *adapter); -int sxg_add_msi_isr(struct adapter_t *adapter); -void sxg_remove_msix_isr(struct adapter_t *adapter); -int sxg_set_interrupt_capability(struct adapter_t *adapter); - -int sxg_set_interrupt_capability(struct adapter_t *adapter) -{ - int ret; - - ret = sxg_enable_msi_x(adapter); - if (ret != STATUS_SUCCESS) { - adapter->msi_enabled = FALSE; - DBG_ERROR("sxg_set_interrupt_capability MSI-X Disable\n"); - } else { - adapter->msi_enabled = TRUE; - DBG_ERROR("sxg_set_interrupt_capability MSI-X Enable\n"); - } - return ret; -} - -int sxg_register_intr(struct adapter_t *adapter) -{ - int ret = 0; - - if (adapter->msi_enabled) { - ret = sxg_add_msi_isr(adapter); - } - else { - DBG_ERROR("MSI-X Enable Failed. Using Pin INT\n"); - ret = sxg_register_interrupt(adapter); - if (ret != STATUS_SUCCESS) { - DBG_ERROR("sxg_register_interrupt Failed\n"); - } - } - return ret; -} - -int sxg_enable_msi_x(struct adapter_t *adapter) -{ - int ret; - - adapter->nr_msix_entries = 1; - adapter->msi_entries = kmalloc(adapter->nr_msix_entries * - sizeof(struct msix_entry),GFP_KERNEL); - if (!adapter->msi_entries) { - DBG_ERROR("%s:MSI Entries memory allocation Failed\n",__func__); - return -ENOMEM; - } - memset(adapter->msi_entries, 0, adapter->nr_msix_entries * - sizeof(struct msix_entry)); - - ret = pci_enable_msix(adapter->pcidev, adapter->msi_entries, - adapter->nr_msix_entries); - if (ret) { - DBG_ERROR("Enabling MSI-X with %d vectors failed\n", - adapter->nr_msix_entries); - /*Should try with less vector returned.*/ - kfree(adapter->msi_entries); - return STATUS_FAILURE; /*MSI-X Enable failed.*/ - } - return (STATUS_SUCCESS); -} - -int sxg_add_msi_isr(struct adapter_t *adapter) -{ - int ret,i; - - if (!adapter->intrregistered) { - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - for (i=0; inr_msix_entries; i++) { - ret = request_irq (adapter->msi_entries[i].vector, - sxg_isr, - IRQF_SHARED, - adapter->netdev->name, - adapter->netdev); - if (ret) { - spin_lock_irqsave(&sxg_global.driver_lock, - sxg_global.flags); - DBG_ERROR("sxg: MSI-X request_irq (%s) " - "FAILED [%x]\n", adapter->netdev->name, - ret); - return (ret); - } - } - } - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - adapter->msi_enabled = TRUE; - adapter->intrregistered = 1; - adapter->IntRegistered = TRUE; - return (STATUS_SUCCESS); -} - -void sxg_remove_msix_isr(struct adapter_t *adapter) -{ - int i,vector; - struct net_device *netdev = adapter->netdev; - - for(i=0; i< adapter->nr_msix_entries;i++) - { - vector = adapter->msi_entries[i].vector; - DBG_ERROR("%s : Freeing IRQ vector#%d\n",__func__,vector); - free_irq(vector,netdev); - } -} - - -static void sxg_remove_isr(struct adapter_t *adapter) -{ - struct net_device *netdev = adapter->netdev; - if (adapter->msi_enabled) - sxg_remove_msix_isr(adapter); - else - free_irq(adapter->netdev->irq, netdev); -} - -void sxg_reset_interrupt_capability(struct adapter_t *adapter) -{ - if (adapter->msi_enabled) { - pci_disable_msix(adapter->pcidev); - kfree(adapter->msi_entries); - adapter->msi_entries = NULL; - } - return; -} - -/* - * sxg_download_microcode - * - * Download Microcode to Sahara adapter using the Linux - * Firmware module to get the ucode.sys file. - * - * Arguments - - * adapter - A pointer to our adapter structure - * UcodeSel - microcode file selection - * - * Return - * int - */ -static bool sxg_download_microcode(struct adapter_t *adapter, - enum SXG_UCODE_SEL UcodeSel) -{ - const struct firmware *fw; - const char *file = ""; - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - int ret; - int ucode_start; - u32 Section; - u32 ThisSectionSize; - u32 instruction = 0; - u32 BaseAddress, AddressOffset, Address; - /* u32 Failure; */ - u32 ValueRead; - u32 i; - u32 index = 0; - u32 num_sections = 0; - u32 sectionSize[16]; - u32 sectionStart[16]; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod", - adapter, 0, 0, 0); - - /* - * This routine is only implemented to download the microcode - * for the Revision B Sahara chip. Rev A and Diagnostic - * microcode is not supported at this time. If Rev A or - * diagnostic ucode is required, this routine will obviously - * need to change. Also, eventually need to add support for - * Rev B checked version of ucode. That's easy enough once - * the free version of Rev B works. - */ - ASSERT(UcodeSel == SXG_UCODE_SYSTEM); - ASSERT(adapter->asictype == SAHARA_REV_B); -#if SXG_UCODE_DEBUG - file = "sxg/saharadbgdownloadB.sys"; -#else - file = "sxg/saharadownloadB.sys"; -#endif - ret = request_firmware(&fw, file, &adapter->pcidev->dev); - if (ret) { - DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file); - return ret; - } - - /* - * The microcode .sys file contains starts with a 4 byte word containing - * the number of sections. That is followed by "num_sections" 4 byte - * words containing each "section" size. That is followed num_sections - * 4 byte words containing each section "start" address. - * - * Following the above header, the .sys file contains num_sections, - * where each section size is specified, newline delineatetd 12 byte - * microcode instructions. - */ - num_sections = *(u32 *)(fw->data + index); - index += 4; - ASSERT(num_sections <= 3); - for (i = 0; i < num_sections; i++) { - sectionSize[i] = *(u32 *)(fw->data + index); - index += 4; - } - for (i = 0; i < num_sections; i++) { - sectionStart[i] = *(u32 *)(fw->data + index); - index += 4; - } - - /* First, reset the card */ - WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); - udelay(50); - HwRegs = adapter->HwRegs; - - /* - * Download each section of the microcode as specified in - * sectionSize[index] to sectionStart[index] address. As - * described above, the .sys file contains 12 byte word - * microcode instructions. The *download.sys file is generated - * using the objtosys.exe utility that was built for Sahara - * microcode. - */ - /* See usage of this below when we read back for parity */ - ucode_start = index; - instruction = *(u32 *)(fw->data + index); - index += 4; - - for (Section = 0; Section < num_sections; Section++) { - BaseAddress = sectionStart[Section]; - /* Size in instructions */ - ThisSectionSize = sectionSize[Section] / 12; - for (AddressOffset = 0; AddressOffset < ThisSectionSize; - AddressOffset++) { - u32 first_instr = 0; /* See comment below */ - - Address = BaseAddress + AddressOffset; - ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0); - /* Write instruction bits 31 - 0 (low) */ - first_instr = instruction; - WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction bits 63-32 (middle) */ - WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction bits 95-64 (high) */ - WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH); - instruction = *(u32 *)(fw->data + index); - index += 4; /* Advance to the "next" instruction */ - - /* Write instruction address with the WRITE bit set */ - WRITE_REG(HwRegs->UcodeAddr, - (Address | MICROCODE_ADDRESS_WRITE), FLUSH); - /* - * Sahara bug in the ucode download logic - the write to DataLow - * for the next instruction could get corrupted. To avoid this, - * write to DataLow again for this instruction (which may get - * corrupted, but it doesn't matter), then increment the address - * and write the data for the next instruction to DataLow. That - * write should succeed. - */ - WRITE_REG(HwRegs->UcodeDataLow, first_instr, FLUSH); - } - } - /* - * Now repeat the entire operation reading the instruction back and - * checking for parity errors - */ - index = ucode_start; - - for (Section = 0; Section < num_sections; Section++) { - BaseAddress = sectionStart[Section]; - /* Size in instructions */ - ThisSectionSize = sectionSize[Section] / 12; - for (AddressOffset = 0; AddressOffset < ThisSectionSize; - AddressOffset++) { - Address = BaseAddress + AddressOffset; - /* Write the address with the READ bit set */ - WRITE_REG(HwRegs->UcodeAddr, - (Address | MICROCODE_ADDRESS_READ), FLUSH); - /* Read it back and check parity bit. */ - READ_REG(HwRegs->UcodeAddr, ValueRead); - if (ValueRead & MICROCODE_ADDRESS_PARITY) { - DBG_ERROR("sxg: %s PARITY ERROR\n", - __func__); - - return FALSE; /* Parity error */ - } - ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address); - /* Read the instruction back and compare */ - /* First instruction */ - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataLow, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE LOW\n", - __func__); - return FALSE; /* Miscompare */ - } - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataMiddle, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n", - __func__); - return FALSE; /* Miscompare */ - } - instruction = *(u32 *)(fw->data + index); - index += 4; - READ_REG(HwRegs->UcodeDataHigh, ValueRead); - if (ValueRead != instruction) { - DBG_ERROR("sxg: %s MISCOMPARE HIGH\n", - __func__); - return FALSE; /* Miscompare */ - } - } - } - - /* download finished */ - release_firmware(fw); - /* Everything OK, Go. */ - WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH); - - /* - * Poll the CardUp register to wait for microcode to initialize - * Give up after 10,000 attemps (500ms). - */ - for (i = 0; i < 10000; i++) { - udelay(50); - READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead); - if (ValueRead == 0xCAFE) { - break; - } - } - if (i == 10000) { - DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__); - - return FALSE; /* Timeout */ - } - /* - * Now write the LoadSync register. This is used to - * synchronize with the card so it can scribble on the memory - * that contained 0xCAFE from the "CardUp" step above - */ - if (UcodeSel == SXG_UCODE_SYSTEM) { - WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH); - } - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd", - adapter, 0, 0, 0); - return (TRUE); -} - -/* - * sxg_allocate_resources - Allocate memory and locks - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - int - */ -static int sxg_allocate_resources(struct adapter_t *adapter) -{ - int status = STATUS_SUCCESS; - u32 RssIds, IsrCount; - /* struct sxg_xmt_ring *XmtRing; */ - /* struct sxg_rcv_ring *RcvRing; */ - - DBG_ERROR("%s ENTER\n", __func__); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes", - adapter, 0, 0, 0); - - /* Windows tells us how many CPUs it plans to use for */ - /* RSS */ - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - - DBG_ERROR("%s Setup the spinlocks\n", __func__); - - /* Allocate spinlocks and initialize listheads first. */ - spin_lock_init(&adapter->RcvQLock); - spin_lock_init(&adapter->SglQLock); - spin_lock_init(&adapter->XmtZeroLock); - spin_lock_init(&adapter->Bit64RegLock); - spin_lock_init(&adapter->AdapterLock); - atomic_set(&adapter->pending_allocations, 0); - - DBG_ERROR("%s Setup the lists\n", __func__); - - InitializeListHead(&adapter->FreeRcvBuffers); - InitializeListHead(&adapter->FreeRcvBlocks); - InitializeListHead(&adapter->AllRcvBlocks); - InitializeListHead(&adapter->FreeSglBuffers); - InitializeListHead(&adapter->AllSglBuffers); - - /* - * Mark these basic allocations done. This flags essentially - * tells the SxgFreeResources routine that it can grab spinlocks - * and reference listheads. - */ - adapter->BasicAllocations = TRUE; - /* - * Main allocation loop. Start with the maximum supported by - * the microcode and back off if memory allocation - * fails. If we hit a minimum, fail. - */ - - for (;;) { - DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_xmt_ring) * 1)); - - /* - * Start with big items first - receive and transmit rings. - * At the moment I'm going to keep the ring size fixed and - * adjust the TCBs if we fail. Later we might - * consider reducing the ring size as well.. - */ - adapter->XmtRings = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * - 1, - &adapter->PXmtRings); - DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings); - - if (!adapter->XmtRings) { - goto per_tcb_allocation_failed; - } - memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1); - - DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_rcv_ring) * 1)); - adapter->RcvRings = - pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - &adapter->PRcvRings); - DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings); - if (!adapter->RcvRings) { - goto per_tcb_allocation_failed; - } - memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1); - adapter->ucode_stats = kzalloc(sizeof(struct sxg_ucode_stats), GFP_ATOMIC); - adapter->pucode_stats = pci_map_single(adapter->pcidev, - adapter->ucode_stats, - sizeof(struct sxg_ucode_stats), - PCI_DMA_FROMDEVICE); -// memset(adapter->ucode_stats, 0, sizeof(struct sxg_ucode_stats)); - break; - - per_tcb_allocation_failed: - /* an allocation failed. Free any successful allocations. */ - if (adapter->XmtRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * 1, - adapter->XmtRings, - adapter->PXmtRings); - adapter->XmtRings = NULL; - } - if (adapter->RcvRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - adapter->RcvRings, - adapter->PRcvRings); - adapter->RcvRings = NULL; - } - /* Loop around and try again.... */ - if (adapter->ucode_stats) { - pci_unmap_single(adapter->pcidev, - sizeof(struct sxg_ucode_stats), - adapter->pucode_stats, PCI_DMA_FROMDEVICE); - adapter->ucode_stats = NULL; - } - - } - - DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__); - /* Initialize rcv zero and xmt zero rings */ - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE); - SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE); - - /* Sanity check receive data structure format */ - /* ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) || - (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); */ - ASSERT(sizeof(struct sxg_rcv_descriptor_block) == - SXG_RCV_DESCRIPTOR_BLOCK_SIZE); - - DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__, - (unsigned int)(sizeof(struct sxg_event_ring) * RssIds)); - - /* Allocate event queues. */ - adapter->EventRings = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_event_ring) * - RssIds, - &adapter->PEventRings); - - if (!adapter->EventRings) { - /* Caller will call SxgFreeAdapter to clean up above - * allocations */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds); - - DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount); - /* Allocate ISR */ - adapter->Isr = pci_alloc_consistent(adapter->pcidev, - IsrCount, &adapter->PIsr); - if (!adapter->Isr) { - /* Caller will call SxgFreeAdapter to clean up above - * allocations */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->Isr, 0, sizeof(u32) * IsrCount); - - DBG_ERROR("%s Allocate shared XMT ring zero index location size[%x]\n", - __func__, (unsigned int)sizeof(u32)); - - /* Allocate shared XMT ring zero index location */ - adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev, - sizeof(u32), - &adapter-> - PXmtRingZeroIndex); - if (!adapter->XmtRingZeroIndex) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF10", - adapter, SXG_MAX_ENTRIES, 0, 0); - status = STATUS_RESOURCES; - goto per_tcb_allocation_failed; - } - memset(adapter->XmtRingZeroIndex, 0, sizeof(u32)); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS", - adapter, SXG_MAX_ENTRIES, 0, 0); - - return status; -} - -/* - * sxg_config_pci - - * - * Set up PCI Configuration space - * - * Arguments - - * pcidev - A pointer to our adapter structure - */ -static void sxg_config_pci(struct pci_dev *pcidev) -{ - u16 pci_command; - u16 new_command; - - pci_read_config_word(pcidev, PCI_COMMAND, &pci_command); - DBG_ERROR("sxg: %s PCI command[%4.4x]\n", __func__, pci_command); - /* Set the command register */ - new_command = pci_command | ( - /* Memory Space Enable */ - PCI_COMMAND_MEMORY | - /* Bus master enable */ - PCI_COMMAND_MASTER | - /* Memory write and invalidate */ - PCI_COMMAND_INVALIDATE | - /* Parity error response */ - PCI_COMMAND_PARITY | - /* System ERR */ - PCI_COMMAND_SERR | - /* Fast back-to-back */ - PCI_COMMAND_FAST_BACK); - if (pci_command != new_command) { - DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n", - __func__, pci_command, new_command); - pci_write_config_word(pcidev, PCI_COMMAND, new_command); - } -} - -/* - * sxg_read_config - * @adapter : Pointer to the adapter structure for the card - * This function will read the configuration data from EEPROM/FLASH - */ -static inline int sxg_read_config(struct adapter_t *adapter) -{ - /* struct sxg_config data; */ - struct sxg_config *config; - struct sw_cfg_data *data; - dma_addr_t p_addr; - unsigned long status; - unsigned long i; - config = pci_alloc_consistent(adapter->pcidev, - sizeof(struct sxg_config), &p_addr); - - if(!config) { - /* - * We cant get even this much memory. Raise a hell - * Get out of here - */ - printk(KERN_ERR"%s : Could not allocate memory for reading \ - EEPROM\n", __func__); - return -ENOMEM; - } - - data = &config->SwCfg; - - /* Initialize (reflective memory) status register */ - WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE); - - /* Send request to fetch configuration data */ - WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0); - for(i=0; i<1000; i++) { - READ_REG(adapter->UcodeRegs[0].ConfigStat, status); - if (status != SXG_CFG_TIMEOUT) - break; - mdelay(1); /* Do we really need this */ - } - - switch(status) { - /* Config read from EEPROM succeeded */ - case SXG_CFG_LOAD_EEPROM: - /* Config read from Flash succeeded */ - case SXG_CFG_LOAD_FLASH: - /* - * Copy the MAC address to adapter structure - * TODO: We are not doing the remaining part : FRU, etc - */ - memcpy(adapter->macaddr, data->MacAddr[0].MacAddr, - sizeof(struct sxg_config_mac)); - break; - case SXG_CFG_TIMEOUT: - case SXG_CFG_LOAD_INVALID: - case SXG_CFG_LOAD_ERROR: - default: /* Fix default handler later */ - printk(KERN_WARNING"%s : We could not read the config \ - word. Status = %ld\n", __func__, status); - break; - } - pci_free_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), data, - p_addr); - if (adapter->netdev) { - memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6); - memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6); - } - sxg_dbg_macaddrs(adapter); - - return status; -} - -static const struct net_device_ops sxg_netdev_ops = { - .ndo_open = sxg_entry_open, - .ndo_stop = sxg_entry_halt, - .ndo_start_xmit = sxg_send_packets, - .ndo_do_ioctl = sxg_ioctl, - .ndo_change_mtu = sxg_change_mtu, - .ndo_get_stats = sxg_get_stats, - .ndo_set_multicast_list = sxg_mcast_set_list, - .ndo_validate_addr = eth_validate_addr, -#if XXXTODO - .ndo_set_mac_address = sxg_mac_set_address, -#else - .ndo_set_mac_address = eth_mac_addr, -#endif -}; - -static int sxg_entry_probe(struct pci_dev *pcidev, - const struct pci_device_id *pci_tbl_entry) -{ - static int did_version = 0; - int err; - struct net_device *netdev; - struct adapter_t *adapter; - void __iomem *memmapped_ioaddr; - u32 status = 0; - ulong mmio_start = 0; - ulong mmio_len = 0; - unsigned char revision_id; - - DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n", - __func__, jiffies, smp_processor_id()); - - /* Initialize trace buffer */ -#ifdef ATKDBG - SxgTraceBuffer = &LSxgTraceBuffer; - SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY); -#endif - - sxg_global.dynamic_intagg = dynamic_intagg; - - err = pci_enable_device(pcidev); - - DBG_ERROR("Call pci_enable_device(%p) status[%x]\n", pcidev, err); - if (err) { - return err; - } - - if (sxg_debug > 0 && did_version++ == 0) { - printk(KERN_INFO "%s\n", sxg_banner); - printk(KERN_INFO "%s\n", SXG_DRV_VERSION); - } - - pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id); - - if (!(err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)))) { - DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(64)) successful\n"); - } else { - if ((err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)))) { - DBG_ERROR - ("No usable DMA configuration, aborting err[%x]\n", - err); - return err; - } - DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(32)) successful\n"); - } - - DBG_ERROR("Call pci_request_regions\n"); - - err = pci_request_regions(pcidev, sxg_driver_name); - if (err) { - DBG_ERROR("pci_request_regions FAILED err[%x]\n", err); - return err; - } - - DBG_ERROR("call pci_set_master\n"); - pci_set_master(pcidev); - - DBG_ERROR("call alloc_etherdev\n"); - netdev = alloc_etherdev(sizeof(struct adapter_t)); - if (!netdev) { - err = -ENOMEM; - goto err_out_exit_sxg_probe; - } - DBG_ERROR("alloc_etherdev for slic netdev[%p]\n", netdev); - - SET_NETDEV_DEV(netdev, &pcidev->dev); - - pci_set_drvdata(pcidev, netdev); - adapter = netdev_priv(netdev); - if (revision_id == 1) { - adapter->asictype = SAHARA_REV_A; - } else if (revision_id == 2) { - adapter->asictype = SAHARA_REV_B; - } else { - ASSERT(0); - DBG_ERROR("%s Unexpected revision ID %x\n", __func__, revision_id); - goto err_out_exit_sxg_probe; - } - adapter->netdev = netdev; - adapter->pcidev = pcidev; - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n", - mmio_start, mmio_len); - - memmapped_ioaddr = ioremap(mmio_start, mmio_len); - DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__, - memmapped_ioaddr); - if (!memmapped_ioaddr) { - DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n", - __func__, mmio_len, mmio_start); - goto err_out_free_mmio_region_0; - } - - DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] \ - len[%lx], IRQ %d.\n", __func__, memmapped_ioaddr, mmio_start, - mmio_len, pcidev->irq); - - adapter->HwRegs = (void *)memmapped_ioaddr; - adapter->base_addr = memmapped_ioaddr; - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - - DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n", - mmio_start, mmio_len); - - memmapped_ioaddr = ioremap(mmio_start, mmio_len); - DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__, - memmapped_ioaddr); - if (!memmapped_ioaddr) { - DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n", - __func__, mmio_len, mmio_start); - goto err_out_free_mmio_region_2; - } - - DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, " - "start[%lx] len[%lx], IRQ %d.\n", __func__, - memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq); - - adapter->UcodeRegs = (void *)memmapped_ioaddr; - - adapter->State = SXG_STATE_INITIALIZING; - /* - * Maintain a list of all adapters anchored by - * the global SxgDriver structure. - */ - adapter->Next = SxgDriver.Adapters; - SxgDriver.Adapters = adapter; - adapter->AdapterID = ++SxgDriver.AdapterID; - - /* Initialize CRC table used to determine multicast hash */ - sxg_mcast_init_crc32(); - - adapter->JumboEnabled = FALSE; - adapter->RssEnabled = FALSE; - if (adapter->JumboEnabled) { - adapter->FrameSize = JUMBOMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE; - } else { - adapter->FrameSize = ETHERMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE; - } - - /* - * status = SXG_READ_EEPROM(adapter); - * if (!status) { - * goto sxg_init_bad; - * } - */ - - DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__); - sxg_config_pci(pcidev); - DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __func__); - - DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __func__); - sxg_init_driver(); - DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __func__); - - adapter->vendid = pci_tbl_entry->vendor; - adapter->devid = pci_tbl_entry->device; - adapter->subsysid = pci_tbl_entry->subdevice; - adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F); - adapter->functionnumber = (pcidev->devfn & 0x7); - adapter->memorylength = pci_resource_len(pcidev, 0); - adapter->irq = pcidev->irq; - adapter->next_netdevice = head_netdevice; - head_netdevice = netdev; - adapter->port = 0; /*adapter->functionnumber; */ - - /* Allocate memory and other resources */ - DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__); - status = sxg_allocate_resources(adapter); - DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n", - __func__, status); - if (status != STATUS_SUCCESS) { - goto err_out_unmap; - } - - DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__); - if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) { - DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n", - __func__); - sxg_read_config(adapter); - status = sxg_adapter_set_hwaddr(adapter); - } else { - adapter->state = ADAPT_FAIL; - adapter->linkstate = LINK_DOWN; - DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", status); - } - - netdev->base_addr = (unsigned long)adapter->base_addr; - netdev->irq = adapter->irq; - netdev->netdev_ops = &sxg_netdev_ops; - SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); - netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - err = sxg_set_interrupt_capability(adapter); - if (err != STATUS_SUCCESS) - DBG_ERROR("Cannot enable MSI-X capability\n"); - - strcpy(netdev->name, "eth%d"); - /* strcpy(netdev->name, pci_name(pcidev)); */ - if ((err = register_netdev(netdev))) { - DBG_ERROR("Cannot register net device, aborting. %s\n", - netdev->name); - goto err_out_unmap; - } - - netif_napi_add(netdev, &adapter->napi, - sxg_poll, SXG_NETDEV_WEIGHT); - netdev->watchdog_timeo = 2 * HZ; - init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &sxg_watchdog; - adapter->watchdog_timer.data = (unsigned long) adapter; - INIT_WORK(&adapter->update_link_status, sxg_update_link_status); - - DBG_ERROR - ("sxg: %s addr 0x%lx, irq %d, MAC addr \ - %02X:%02X:%02X:%02X:%02X:%02X\n", - netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0], - netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], - netdev->dev_addr[4], netdev->dev_addr[5]); - - /* sxg_init_bad: */ - ASSERT(status == FALSE); - /* sxg_free_adapter(adapter); */ - - DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__, - status, jiffies, smp_processor_id()); - return status; - - err_out_unmap: - sxg_free_resources(adapter); - - err_out_free_mmio_region_2: - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - release_mem_region(mmio_start, mmio_len); - - err_out_free_mmio_region_0: - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - release_mem_region(mmio_start, mmio_len); - - err_out_exit_sxg_probe: - - DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies, - smp_processor_id()); - - pci_disable_device(pcidev); - DBG_ERROR("sxg: %s deallocate device\n", __func__); - kfree(netdev); - printk("Exit %s, Sxg driver loading failed..\n", __func__); - - return -ENODEV; -} - -/* - * LINE BASE Interrupt routines.. - * - * sxg_disable_interrupt - * - * DisableInterrupt Handler - * - * Arguments: - * - * adapter: Our adapter structure - * - * Return Value: - * None. - */ -static void sxg_disable_interrupt(struct adapter_t *adapter) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr", - adapter, adapter->InterruptsEnabled, 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - /* Turn off interrupts by writing to the icr register. */ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE); - - adapter->InterruptsEnabled = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDisIntr", - adapter, adapter->InterruptsEnabled, 0, 0); -} - -/* - * sxg_enable_interrupt - * - * EnableInterrupt Handler - * - * Arguments: - * - * adapter: Our adapter structure - * - * Return Value: - * None. - */ -static void sxg_enable_interrupt(struct adapter_t *adapter) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr", - adapter, adapter->InterruptsEnabled, 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - /* Turn on interrupts by writing to the icr register. */ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE); - - adapter->InterruptsEnabled = 1; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XEnIntr", - adapter, 0, 0, 0); -} - -/* - * sxg_isr - Process an line-based interrupt - * - * Arguments: - * Context - Our adapter structure - * QueueDefault - Output parameter to queue to default CPU - * TargetCpus - Output bitmap to schedule DPC's - * - * Return Value: TRUE if our interrupt - */ -static irqreturn_t sxg_isr(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - if(adapter->state != ADAPT_UP) - return IRQ_NONE; - adapter->Stats.NumInts++; - if (adapter->Isr[0] == 0) { - /* - * The SLIC driver used to experience a number of spurious - * interrupts due to the delay associated with the masking of - * the interrupt (we'd bounce back in here). If we see that - * again with Sahara,add a READ_REG of the Icr register after - * the WRITE_REG below. - */ - adapter->Stats.FalseInts++; - return IRQ_NONE; - } - /* - * Move the Isr contents and clear the value in - * shared memory, and mask interrupts - */ - /* ASSERT(adapter->IsrDpcsPending == 0); */ -#if XXXTODO /* RSS Stuff */ - /* - * If RSS is enabled and the ISR specifies SXG_ISR_EVENT, then - * schedule DPC's based on event queues. - */ - if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) { - for (i = 0; - i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount; - i++) { - struct sxg_event_ring *EventRing = - &adapter->EventRings[i]; - struct sxg_event *Event = - &EventRing->Ring[adapter->NextEvent[i]]; - unsigned char Cpu = - adapter->RssSystemInfo->RssIdToCpu[i]; - if (Event->Status & EVENT_STATUS_VALID) { - adapter->IsrDpcsPending++; - CpuMask |= (1 << Cpu); - } - } - } - /* - * Now, either schedule the CPUs specified by the CpuMask, - * or queue default - */ - if (CpuMask) { - *QueueDefault = FALSE; - } else { - adapter->IsrDpcsPending = 1; - *QueueDefault = TRUE; - } - *TargetCpus = CpuMask; -#endif - sxg_interrupt(adapter); - - return IRQ_HANDLED; -} - -static void sxg_interrupt(struct adapter_t *adapter) -{ - WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE); - - if (napi_schedule_prep(&adapter->napi)) { - __napi_schedule(&adapter->napi); - } -} - -static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done, - int budget) -{ - /* unsigned char RssId = 0; */ - u32 NewIsr; - int sxg_napi_continue = 1; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr", - adapter, adapter->IsrCopy[0], 0, 0); - /* For now, RSS is disabled with line based interrupts */ - ASSERT(adapter->RssEnabled == FALSE); - - adapter->IsrCopy[0] = adapter->Isr[0]; - adapter->Isr[0] = 0; - - /* Always process the event queue. */ - while (sxg_napi_continue) - { - sxg_process_event_queue(adapter, - (adapter->RssEnabled ? /*RssId */ 0 : 0), - &sxg_napi_continue, work_done, budget); - } - -#if XXXTODO /* RSS stuff */ - if (--adapter->IsrDpcsPending) { - /* We're done. */ - ASSERT(adapter->RssEnabled); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend", - adapter, 0, 0, 0); - return; - } -#endif - /* Last (or only) DPC processes the ISR and clears the interrupt. */ - NewIsr = sxg_process_isr(adapter, 0); - /* Reenable interrupts */ - adapter->IsrCopy[0] = 0; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr", - adapter, NewIsr, 0, 0); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt", - adapter, 0, 0, 0); -} -static int sxg_poll(struct napi_struct *napi, int budget) -{ - struct adapter_t *adapter = container_of(napi, struct adapter_t, napi); - int work_done = 0; - - sxg_handle_interrupt(adapter, &work_done, budget); - - if (work_done < budget) { - napi_complete(napi); - WRITE_REG(adapter->UcodeRegs[0].Isr, 0, TRUE); - } - return work_done; -} - -/* - * sxg_process_isr - Process an interrupt. Called from the line-based and - * message based interrupt DPC routines - * - * Arguments: - * adapter - Our adapter structure - * Queue - The ISR that needs processing - * - * Return Value: - * None - */ -static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId) -{ - u32 Isr = adapter->IsrCopy[MessageId]; - u32 NewIsr = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr", - adapter, Isr, 0, 0); - - /* Error */ - if (Isr & SXG_ISR_ERR) { - if (Isr & SXG_ISR_PDQF) { - adapter->Stats.PdqFull++; - DBG_ERROR("%s: SXG_ISR_ERR PDQF!!\n", __func__); - } - /* No host buffer */ - if (Isr & SXG_ISR_RMISS) { - /* - * There is a bunch of code in the SLIC driver which - * attempts to process more receive events per DPC - * if we start to fall behind. We'll probablyd - * need to do something similar here, but hold - * off for now. I don't want to make the code more - * complicated than strictly needed. - */ - adapter->stats.rx_missed_errors++; - if (adapter->stats.rx_missed_errors< 5) { - DBG_ERROR("%s: SXG_ISR_ERR RMISS!!\n", - __func__); - } - } - /* Card crash */ - if (Isr & SXG_ISR_DEAD) { - /* - * Set aside the crash info and set the adapter state - * to RESET - */ - adapter->CrashCpu = (unsigned char) - ((Isr & SXG_ISR_CPU) >> SXG_ISR_CPU_SHIFT); - adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH); - adapter->Dead = TRUE; - DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__, - adapter->CrashLocation, adapter->CrashCpu); - } - /* Event ring full */ - if (Isr & SXG_ISR_ERFULL) { - /* - * Same issue as RMISS, really. This means the - * host is falling behind the card. Need to increase - * event ring size, process more events per interrupt, - * and/or reduce/remove interrupt aggregation. - */ - adapter->Stats.EventRingFull++; - DBG_ERROR("%s: SXG_ISR_ERR EVENT RING FULL!!\n", - __func__); - } - /* Transmit drop - no DRAM buffers or XMT error */ - if (Isr & SXG_ISR_XDROP) { - DBG_ERROR("%s: SXG_ISR_ERR XDROP!!\n", __func__); - } - } - /* Slowpath send completions */ - if (Isr & SXG_ISR_SPSEND) { - sxg_complete_slow_send(adapter); - } - /* Dump */ - if (Isr & SXG_ISR_UPC) { - /* Maybe change when debug is added.. */ -// ASSERT(adapter->DumpCmdRunning); - adapter->DumpCmdRunning = FALSE; - } - /* Link event */ - if (Isr & SXG_ISR_LINK) { - if (adapter->state != ADAPT_DOWN) { - adapter->link_status_changed = 1; - schedule_work(&adapter->update_link_status); - } - } - /* Debug - breakpoint hit */ - if (Isr & SXG_ISR_BREAK) { - /* - * At the moment AGDB isn't written to support interactive - * debug sessions. When it is, this interrupt will be used to - * signal AGDB that it has hit a breakpoint. For now, ASSERT. - */ - ASSERT(0); - } - /* Heartbeat response */ - if (Isr & SXG_ISR_PING) { - adapter->PingOutstanding = FALSE; - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XProcIsr", - adapter, Isr, NewIsr, 0); - - return (NewIsr); -} - -/* - * sxg_rcv_checksum - Set the checksum for received packet - * - * Arguements: - * @adapter - Adapter structure on which packet is received - * @skb - Packet which is receieved - * @Event - Event read from hardware - */ - -void sxg_rcv_checksum(struct adapter_t *adapter, struct sk_buff *skb, - struct sxg_event *Event) -{ - skb->ip_summed = CHECKSUM_NONE; - if (likely(adapter->flags & SXG_RCV_IP_CSUM_ENABLED)) { - if (likely(adapter->flags & SXG_RCV_TCP_CSUM_ENABLED) - && (Event->Status & EVENT_STATUS_TCPIP)) { - if(!(Event->Status & EVENT_STATUS_TCPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - if(!(Event->Status & EVENT_STATUS_IPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if(Event->Status & EVENT_STATUS_IPONLY) { - if(!(Event->Status & EVENT_STATUS_IPBAD)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - } - } -} - -/* - * sxg_process_event_queue - Process our event queue - * - * Arguments: - * - adapter - Adapter structure - * - RssId - The event queue requiring processing - * - * Return Value: - * None. - */ -static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId, - int *sxg_napi_continue, int *work_done, int budget) -{ - struct sxg_event_ring *EventRing = &adapter->EventRings[RssId]; - struct sxg_event *Event = &EventRing->Ring[adapter->NextEvent[RssId]]; - u32 EventsProcessed = 0, Batches = 0; - struct sk_buff *skb; -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - struct sk_buff *prev_skb = NULL; - struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE]; - u32 Index; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; -#endif - u32 ReturnStatus = 0; - int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS; - - ASSERT((adapter->State == SXG_STATE_RUNNING) || - (adapter->State == SXG_STATE_PAUSING) || - (adapter->State == SXG_STATE_PAUSED) || - (adapter->State == SXG_STATE_HALTING)); - /* - * We may still have unprocessed events on the queue if - * the card crashed. Don't process them. - */ - if (adapter->Dead) { - return (0); - } - /* - * In theory there should only be a single processor that - * accesses this queue, and only at interrupt-DPC time. So/ - * we shouldn't need a lock for any of this. - */ - while (Event->Status & EVENT_STATUS_VALID) { - (*sxg_napi_continue) = 1; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event", - Event, Event->Code, Event->Status, - adapter->NextEvent); - switch (Event->Code) { - case EVENT_CODE_BUFFERS: - /* struct sxg_ring_info Head & Tail == unsigned char */ - ASSERT(!(Event->CommandIndex & 0xFF00)); - sxg_complete_descriptor_blocks(adapter, - Event->CommandIndex); - break; - case EVENT_CODE_SLOWRCV: - (*work_done)++; - --adapter->RcvBuffersOnCard; - if ((skb = sxg_slow_receive(adapter, Event))) { - u32 rx_bytes; -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - /* Add it to our indication list */ - SXG_ADD_RCV_PACKET(adapter, skb, prev_skb, - IndicationList, num_skbs); - /* - * Linux, we just pass up each skb to the - * protocol above at this point, there is no - * capability of an indication list. - */ -#else - /* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */ - /* (rcvbuf->length & IRHDDR_FLEN_MSK); */ - rx_bytes = Event->Length; - adapter->stats.rx_packets++; - adapter->stats.rx_bytes += rx_bytes; - sxg_rcv_checksum(adapter, skb, Event); - skb->dev = adapter->netdev; - netif_receive_skb(skb); -#endif - } - break; - default: - DBG_ERROR("%s: ERROR Invalid EventCode %d\n", - __func__, Event->Code); - /* ASSERT(0); */ - } - /* - * See if we need to restock card receive buffers. - * There are two things to note here: - * First - This test is not SMP safe. The - * adapter->BuffersOnCard field is protected via atomic - * interlocked calls, but we do not protect it with respect - * to these tests. The only way to do that is with a lock, - * and I don't want to grab a lock every time we adjust the - * BuffersOnCard count. Instead, we allow the buffer - * replenishment to be off once in a while. The worst that - * can happen is the card is given on more-or-less descriptor - * block than the arbitrary value we've chosen. No big deal - * In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard - * is adjusted. - * Second - We expect this test to rarely - * evaluate to true. We attempt to refill descriptor blocks - * as they are returned to us (sxg_complete_descriptor_blocks) - * so The only time this should evaluate to true is when - * sxg_complete_descriptor_blocks failed to allocate - * receive buffers. - */ - if (adapter->JumboEnabled) - sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS; - - if (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) { - sxg_stock_rcv_buffers(adapter); - } - /* - * It's more efficient to just set this to zero. - * But clearing the top bit saves potential debug info... - */ - Event->Status &= ~EVENT_STATUS_VALID; - /* Advance to the next event */ - SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE); - Event = &EventRing->Ring[adapter->NextEvent[RssId]]; - EventsProcessed++; - if (EventsProcessed == EVENT_RING_BATCH) { - /* Release a batch of events back to the card */ - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EVENT_RING_BATCH, FALSE); - EventsProcessed = 0; - /* - * If we've processed our batch limit, break out of the - * loop and return SXG_ISR_EVENT to arrange for us to - * be called again - */ - if (Batches++ == EVENT_BATCH_LIMIT) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, - TRACE_NOISY, "EvtLimit", Batches, - adapter->NextEvent, 0, 0); - ReturnStatus = SXG_ISR_EVENT; - break; - } - } - if (*work_done >= budget) { - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EventsProcessed, FALSE); - EventsProcessed = 0; - (*sxg_napi_continue) = 0; - break; - } - } - if (!(Event->Status & EVENT_STATUS_VALID)) - (*sxg_napi_continue) = 0; - -#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS - /* Indicate any received dumb-nic frames */ - SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs); -#endif - /* Release events back to the card. */ - if (EventsProcessed) { - WRITE_REG(adapter->UcodeRegs[RssId].EventRelease, - EventsProcessed, FALSE); - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XPrcEvnt", - Batches, EventsProcessed, adapter->NextEvent, num_skbs); - - return (ReturnStatus); -} - -/* - * sxg_complete_slow_send - Complete slowpath or dumb-nic sends - * - * Arguments - - * adapter - A pointer to our adapter structure - * Return - * None - */ -static void sxg_complete_slow_send(struct adapter_t *adapter) -{ - struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0]; - struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo; - u32 *ContextType; - struct sxg_cmd *XmtCmd; - unsigned long flags = 0; - unsigned long sgl_flags = 0; - unsigned int processed_count = 0; - - /* - * NOTE - This lock is dropped and regrabbed in this loop. - * This means two different processors can both be running/ - * through this loop. Be *very* careful. - */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds", - adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0); - - while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) - && processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT) { - /* - * Locate the current Cmd (ring descriptor entry), and - * associated SGL, and advance the tail - */ - SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType); - ASSERT(ContextType); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd", - XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0); - /* Clear the SGL field. */ - XmtCmd->Sgl = 0; - - switch (*ContextType) { - case SXG_SGL_DUMB: - { - struct sk_buff *skb; - struct sxg_scatter_gather *SxgSgl = - (struct sxg_scatter_gather *)ContextType; - dma64_addr_t FirstSgeAddress; - u32 FirstSgeLength; - - /* Dumb-nic send. Command context is the dumb-nic SGL */ - skb = (struct sk_buff *)ContextType; - skb = SxgSgl->DumbPacket; - FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress; - FirstSgeLength = XmtCmd->Buffer.FirstSgeLength; - /* Complete the send */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, - TRACE_IMPORTANT, "DmSndCmp", skb, 0, - 0, 0); - ASSERT(adapter->Stats.XmtQLen); - /* - * Now drop the lock and complete the send - * back to Microsoft. We need to drop the lock - * because Microsoft can come back with a - * chimney send, which results in a double trip - * in SxgTcpOuput - */ - spin_unlock_irqrestore( - &adapter->XmtZeroLock, flags); - - SxgSgl->DumbPacket = NULL; - SXG_COMPLETE_DUMB_SEND(adapter, skb, - FirstSgeAddress, - FirstSgeLength); - SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL); - /* and reacquire.. */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - } - break; - default: - ASSERT(0); - } - } - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd", - adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0); -} - -/* - * sxg_slow_receive - * - * Arguments - - * adapter - A pointer to our adapter structure - * Event - Receive event - * - * Return - skb - */ -static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, - struct sxg_event *Event) -{ - u32 BufferSize = adapter->ReceiveBufferSize; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sk_buff *Packet; - static int read_counter = 0; - - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle; - if(read_counter++ & 0x100) - { - sxg_collect_statistics(adapter); - read_counter = 0; - } - ASSERT(RcvDataBufferHdr); - ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event, - RcvDataBufferHdr, RcvDataBufferHdr->State, - /*RcvDataBufferHdr->VirtualAddress*/ 0); - /* Drop rcv frames in non-running state */ - switch (adapter->State) { - case SXG_STATE_RUNNING: - break; - case SXG_STATE_PAUSING: - case SXG_STATE_PAUSED: - case SXG_STATE_HALTING: - goto drop; - default: - ASSERT(0); - goto drop; - } - - /* - * memcpy(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - * RcvDataBufferHdr->VirtualAddress, Event->Length); - */ - - /* Change buffer state to UPSTREAM */ - RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; - if (Event->Status & EVENT_STATUS_RCVERR) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError", - Event, Event->Status, Event->HostHandle, 0); - sxg_process_rcv_error(adapter, *(u32 *) - SXG_RECEIVE_DATA_LOCATION - (RcvDataBufferHdr)); - goto drop; - } -#if XXXTODO /* VLAN stuff */ - /* If there's a VLAN tag, extract it and validate it */ - if (((struct ether_header *) - (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->EtherType - == ETHERTYPE_VLAN) { - if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) != - STATUS_SUCCESS) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, - "BadVlan", Event, - SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - Event->Length, 0); - goto drop; - } - } -#endif - /* Dumb-nic frame. See if it passes our mac filter and update stats */ - - if (!sxg_mac_filter(adapter, - (struct ether_header *)(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)), - Event->Length)) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr", - Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr), - Event->Length, 0); - goto drop; - } - - Packet = RcvDataBufferHdr->SxgDumbRcvPacket; - SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event); - Packet->protocol = eth_type_trans(Packet, adapter->netdev); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv", - RcvDataBufferHdr, Packet, Event->Length, 0); - /* Lastly adjust the receive packet length. */ - RcvDataBufferHdr->SxgDumbRcvPacket = NULL; - RcvDataBufferHdr->PhysicalAddress = (dma_addr_t)NULL; - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize); - if (RcvDataBufferHdr->skb) - { - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - // adapter->RcvBuffersOnCard ++; - spin_unlock(&adapter->RcvQLock); - } - return (Packet); - - drop: - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv", - RcvDataBufferHdr, Event->Length, 0, 0); - adapter->stats.rx_dropped++; -// adapter->Stats.RcvDiscards++; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - spin_unlock(&adapter->RcvQLock); - return (NULL); -} - -/* - * sxg_process_rcv_error - process receive error and update - * stats - * - * Arguments: - * adapter - Adapter structure - * ErrorStatus - 4-byte receive error status - * - * Return Value : None - */ -static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus) -{ - u32 Error; - - adapter->stats.rx_errors++; - - if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK; - switch (Error) { - case SXG_RCV_STATUS_TRANSPORT_CSUM: - adapter->Stats.TransportCsum++; - break; - case SXG_RCV_STATUS_TRANSPORT_UFLOW: - adapter->Stats.TransportUflow++; - break; - case SXG_RCV_STATUS_TRANSPORT_HDRLEN: - adapter->Stats.TransportHdrLen++; - break; - } - } - if (ErrorStatus & SXG_RCV_STATUS_NETWORK_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_NETWORK_MASK; - switch (Error) { - case SXG_RCV_STATUS_NETWORK_CSUM: - adapter->Stats.NetworkCsum++; - break; - case SXG_RCV_STATUS_NETWORK_UFLOW: - adapter->Stats.NetworkUflow++; - break; - case SXG_RCV_STATUS_NETWORK_HDRLEN: - adapter->Stats.NetworkHdrLen++; - break; - } - } - if (ErrorStatus & SXG_RCV_STATUS_PARITY) { - adapter->Stats.Parity++; - } - if (ErrorStatus & SXG_RCV_STATUS_LINK_ERROR) { - Error = ErrorStatus & SXG_RCV_STATUS_LINK_MASK; - switch (Error) { - case SXG_RCV_STATUS_LINK_PARITY: - adapter->Stats.LinkParity++; - break; - case SXG_RCV_STATUS_LINK_EARLY: - adapter->Stats.LinkEarly++; - break; - case SXG_RCV_STATUS_LINK_BUFOFLOW: - adapter->Stats.LinkBufOflow++; - break; - case SXG_RCV_STATUS_LINK_CODE: - adapter->Stats.LinkCode++; - break; - case SXG_RCV_STATUS_LINK_DRIBBLE: - adapter->Stats.LinkDribble++; - break; - case SXG_RCV_STATUS_LINK_CRC: - adapter->Stats.LinkCrc++; - break; - case SXG_RCV_STATUS_LINK_OFLOW: - adapter->Stats.LinkOflow++; - break; - case SXG_RCV_STATUS_LINK_UFLOW: - adapter->Stats.LinkUflow++; - break; - } - } -} - -/* - * sxg_mac_filter - * - * Arguments: - * adapter - Adapter structure - * pether - Ethernet header - * length - Frame length - * - * Return Value : TRUE if the frame is to be allowed - */ -static bool sxg_mac_filter(struct adapter_t *adapter, - struct ether_header *EtherHdr, ushort length) -{ - bool EqualAddr; - struct net_device *dev = adapter->netdev; - - if (SXG_MULTICAST_PACKET(EtherHdr)) { - if (SXG_BROADCAST_PACKET(EtherHdr)) { - /* broadcast */ - if (adapter->MacFilter & MAC_BCAST) { - adapter->Stats.DumbRcvBcastPkts++; - adapter->Stats.DumbRcvBcastBytes += length; - return (TRUE); - } - } else { - /* multicast */ - if (adapter->MacFilter & MAC_ALLMCAST) { - adapter->Stats.DumbRcvMcastPkts++; - adapter->Stats.DumbRcvMcastBytes += length; - return (TRUE); - } - if (adapter->MacFilter & MAC_MCAST) { - struct dev_mc_list *mclist = dev->mc_list; - while (mclist) { - ETHER_EQ_ADDR(mclist->da_addr, - EtherHdr->ether_dhost, - EqualAddr); - if (EqualAddr) { - adapter->Stats. - DumbRcvMcastPkts++; - adapter->Stats. - DumbRcvMcastBytes += length; - return (TRUE); - } - mclist = mclist->next; - } - } - } - } else if (adapter->MacFilter & MAC_DIRECTED) { - /* - * Not broadcast or multicast. Must be directed at us or - * the card is in promiscuous mode. Either way, consider it - * ours if MAC_DIRECTED is set - */ - adapter->Stats.DumbRcvUcastPkts++; - adapter->Stats.DumbRcvUcastBytes += length; - return (TRUE); - } - if (adapter->MacFilter & MAC_PROMISC) { - /* Whatever it is, keep it. */ - return (TRUE); - } - return (FALSE); -} - -static int sxg_register_interrupt(struct adapter_t *adapter) -{ - if (!adapter->intrregistered) { - int retval; - - DBG_ERROR - ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n", - __func__, adapter, adapter->netdev->irq, NR_IRQS); - - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - - retval = request_irq(adapter->netdev->irq, - &sxg_isr, - IRQF_SHARED, - adapter->netdev->name, adapter->netdev); - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - - if (retval) { - DBG_ERROR("sxg: request_irq (%s) FAILED [%x]\n", - adapter->netdev->name, retval); - return (retval); - } - adapter->intrregistered = 1; - adapter->IntRegistered = TRUE; - /* Disable RSS with line-based interrupts */ - adapter->RssEnabled = FALSE; - DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n", - __func__, adapter, adapter->netdev->irq); - } - return (STATUS_SUCCESS); -} - -static void sxg_deregister_interrupt(struct adapter_t *adapter) -{ - DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __func__, adapter); -#if XXXTODO - slic_init_cleanup(adapter); -#endif - memset(&adapter->stats, 0, sizeof(struct net_device_stats)); - adapter->error_interrupts = 0; - adapter->rcv_interrupts = 0; - adapter->xmit_interrupts = 0; - adapter->linkevent_interrupts = 0; - adapter->upr_interrupts = 0; - adapter->num_isrs = 0; - adapter->xmit_completes = 0; - adapter->rcv_broadcasts = 0; - adapter->rcv_multicasts = 0; - adapter->rcv_unicasts = 0; - DBG_ERROR("sxg: %s EXIT\n", __func__); -} - -/* - * sxg_if_init - * - * Perform initialization of our slic interface. - * - */ -static int sxg_if_init(struct adapter_t *adapter) -{ - struct net_device *dev = adapter->netdev; - int status = 0; - - DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n", - __func__, adapter->netdev->name, - adapter->state, - adapter->linkstate, dev->flags); - - /* adapter should be down at this point */ - if (adapter->state != ADAPT_DOWN) { - DBG_ERROR("sxg_if_init adapter->state != ADAPT_DOWN\n"); - return (-EIO); - } - ASSERT(adapter->linkstate == LINK_DOWN); - - adapter->devflags_prev = dev->flags; - adapter->MacFilter = MAC_DIRECTED; - if (dev->flags) { - DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__, - adapter->netdev->name); - if (dev->flags & IFF_BROADCAST) { - adapter->MacFilter |= MAC_BCAST; - DBG_ERROR("BCAST "); - } - if (dev->flags & IFF_PROMISC) { - adapter->MacFilter |= MAC_PROMISC; - DBG_ERROR("PROMISC "); - } - if (dev->flags & IFF_ALLMULTI) { - adapter->MacFilter |= MAC_ALLMCAST; - DBG_ERROR("ALL_MCAST "); - } - if (dev->flags & IFF_MULTICAST) { - adapter->MacFilter |= MAC_MCAST; - DBG_ERROR("MCAST "); - } - DBG_ERROR("\n"); - } - status = sxg_register_intr(adapter); - if (status != STATUS_SUCCESS) { - DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n", - status); - sxg_deregister_interrupt(adapter); - return (status); - } - - adapter->state = ADAPT_UP; - - /* clear any pending events, then enable interrupts */ - DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__); - - return (STATUS_SUCCESS); -} - -void sxg_set_interrupt_aggregation(struct adapter_t *adapter) -{ - /* - * Top bit disables aggregation on xmt (SXG_AGG_XMT_DISABLE). - * Make sure Max is less than 0x8000. - */ - adapter->max_aggregation = SXG_MAX_AGG_DEFAULT; - adapter->min_aggregation = SXG_MIN_AGG_DEFAULT; - WRITE_REG(adapter->UcodeRegs[0].Aggregation, - ((adapter->max_aggregation << SXG_MAX_AGG_SHIFT) | - adapter->min_aggregation), - TRUE); -} - -static int sxg_entry_open(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - int status; - static int turn; - int sxg_initial_rcv_data_buffers = SXG_INITIAL_RCV_DATA_BUFFERS; - int i; - - if (adapter->JumboEnabled == TRUE) { - sxg_initial_rcv_data_buffers = - SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS; - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, - SXG_JUMBO_RCV_RING_SIZE); - } - - /* - * Allocate receive data buffers. We allocate a block of buffers and - * a corresponding descriptor block at once. See sxghw.h:SXG_RCV_BLOCK - */ - - for (i = 0; i < sxg_initial_rcv_data_buffers; - i += SXG_RCV_DESCRIPTORS_PER_BLOCK) - { - status = sxg_allocate_buffer_memory(adapter, - SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE), - SXG_BUFFER_TYPE_RCV); - if (status != STATUS_SUCCESS) - return status; - } - /* - * NBL resource allocation can fail in the 'AllocateComplete' routine, - * which doesn't return status. Make sure we got the number of buffers - * we requested - */ - - if (adapter->FreeRcvBufferCount < sxg_initial_rcv_data_buffers) { - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6", - adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES, - 0); - return (STATUS_RESOURCES); - } - /* - * The microcode expects it to be downloaded on every open. - */ - DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__); - if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) { - DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n", - __func__); - sxg_read_config(adapter); - } else { - adapter->state = ADAPT_FAIL; - adapter->linkstate = LINK_DOWN; - DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", - status); - } - msleep(5); - - if (turn) { - sxg_second_open(adapter->netdev); - - return STATUS_SUCCESS; - } - - turn++; - - ASSERT(adapter); - DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__, - adapter->activated); - DBG_ERROR - ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n", - __func__, adapter->netdev->name, jiffies, smp_processor_id(), - adapter->netdev, adapter, adapter->port); - - netif_stop_queue(adapter->netdev); - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - if (!adapter->activated) { - sxg_global.num_sxg_ports_active++; - adapter->activated = 1; - } - /* Initialize the adapter */ - DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __func__); - status = sxg_initialize_adapter(adapter); - DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n", - __func__, status); - - if (status == STATUS_SUCCESS) { - DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __func__); - status = sxg_if_init(adapter); - DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __func__, - status); - } - - if (status != STATUS_SUCCESS) { - if (adapter->activated) { - sxg_global.num_sxg_ports_active--; - adapter->activated = 0; - } - spin_unlock_irqrestore(&sxg_global.driver_lock, - sxg_global.flags); - return (status); - } - DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__); - sxg_set_interrupt_aggregation(adapter); - napi_enable(&adapter->napi); - - /* Enable interrupts */ - SXG_ENABLE_ALL_INTERRUPTS(adapter); - - DBG_ERROR("sxg: %s EXIT\n", __func__); - - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - mod_timer(&adapter->watchdog_timer, jiffies); - - return STATUS_SUCCESS; -} - -int sxg_second_open(struct net_device * dev) -{ - struct adapter_t *adapter = (struct adapter_t*) netdev_priv(dev); - int status = 0; - - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - netif_start_queue(adapter->netdev); - adapter->state = ADAPT_UP; - adapter->linkstate = LINK_UP; - - status = sxg_initialize_adapter(adapter); - sxg_set_interrupt_aggregation(adapter); - napi_enable(&adapter->napi); - /* Re-enable interrupts */ - SXG_ENABLE_ALL_INTERRUPTS(adapter); - - sxg_register_intr(adapter); - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - mod_timer(&adapter->watchdog_timer, jiffies); - return (STATUS_SUCCESS); - -} - -static void __devexit sxg_entry_remove(struct pci_dev *pcidev) -{ - u32 mmio_start = 0; - u32 mmio_len = 0; - - struct net_device *dev = pci_get_drvdata(pcidev); - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - flush_scheduled_work(); - - /* Deallocate Resources */ - unregister_netdev(dev); - sxg_reset_interrupt_capability(adapter); - sxg_free_resources(adapter); - - ASSERT(adapter); - - mmio_start = pci_resource_start(pcidev, 0); - mmio_len = pci_resource_len(pcidev, 0); - - DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__, - mmio_start, mmio_len); - release_mem_region(mmio_start, mmio_len); - - mmio_start = pci_resource_start(pcidev, 2); - mmio_len = pci_resource_len(pcidev, 2); - - DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __func__, - mmio_start, mmio_len); - release_mem_region(mmio_start, mmio_len); - - pci_disable_device(pcidev); - - DBG_ERROR("sxg: %s deallocate device\n", __func__); - kfree(dev); - DBG_ERROR("sxg: %s EXIT\n", __func__); -} - -static int sxg_entry_halt(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - int i; - u32 RssIds, IsrCount; - unsigned long flags; - - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - /* Disable interrupts */ - spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); - SXG_DISABLE_ALL_INTERRUPTS(adapter); - adapter->state = ADAPT_DOWN; - adapter->linkstate = LINK_DOWN; - - spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); - sxg_deregister_interrupt(adapter); - WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); - mdelay(5000); - - del_timer_sync(&adapter->watchdog_timer); - netif_stop_queue(dev); - netif_carrier_off(dev); - - napi_disable(&adapter->napi); - - WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true); - adapter->devflags_prev = 0; - DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n", - __func__, dev->name, adapter, adapter->state); - - spin_lock(&adapter->RcvQLock); - /* Free all the blocks and the buffers, moved from remove() routine */ - if (!(IsListEmpty(&adapter->AllRcvBlocks))) { - sxg_free_rcvblocks(adapter); - } - - - InitializeListHead(&adapter->FreeRcvBuffers); - InitializeListHead(&adapter->FreeRcvBlocks); - InitializeListHead(&adapter->AllRcvBlocks); - InitializeListHead(&adapter->FreeSglBuffers); - InitializeListHead(&adapter->AllSglBuffers); - - adapter->FreeRcvBufferCount = 0; - adapter->FreeRcvBlockCount = 0; - adapter->AllRcvBlockCount = 0; - adapter->RcvBuffersOnCard = 0; - adapter->PendingRcvCount = 0; - - memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1); - memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds); - memset(adapter->Isr, 0, sizeof(u32) * IsrCount); - for (i = 0; i < SXG_MAX_RING_SIZE; i++) - adapter->RcvRingZeroInfo.Context[i] = NULL; - SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE); - SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE); - - spin_unlock(&adapter->RcvQLock); - - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - adapter->AllSglBufferCount = 0; - adapter->FreeSglBufferCount = 0; - adapter->PendingXmtCount = 0; - memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1); - memset(adapter->XmtRingZeroIndex, 0, sizeof(u32)); - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - - for (i = 0; i < SXG_MAX_RSS; i++) { - adapter->NextEvent[i] = 0; - } - atomic_set(&adapter->pending_allocations, 0); - adapter->intrregistered = 0; - sxg_remove_isr(adapter); - DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name); - return (STATUS_SUCCESS); -} - -static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - ASSERT(rq); -/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);*/ - switch (cmd) { - case SIOCSLICSETINTAGG: - { - /* struct adapter_t *adapter = (struct adapter_t *) - * netdev_priv(dev); - */ - u32 data[7]; - u32 intagg; - - if (copy_from_user(data, rq->ifr_data, 28)) { - DBG_ERROR("copy_from_user FAILED getting \ - initial params\n"); - return -EFAULT; - } - intagg = data[0]; - printk(KERN_EMERG - "%s: set interrupt aggregation to %d\n", - __func__, intagg); - return 0; - } - - default: - /* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */ - return -EOPNOTSUPP; - } - return 0; -} - -#define NORMAL_ETHFRAME 0 - -/* - * sxg_send_packets - Send a skb packet - * - * Arguments: - * skb - The packet to send - * dev - Our linux net device that refs our adapter - * - * Return: - * 0 regardless of outcome XXXTODO refer to e1000 driver - */ -static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - u32 status = STATUS_SUCCESS; - - /* - * DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__, - * skb); - */ - - /* Check the adapter state */ - switch (adapter->State) { - case SXG_STATE_INITIALIZING: - case SXG_STATE_HALTED: - case SXG_STATE_SHUTDOWN: - ASSERT(0); /* unexpected */ - /* fall through */ - case SXG_STATE_RESETTING: - case SXG_STATE_SLEEP: - case SXG_STATE_BOOTDIAG: - case SXG_STATE_DIAG: - case SXG_STATE_HALTING: - status = STATUS_FAILURE; - break; - case SXG_STATE_RUNNING: - if (adapter->LinkState != SXG_LINK_UP) { - status = STATUS_FAILURE; - } - break; - default: - ASSERT(0); - status = STATUS_FAILURE; - } - if (status != STATUS_SUCCESS) { - goto xmit_fail; - } - /* send a packet */ - status = sxg_transmit_packet(adapter, skb); - if (status == STATUS_SUCCESS) { - goto xmit_done; - } - - xmit_fail: - /* reject & complete all the packets if they cant be sent */ - if (status != STATUS_SUCCESS) { -#if XXXTODO - /* sxg_send_packets_fail(adapter, skb, status); */ -#else - SXG_DROP_DUMB_SEND(adapter, skb); - adapter->stats.tx_dropped++; - return NETDEV_TX_BUSY; -#endif - } - DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__, - status); - - xmit_done: - return NETDEV_TX_OK; -} - -/* - * sxg_transmit_packet - * - * This function transmits a single packet. - * - * Arguments - - * adapter - Pointer to our adapter structure - * skb - The packet to be sent - * - * Return - STATUS of send - */ -static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb) -{ - struct sxg_x64_sgl *pSgl; - struct sxg_scatter_gather *SxgSgl; - unsigned long sgl_flags; - /* void *SglBuffer; */ - /* u32 SglBufferLength; */ - - /* - * The vast majority of work is done in the shared - * sxg_dumb_sgl routine. - */ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend", - adapter, skb, 0, 0); - - /* Allocate a SGL buffer */ - SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0); - if (!SxgSgl) { - adapter->Stats.NoSglBuf++; - adapter->stats.tx_errors++; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1", - adapter, skb, 0, 0); - return (STATUS_RESOURCES); - } - ASSERT(SxgSgl->adapter == adapter); - /*SglBuffer = SXG_SGL_BUFFER(SxgSgl); - SglBufferLength = SXG_SGL_BUF_SIZE; */ - SxgSgl->VlanTag.VlanTci = 0; - SxgSgl->VlanTag.VlanTpid = 0; - SxgSgl->Type = SXG_SGL_DUMB; - SxgSgl->DumbPacket = skb; - pSgl = NULL; - - /* Call the common sxg_dumb_sgl routine to complete the send. */ - return (sxg_dumb_sgl(pSgl, SxgSgl)); -} - -/* - * sxg_dumb_sgl - * - * Arguments: - * pSgl - - * SxgSgl - struct sxg_scatter_gather - * - * Return Value: - * Status of send operation. - */ -static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, - struct sxg_scatter_gather *SxgSgl) -{ - struct adapter_t *adapter = SxgSgl->adapter; - struct sk_buff *skb = SxgSgl->DumbPacket; - /* For now, all dumb-nic sends go on RSS queue zero */ - struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0]; - struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo; - struct sxg_cmd *XmtCmd = NULL; - /* u32 Index = 0; */ - u32 DataLength = skb->len; - /* unsigned int BufLen; */ - /* u32 SglOffset; */ - u64 phys_addr; - unsigned long flags; - unsigned long queue_id=0; - int offload_cksum = 0; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", - pSgl, SxgSgl, 0, 0); - - /* Set aside a pointer to the sgl */ - SxgSgl->pSgl = pSgl; - - /* Sanity check that our SGL format is as we expect. */ - ASSERT(sizeof(struct sxg_x64_sge) == sizeof(struct sxg_x64_sge)); - /* Shouldn't be a vlan tag on this frame */ - ASSERT(SxgSgl->VlanTag.VlanTci == 0); - ASSERT(SxgSgl->VlanTag.VlanTpid == 0); - - /* - * From here below we work with the SGL placed in our - * buffer. - */ - - SxgSgl->Sgl.NumberOfElements = 1; - /* - * Set ucode Queue ID based on bottom bits of destination TCP port. - * This Queue ID splits slowpath/dumb-nic packet processing across - * multiple threads on the card to improve performance. It is split - * using the TCP port to avoid out-of-order packets that can result - * from multithreaded processing. We use the destination port because - * we expect to be run on a server, so in nearly all cases the local - * port is likely to be constant (well-known server port) and the - * remote port is likely to be random. The exception to this is iSCSI, - * in which case we use the sport instead. Note - * that original attempt at XOR'ing source and dest port resulted in - * poor balance on NTTTCP/iometer applications since they tend to - * line up (even-even, odd-odd..). - */ - - if (skb->protocol == htons(ETH_P_IP)) { - struct iphdr *ip; - - ip = ip_hdr(skb); - if (ip->protocol == IPPROTO_TCP) - offload_cksum = 1; - if (!offload_cksum || !tcp_hdr(skb)) - queue_id = 0; - else if (offload_cksum && (DataLength >= sizeof( - struct tcphdr))){ - queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? - (ntohs (tcp_hdr(skb)->source) & - SXG_LARGE_SEND_QUEUE_MASK): - (ntohs(tcp_hdr(skb)->dest) & - SXG_LARGE_SEND_QUEUE_MASK)); - } - } else if (skb->protocol == htons(ETH_P_IPV6)) { - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - offload_cksum = 1; - if (!offload_cksum || !tcp_hdr(skb)) - queue_id = 0; - else if (offload_cksum && (DataLength>=sizeof(struct tcphdr))){ - queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? - (ntohs (tcp_hdr(skb)->source) & - SXG_LARGE_SEND_QUEUE_MASK): - (ntohs(tcp_hdr(skb)->dest) & - SXG_LARGE_SEND_QUEUE_MASK)); - } - } - - /* Grab the spinlock and acquire a command */ - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl); - if (XmtCmd == NULL) { - /* - * Call sxg_complete_slow_send to see if we can - * free up any XmtRingZero entries and then try again - */ - - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - sxg_complete_slow_send(adapter); - spin_lock_irqsave(&adapter->XmtZeroLock, flags); - SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl); - if (XmtCmd == NULL) { - adapter->Stats.XmtZeroFull++; - goto abortcmd; - } - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", - XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); - memset(XmtCmd, '\0', sizeof(*XmtCmd)); - XmtCmd->SgEntries = 1; - XmtCmd->Flags = 0; - if (skb->ip_summed == CHECKSUM_PARTIAL) { - /* - * We need to set the Checkum in IP header to 0. This is - * required by hardware. - */ - if (offload_cksum) { - ip_hdr(skb)->check = 0x0; - XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; - XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; - /* - * Dont know if length will require a change in - * case of VLAN - */ - XmtCmd->CsumFlags.MacLen = ETH_HLEN; - XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> - SXG_NW_HDR_LEN_SHIFT; - } else { - if (skb_checksum_help(skb)){ - printk(KERN_EMERG "Dropped UDP packet for" - " incorrect checksum calculation\n"); - if (XmtCmd) - SXG_ABORT_CMD(XmtRingInfo); - spin_unlock_irqrestore(&adapter->XmtZeroLock, - flags); - return STATUS_SUCCESS; - } - } - } - - /* - * Fill in the command - * Copy out the first SGE to the command and adjust for offset - */ - phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len, - PCI_DMA_TODEVICE); - - /* - * SAHARA SGL WORKAROUND - * See if the SGL straddles a 64k boundary. If so, skip to - * the start of the next 64k boundary and continue - */ - - if ((adapter->asictype == SAHARA_REV_A) && - (SXG_INVALID_SGL(phys_addr,skb->data_len))) - { - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - if (XmtCmd) - SXG_ABORT_CMD(XmtRingInfo); - /* Silently drop this packet */ - printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); - return STATUS_SUCCESS; - } - XmtCmd->Buffer.FirstSgeAddress = phys_addr; - XmtCmd->Buffer.FirstSgeLength = DataLength; - XmtCmd->Buffer.SgeOffset = 0; - XmtCmd->Buffer.TotalLength = DataLength; - - /* - * Advance transmit cmd descripter by 1. - * NOTE - See comments in SxgTcpOutput where we write - * to the XmtCmd register regarding CPU ID values and/or - * multiple commands. - * Top 16 bits specify queue_id. See comments about queue_id above - */ - /* Four queues at the moment */ - ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); - WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); - adapter->Stats.XmtQLen++; /* Stats within lock */ - /* Update stats */ - adapter->stats.tx_packets++; - adapter->stats.tx_bytes += DataLength; -#if XXXTODO /* Stats stuff */ - if (SXG_MULTICAST_PACKET(EtherHdr)) { - if (SXG_BROADCAST_PACKET(EtherHdr)) { - adapter->Stats.DumbXmtBcastPkts++; - adapter->Stats.DumbXmtBcastBytes += DataLength; - } else { - adapter->Stats.DumbXmtMcastPkts++; - adapter->Stats.DumbXmtMcastBytes += DataLength; - } - } else { - adapter->Stats.DumbXmtUcastPkts++; - adapter->Stats.DumbXmtUcastBytes += DataLength; - } -#endif - - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", - XmtCmd, pSgl, SxgSgl, 0); - return STATUS_SUCCESS; - - abortcmd: - /* - * NOTE - Only jump to this label AFTER grabbing the - * XmtZeroLock, and DO NOT DROP IT between the - * command allocation and the following abort. - */ - if (XmtCmd) { - SXG_ABORT_CMD(XmtRingInfo); - } - spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); - -/* - * failsgl: - * Jump to this label if failure occurs before the - * XmtZeroLock is grabbed - */ - adapter->stats.tx_errors++; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal", - pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail); - /* SxgSgl->DumbPacket is the skb */ - // SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket); - - return STATUS_FAILURE; -} - -/* - * Link management functions - * - * sxg_initialize_link - Initialize the link stuff - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * status - */ -static int sxg_initialize_link(struct adapter_t *adapter) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - u32 Value; - u32 ConfigData; - u32 MaxFrame; - u32 AxgMacReg1; - int status; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink", - adapter, 0, 0, 0); - - /* Reset PHY and XGXS module */ - WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE); - - /* Reset transmit configuration register */ - WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE); - - /* Reset receive configuration register */ - WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE); - - /* Reset all MAC modules */ - WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE); - - /* - * Link address 0 - * XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) - * is stored with the first nibble (0a) in the byte 0 - * of the Mac address. Possibly reverse? - */ - Value = *(u32 *) adapter->macaddr; - WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE); - /* also write the MAC address to the MAC. Endian is reversed. */ - WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE); - Value = (*(u16 *) & adapter->macaddr[4] & 0x0000FFFF); - WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE); - /* endian swap for the MAC (put high bytes in bits [31:16], swapped) */ - Value = ntohl(Value); - WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE); - /* Link address 1 */ - WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE); - /* Link address 2 */ - WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE); - /* Link address 3 */ - WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE); - WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE); - - /* Enable MAC modules */ - WRITE_REG(HwRegs->MacConfig0, 0, TRUE); - - /* Configure MAC */ - AxgMacReg1 = ( /* Enable XMT */ - AXGMAC_CFG1_XMT_EN | - /* Enable receive */ - AXGMAC_CFG1_RCV_EN | - /* short frame detection */ - AXGMAC_CFG1_SHORT_ASSERT | - /* Verify frame length */ - AXGMAC_CFG1_CHECK_LEN | - /* Generate FCS */ - AXGMAC_CFG1_GEN_FCS | - /* Pad frames to 64 bytes */ - AXGMAC_CFG1_PAD_64); - - if (adapter->XmtFcEnabled) { - AxgMacReg1 |= AXGMAC_CFG1_XMT_PAUSE; /* Allow sending of pause */ - } - if (adapter->RcvFcEnabled) { - AxgMacReg1 |= AXGMAC_CFG1_RCV_PAUSE; /* Enable detection of pause */ - } - - WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, TRUE); - - /* Set AXGMAC max frame length if jumbo. Not needed for standard MTU */ - if (adapter->JumboEnabled) { - WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE); - } - /* - * AMIIM Configuration Register - - * The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion - * (bottom bits) of this register is used to determine the MDC frequency - * as specified in the A-XGMAC Design Document. This value must not be - * zero. The following value (62 or 0x3E) is based on our MAC transmit - * clock frequency (MTCLK) of 312.5 MHz. Given a maximum MDIO clock - * frequency of 2.5 MHz (see the PHY spec), we get: - * 312.5/(2*(X+1)) < 2.5 ==> X = 62. - * This value happens to be the default value for this register, so we - * really don't have to do this. - */ - if (adapter->asictype == SAHARA_REV_B) { - WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE); - } else { - WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE); - } - - /* Power up and enable PHY and XAUI/XGXS/Serdes logic */ - WRITE_REG(HwRegs->LinkStatus, - (LS_PHY_CLR_RESET | - LS_XGXS_ENABLE | - LS_XGXS_CTL | - LS_PHY_CLK_EN | - LS_ATTN_ALARM), - TRUE); - DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n"); - - /* - * Per information given by Aeluros, wait 100 ms after removing reset. - * It's not enough to wait for the self-clearing reset bit in reg 0 to - * clear. - */ - mdelay(100); - - /* Verify the PHY has come up by checking that the Reset bit has - * cleared. - */ - status = sxg_read_mdio_reg(adapter, - MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */ - PHY_PMA_CONTROL1, /* PMA/PMD control register */ - &Value); - DBG_ERROR("After sxg_read_mdio_reg Value[%x] fail=%x\n", Value, - (Value & PMA_CONTROL1_RESET)); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */ - return (STATUS_FAILURE); - - /* The SERDES should be initialized by now - confirm */ - READ_REG(HwRegs->LinkStatus, Value); - if (Value & LS_SERDES_DOWN) /* verify SERDES is initialized */ - return (STATUS_FAILURE); - - /* The XAUI link should also be up - confirm */ - if (!(Value & LS_XAUI_LINK_UP)) /* verify XAUI link is up */ - return (STATUS_FAILURE); - - /* Initialize the PHY */ - status = sxg_phy_init(adapter); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - /* Enable the Link Alarm */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * LASI_CONTROL - LASI control register - * LASI_CTL_LS_ALARM_ENABLE - enable link alarm bit - */ - status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - LASI_CONTROL, - LASI_CTL_LS_ALARM_ENABLE); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - /* XXXTODO - temporary - verify bit is set */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * LASI_CONTROL - LASI control register - */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - LASI_CONTROL, - &Value); - - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) { - DBG_ERROR("Error! LASI Control Alarm Enable bit not set!\n"); - } - /* Enable receive */ - MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME; - ConfigData = (RCV_CONFIG_ENABLE | - RCV_CONFIG_ENPARSE | - RCV_CONFIG_RCVBAD | - RCV_CONFIG_RCVPAUSE | - RCV_CONFIG_TZIPV6 | - RCV_CONFIG_TZIPV4 | - RCV_CONFIG_HASH_16 | - RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame)); - - if (adapter->asictype == SAHARA_REV_B) { - ConfigData |= (RCV_CONFIG_HIPRICTL | - RCV_CONFIG_NEWSTATUSFMT); - } - WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE); - - WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE); - - /* Mark the link as down. We'll get a link event when it comes up. */ - sxg_link_state(adapter, SXG_LINK_DOWN); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk", - adapter, 0, 0, 0); - return (STATUS_SUCCESS); -} - -/* - * sxg_phy_init - Initialize the PHY - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * status - */ -static int sxg_phy_init(struct adapter_t *adapter) -{ - u32 Value; - struct phy_ucode *p; - int status; - - DBG_ERROR("ENTER %s\n", __func__); - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module - * 0xC205 - PHY ID register (?) - * &Value - XXXTODO - add def - */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - 0xC205, - &Value); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - - if (Value == 0x0012) { - /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */ - DBG_ERROR("AEL2005C PHY detected. Downloading PHY \ - microcode.\n"); - - /* Initialize AEL2005C PHY and download PHY microcode */ - for (p = PhyUcode; p->Addr != 0xFFFF; p++) { - if (p->Addr == 0) { - /* if address == 0, data == sleep time in ms */ - mdelay(p->Data); - } else { - /* write the given data to the specified address */ - status = sxg_write_mdio_reg(adapter, - MIIM_DEV_PHY_PMA, - /* PHY address */ - p->Addr, - /* PHY data */ - p->Data); - if (status != STATUS_SUCCESS) - return (STATUS_FAILURE); - } - } - } - DBG_ERROR("EXIT %s\n", __func__); - - return (STATUS_SUCCESS); -} - -/* - * sxg_link_event - Process a link event notification from the card - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * None - */ -static void sxg_link_event(struct adapter_t *adapter) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - struct net_device *netdev = adapter->netdev; - enum SXG_LINK_STATE LinkState; - int status; - u32 Value; - - if (adapter->state == ADAPT_DOWN) - return; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt", - adapter, 0, 0, 0); - DBG_ERROR("ENTER %s\n", __func__); - - /* Check the Link Status register. We should have a Link Alarm. */ - READ_REG(HwRegs->LinkStatus, Value); - if (Value & LS_LINK_ALARM) { - /* - * We got a Link Status alarm. First, pause to let the - * link state settle (it can bounce a number of times) - */ - mdelay(10); - - /* Now clear the alarm by reading the LASI status register. */ - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - /* LASI status register */ - LASI_STATUS, - &Value); - if (status != STATUS_SUCCESS) { - DBG_ERROR("Error reading LASI Status MDIO register!\n"); - sxg_link_state(adapter, SXG_LINK_DOWN); - /* ASSERT(0); */ - } - /* - * We used to assert that the LASI_LS_ALARM bit was set, as - * it should be. But there appears to be cases during - * initialization (when the PHY is reset and re-initialized) - * when we get a link alarm, but the status bit is 0 when we - * read it. Rather than trying to assure this never happens - * (and nver being certain), just ignore it. - - * ASSERT(Value & LASI_STATUS_LS_ALARM); - */ - - /* Now get and set the link state */ - LinkState = sxg_get_link_state(adapter); - sxg_link_state(adapter, LinkState); - DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n", - ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN")); - if (LinkState == SXG_LINK_UP) { - netif_carrier_on(netdev); - netif_tx_start_all_queues(netdev); - } else { - netif_tx_stop_all_queues(netdev); - netif_carrier_off(netdev); - } - } else { - /* - * XXXTODO - Assuming Link Attention is only being generated - * for the Link Alarm pin (and not for a XAUI Link Status change) - * , then it's impossible to get here. Yet we've gotten here - * twice (under extreme conditions - bouncing the link up and - * down many times a second). Needs further investigation. - */ - DBG_ERROR("SXG: sxg_link_event: Can't get here!\n"); - DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value); - /* ASSERT(0); */ - } - DBG_ERROR("EXIT %s\n", __func__); - -} - -/* - * sxg_get_link_state - Determine if the link is up or down - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * Link State - */ -static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter) -{ - int status; - u32 Value; - - DBG_ERROR("ENTER %s\n", __func__); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink", - adapter, 0, 0, 0); - - /* - * Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if - * the following 3 bits (from 3 different MDIO registers) are all true. - */ - - /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, - /* PMA/PMD Receive Signal Detect register */ - PHY_PMA_RCV_DET, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If PMA/PMD receive signal detect is 0, then the link is down */ - if (!(Value & PMA_RCV_DETECT)) - return (SXG_LINK_DOWN); - - /* MIIM_DEV_PHY_PCS - PHY PCS module */ - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS, - /* PCS 10GBASE-R Status 1 register */ - PHY_PCS_10G_STATUS1, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If PCS is not locked to receive blocks, then the link is down */ - if (!(Value & PCS_10B_BLOCK_LOCK)) - return (SXG_LINK_DOWN); - - status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,/* PHY XS module */ - /* XS Lane Status register */ - PHY_XS_LANE_STATUS, - &Value); - if (status != STATUS_SUCCESS) - goto bad; - - /* If XS transmit lanes are not aligned, then the link is down */ - if (!(Value & XS_LANE_ALIGN)) - return (SXG_LINK_DOWN); - - /* All 3 bits are true, so the link is up */ - DBG_ERROR("EXIT %s\n", __func__); - - return (SXG_LINK_UP); - - bad: - /* An error occurred reading an MDIO register. This shouldn't happen. */ - DBG_ERROR("Error reading an MDIO register!\n"); - ASSERT(0); - return (SXG_LINK_DOWN); -} - -static void sxg_indicate_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState) -{ - if (adapter->LinkState == SXG_LINK_UP) { - DBG_ERROR("%s: LINK now UP, call netif_start_queue\n", - __func__); - netif_start_queue(adapter->netdev); - } else { - DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n", - __func__); - netif_stop_queue(adapter->netdev); - } -} - -/* - * sxg_change_mtu - Change the Maximum Transfer Unit - * * @returns 0 on success, negative on failure - */ -int sxg_change_mtu (struct net_device *netdev, int new_mtu) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(netdev); - - if (!((new_mtu == SXG_DEFAULT_MTU) || (new_mtu == SXG_JUMBO_MTU))) - return -EINVAL; - - if(new_mtu == netdev->mtu) - return 0; - - netdev->mtu = new_mtu; - - if (new_mtu == SXG_JUMBO_MTU) { - adapter->JumboEnabled = TRUE; - adapter->FrameSize = JUMBOMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE; - } else { - adapter->JumboEnabled = FALSE; - adapter->FrameSize = ETHERMAXFRAME; - adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE; - } - - sxg_entry_halt(netdev); - sxg_entry_open(netdev); - return 0; -} - -/* - * sxg_link_state - Set the link state and if necessary, indicate. - * This routine the central point of processing for all link state changes. - * Nothing else in the driver should alter the link state or perform - * link state indications - * - * Arguments - - * adapter - A pointer to our adapter structure - * LinkState - The link state - * - * Return - * None - */ -static void sxg_link_state(struct adapter_t *adapter, - enum SXG_LINK_STATE LinkState) -{ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT", - adapter, LinkState, adapter->LinkState, adapter->State); - - DBG_ERROR("ENTER %s\n", __func__); - - /* - * Hold the adapter lock during this routine. Maybe move - * the lock to the caller. - */ - /* IMP TODO : Check if we can survive without taking this lock */ -// spin_lock(&adapter->AdapterLock); - if (LinkState == adapter->LinkState) { - /* Nothing changed.. */ -// spin_unlock(&adapter->AdapterLock); - DBG_ERROR("EXIT #0 %s. Link status = %d\n", - __func__, LinkState); - return; - } - /* Save the adapter state */ - adapter->LinkState = LinkState; - - /* Drop the lock and indicate link state */ -// spin_unlock(&adapter->AdapterLock); - DBG_ERROR("EXIT #1 %s\n", __func__); - - sxg_indicate_link_state(adapter, LinkState); -} - -/* - * sxg_write_mdio_reg - Write to a register on the MDIO bus - * - * Arguments - - * adapter - A pointer to our adapter structure - * DevAddr - MDIO device number being addressed - * RegAddr - register address for the specified MDIO device - * Value - value to write to the MDIO register - * - * Return - * status - */ -static int sxg_write_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 Value) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - /* Address operation (written to MIIM field reg) */ - u32 AddrOp; - /* Write operation (written to MIIM field reg) */ - u32 WriteOp; - u32 Cmd;/* Command (written to MIIM command reg) */ - u32 ValueRead; - u32 Timeout; - - /* DBG_ERROR("ENTER %s\n", __func__); */ - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO", - adapter, 0, 0, 0); - - /* Ensure values don't exceed field width */ - DevAddr &= 0x001F; /* 5-bit field */ - RegAddr &= 0xFFFF; /* 16-bit field */ - Value &= 0xFFFF; /* 16-bit field */ - - /* Set MIIM field register bits for an MIIM address operation */ - AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr; - - /* Set MIIM field register bits for an MIIM write operation */ - WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value; - - /* Set MIIM command register bits to execute an MIIM command */ - Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION; - - /* Reset the command register command bit (in case it's not 0) */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set the address of the specified MDIO register */ - WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE); - - /* Write to MIIM Command Register to execute to address operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Reset the command register command bit */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set up an MDIO write operation */ - WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE); - - /* Write to MIIM Command Register to execute the write operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* DBG_ERROR("EXIT %s\n", __func__); */ - - return (STATUS_SUCCESS); -} - -/* - * sxg_read_mdio_reg - Read a register on the MDIO bus - * - * Arguments - - * adapter - A pointer to our adapter structure - * DevAddr - MDIO device number being addressed - * RegAddr - register address for the specified MDIO device - * pValue - pointer to where to put data read from the MDIO register - * - * Return - * status - */ -static int sxg_read_mdio_reg(struct adapter_t *adapter, - u32 DevAddr, u32 RegAddr, u32 *pValue) -{ - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - u32 AddrOp; /* Address operation (written to MIIM field reg) */ - u32 ReadOp; /* Read operation (written to MIIM field reg) */ - u32 Cmd; /* Command (written to MIIM command reg) */ - u32 ValueRead; - u32 Timeout; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO", - adapter, 0, 0, 0); - DBG_ERROR("ENTER %s\n", __func__); - - /* Ensure values don't exceed field width */ - DevAddr &= 0x001F; /* 5-bit field */ - RegAddr &= 0xFFFF; /* 16-bit field */ - - /* Set MIIM field register bits for an MIIM address operation */ - AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr; - - /* Set MIIM field register bits for an MIIM read operation */ - ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) | - (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) | - (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) | - (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT); - - /* Set MIIM command register bits to execute an MIIM command */ - Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION; - - /* Reset the command register command bit (in case it's not 0) */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set the address of the specified MDIO register */ - WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE); - - /* Write to MIIM Command Register to execute to address operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __func__); - - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Reset the command register command bit */ - WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE); - - /* MIIM write to set up an MDIO register read operation */ - WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE); - - /* Write to MIIM Command Register to execute the read operation */ - WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE); - - /* Poll AMIIM Indicator register to wait for completion */ - Timeout = SXG_LINK_TIMEOUT; - do { - udelay(100); /* Timeout in 100us units */ - READ_REG(HwRegs->MacAmiimIndicator, ValueRead); - if (--Timeout == 0) { - DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __func__); - - return (STATUS_FAILURE); - } - } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY); - - /* Read the MDIO register data back from the field register */ - READ_REG(HwRegs->MacAmiimField, *pValue); - *pValue &= 0xFFFF; /* data is in the lower 16 bits */ - - DBG_ERROR("EXIT %s\n", __func__); - - return (STATUS_SUCCESS); -} - -/* - * Functions to obtain the CRC corresponding to the destination mac address. - * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using - * the polynomial: - * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 - * + x^4 + x^2 + x^1. - * - * After the CRC for the 6 bytes is generated (but before the value is - * complemented), we must then transpose the value and return bits 30-23. - */ -static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */ -static u32 sxg_crc_init; /* Is table initialized */ - -/* Contruct the CRC32 table */ -static void sxg_mcast_init_crc32(void) -{ - u32 c; /* CRC shit reg */ - u32 e = 0; /* Poly X-or pattern */ - int i; /* counter */ - int k; /* byte being shifted into crc */ - - static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 }; - - for (i = 0; i < ARRAY_SIZE(p); i++) { - e |= 1L << (31 - p[i]); - } - - for (i = 1; i < 256; i++) { - c = i; - for (k = 8; k; k--) { - c = c & 1 ? (c >> 1) ^ e : c >> 1; - } - sxg_crc_table[i] = c; - } -} - -/* - * Return the MAC hast as described above. - */ -static unsigned char sxg_mcast_get_mac_hash(char *macaddr) -{ - u32 crc; - char *p; - int i; - unsigned char machash = 0; - - if (!sxg_crc_init) { - sxg_mcast_init_crc32(); - sxg_crc_init = 1; - } - - crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */ - for (i = 0, p = macaddr; i < 6; ++p, ++i) { - crc = (crc >> 8) ^ sxg_crc_table[(crc ^ *p) & 0xFF]; - } - - /* Return bits 1-8, transposed */ - for (i = 1; i < 9; i++) { - machash |= (((crc >> i) & 1) << (8 - i)); - } - - return (machash); -} - -static void sxg_mcast_set_mask(struct adapter_t *adapter) -{ - struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs; - - DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __func__, - adapter->netdev->name, (unsigned int)adapter->MacFilter, - adapter->MulticastMask); - - if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) { - /* - * Turn on all multicast addresses. We have to do this for - * promiscuous mode as well as ALLMCAST mode. It saves the - * Microcode from having keep state about the MAC configuration - */ - /* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \ - * SLUT MODE!!!\n",__func__); - */ - WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH); - WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH); - /* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high \ - * 0xFFFFFFFF\n",__func__, adapter->netdev->name); - */ - - } else { - /* - * Commit our multicast mast to the SLIC by writing to the - * multicast address mask registers - */ - DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n", - __func__, adapter->netdev->name, - ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)), - ((ulong) - ((adapter->MulticastMask >> 32) & 0xFFFFFFFF))); - - WRITE_REG(sxg_regs->McastLow, - (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH); - WRITE_REG(sxg_regs->McastHigh, - (u32) ((adapter-> - MulticastMask >> 32) & 0xFFFFFFFF), FLUSH); - } -} - -static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address) -{ - unsigned char crcpoly; - - /* Get the CRC polynomial for the mac address */ - crcpoly = sxg_mcast_get_mac_hash(address); - - /* - * We only have space on the SLIC for 64 entries. Lop - * off the top two bits. (2^6 = 64) - */ - crcpoly &= 0x3F; - - /* OR in the new bit into our 64 bit mask. */ - adapter->MulticastMask |= (u64) 1 << crcpoly; -} - -/* - * Function takes MAC addresses from dev_mc_list and generates the Mask - */ - -static void sxg_set_mcast_addr(struct adapter_t *adapter) -{ - struct dev_mc_list *mclist; - struct net_device *dev = adapter->netdev; - int i; - - if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) { - for (i = 0, mclist = dev->mc_list; i < dev->mc_count; - i++, mclist = mclist->next) { - sxg_mcast_set_bit(adapter,mclist->da_addr); - } - } - sxg_mcast_set_mask(adapter); -} - -static void sxg_mcast_set_list(struct net_device *dev) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - - ASSERT(adapter); - if (dev->flags & IFF_PROMISC) - adapter->MacFilter |= MAC_PROMISC; - if (dev->flags & IFF_MULTICAST) - adapter->MacFilter |= MAC_MCAST; - if (dev->flags & IFF_ALLMULTI) - adapter->MacFilter |= MAC_ALLMCAST; - - //XXX handle other flags as well - sxg_set_mcast_addr(adapter); -} - -void sxg_free_sgl_buffers(struct adapter_t *adapter) -{ - struct list_entry *ple; - struct sxg_scatter_gather *Sgl; - - while(!(IsListEmpty(&adapter->AllSglBuffers))) { - ple = RemoveHeadList(&adapter->AllSglBuffers); - Sgl = container_of(ple, struct sxg_scatter_gather, AllList); - kfree(Sgl); - adapter->AllSglBufferCount--; - } -} - -void sxg_free_rcvblocks(struct adapter_t *adapter) -{ - u32 i; - void *temp_RcvBlock; - struct list_entry *ple; - struct sxg_rcv_block_hdr *RcvBlockHdr; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - ASSERT((adapter->state == SXG_STATE_INITIALIZING) || - (adapter->state == SXG_STATE_HALTING)); - while(!(IsListEmpty(&adapter->AllRcvBlocks))) { - - ple = RemoveHeadList(&adapter->AllRcvBlocks); - RcvBlockHdr = container_of(ple, struct sxg_rcv_block_hdr, AllList); - - if(RcvBlockHdr->VirtualAddress) { - temp_RcvBlock = RcvBlockHdr->VirtualAddress; - - for(i=0; i< SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - SXG_FREE_RCV_PACKET(RcvDataBufferHdr); - } - } - - pci_free_consistent(adapter->pcidev, - SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE), - RcvBlockHdr->VirtualAddress, - RcvBlockHdr->PhysicalAddress); - adapter->AllRcvBlockCount--; - } - ASSERT(adapter->AllRcvBlockCount == 0); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk", - adapter, 0, 0, 0); -} -void sxg_free_mcast_addrs(struct adapter_t *adapter) -{ - struct sxg_multicast_address *address; - while(adapter->MulticastAddrs) { - address = adapter->MulticastAddrs; - adapter->MulticastAddrs = address->Next; - kfree(address); - } - - adapter->MulticastMask= 0; -} - -void sxg_unmap_resources(struct adapter_t *adapter) -{ - if(adapter->HwRegs) { - iounmap((void *)adapter->HwRegs); - } - if(adapter->UcodeRegs) { - iounmap((void *)adapter->UcodeRegs); - } - - ASSERT(adapter->AllRcvBlockCount == 0); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk", - adapter, 0, 0, 0); -} - - - -/* - * sxg_free_resources - Free everything allocated in SxgAllocateResources - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * none - */ -void sxg_free_resources(struct adapter_t *adapter) -{ - u32 RssIds, IsrCount; - RssIds = SXG_RSS_CPU_COUNT(adapter); - IsrCount = adapter->msi_enabled ? RssIds : 1; - - if (adapter->BasicAllocations == FALSE) { - /* - * No allocations have been made, including spinlocks, - * or listhead initializations. Return. - */ - return; - } - - if (!(IsListEmpty(&adapter->AllRcvBlocks))) { - sxg_free_rcvblocks(adapter); - } - if (!(IsListEmpty(&adapter->AllSglBuffers))) { - sxg_free_sgl_buffers(adapter); - } - - if (adapter->XmtRingZeroIndex) { - pci_free_consistent(adapter->pcidev, - sizeof(u32), - adapter->XmtRingZeroIndex, - adapter->PXmtRingZeroIndex); - } - if (adapter->Isr) { - pci_free_consistent(adapter->pcidev, - sizeof(u32) * IsrCount, - adapter->Isr, adapter->PIsr); - } - - if (adapter->EventRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_event_ring) * RssIds, - adapter->EventRings, adapter->PEventRings); - } - if (adapter->RcvRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_rcv_ring) * 1, - adapter->RcvRings, - adapter->PRcvRings); - adapter->RcvRings = NULL; - } - - if(adapter->XmtRings) { - pci_free_consistent(adapter->pcidev, - sizeof(struct sxg_xmt_ring) * 1, - adapter->XmtRings, - adapter->PXmtRings); - adapter->XmtRings = NULL; - } - - if (adapter->ucode_stats) { - pci_unmap_single(adapter->pcidev, - sizeof(struct sxg_ucode_stats), - adapter->pucode_stats, PCI_DMA_FROMDEVICE); - adapter->ucode_stats = NULL; - } - - - /* Unmap register spaces */ - sxg_unmap_resources(adapter); - - sxg_free_mcast_addrs(adapter); - - adapter->BasicAllocations = FALSE; - -} - -/* - * sxg_allocate_complete - - * - * This routine is called when a memory allocation has completed. - * - * Arguments - - * struct adapter_t * - Our adapter structure - * VirtualAddress - Memory virtual address - * PhysicalAddress - Memory physical address - * Length - Length of memory allocated (or 0) - * Context - The type of buffer allocated - * - * Return - * None. - */ -static int sxg_allocate_complete(struct adapter_t *adapter, - void *VirtualAddress, - dma_addr_t PhysicalAddress, - u32 Length, enum sxg_buffer_type Context) -{ - int status = 0; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp", - adapter, VirtualAddress, Length, Context); - ASSERT(atomic_read(&adapter->pending_allocations)); - atomic_dec(&adapter->pending_allocations); - - switch (Context) { - - case SXG_BUFFER_TYPE_RCV: - status = sxg_allocate_rcvblock_complete(adapter, - VirtualAddress, - PhysicalAddress, Length); - break; - case SXG_BUFFER_TYPE_SGL: - sxg_allocate_sgl_buffer_complete(adapter, (struct sxg_scatter_gather *) - VirtualAddress, - PhysicalAddress, Length); - break; - } - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp", - adapter, VirtualAddress, Length, Context); - - return status; -} - -/* - * sxg_allocate_buffer_memory - Shared memory allocation routine used for - * synchronous and asynchronous buffer allocations - * - * Arguments - - * adapter - A pointer to our adapter structure - * Size - block size to allocate - * BufferType - Type of buffer to allocate - * - * Return - * int - */ -static int sxg_allocate_buffer_memory(struct adapter_t *adapter, - u32 Size, enum sxg_buffer_type BufferType) -{ - int status; - void *Buffer; - dma_addr_t pBuffer; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem", - adapter, Size, BufferType, 0); - /* - * Grab the adapter lock and check the state. If we're in anything other - * than INITIALIZING or RUNNING state, fail. This is to prevent - * allocations in an improper driver state - */ - - atomic_inc(&adapter->pending_allocations); - - if(BufferType != SXG_BUFFER_TYPE_SGL) - Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer); - else { - Buffer = kzalloc(Size, GFP_ATOMIC); - pBuffer = (dma_addr_t)NULL; - } - if (Buffer == NULL) { - /* - * Decrement the AllocationsPending count while holding - * the lock. Pause processing relies on this - */ - atomic_dec(&adapter->pending_allocations); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1", - adapter, Size, BufferType, 0); - return (STATUS_RESOURCES); - } - status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType); - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem", - adapter, Size, BufferType, status); - return status; -} - -/* - * sxg_allocate_rcvblock_complete - Complete a receive descriptor - * block allocation - * - * Arguments - - * adapter - A pointer to our adapter structure - * RcvBlock - receive block virtual address - * PhysicalAddress - Physical address - * Length - Memory length - * - * Return - */ -static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter, - void *RcvBlock, - dma_addr_t PhysicalAddress, - u32 Length) -{ - u32 i; - u32 BufferSize = adapter->ReceiveBufferSize; - u64 Paddr; - void *temp_RcvBlock; - struct sxg_rcv_block_hdr *RcvBlockHdr; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sxg_rcv_descriptor_block *RcvDescriptorBlock; - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk", - adapter, RcvBlock, Length, 0); - if (RcvBlock == NULL) { - goto fail; - } - memset(RcvBlock, 0, Length); - ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) || - (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); - ASSERT(Length == SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE)); - /* - * First, initialize the contained pool of receive data buffers. - * This initialization requires NBL/NB/MDL allocations, if any of them - * fail, free the block and return without queueing the shared memory - */ - //RcvDataBuffer = RcvBlock; - temp_RcvBlock = RcvBlock; - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) - temp_RcvBlock; - /* For FREE macro assertion */ - RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize); - if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL) - goto fail; - - } - - /* - * Place this entire block of memory on the AllRcvBlocks queue so it - * can be free later - */ - - RcvBlockHdr = (struct sxg_rcv_block_hdr *) ((unsigned char *)RcvBlock + - SXG_RCV_BLOCK_HDR_OFFSET(SXG_RCV_DATA_HDR_SIZE)); - RcvBlockHdr->VirtualAddress = RcvBlock; - RcvBlockHdr->PhysicalAddress = PhysicalAddress; - spin_lock(&adapter->RcvQLock); - adapter->AllRcvBlockCount++; - InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList); - spin_unlock(&adapter->RcvQLock); - - /* Now free the contained receive data buffers that we - * initialized above */ - temp_RcvBlock = RcvBlock; - for (i = 0, Paddr = PhysicalAddress; - i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, Paddr += SXG_RCV_DATA_HDR_SIZE, - temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - spin_unlock(&adapter->RcvQLock); - } - - /* Locate the descriptor block and put it on a separate free queue */ - RcvDescriptorBlock = - (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock + - SXG_RCV_DESCRIPTOR_BLOCK_OFFSET - (SXG_RCV_DATA_HDR_SIZE)); - RcvDescriptorBlockHdr = - (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock + - SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET - (SXG_RCV_DATA_HDR_SIZE)); - RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock; - RcvDescriptorBlockHdr->PhysicalAddress = Paddr; - spin_lock(&adapter->RcvQLock); - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, RcvDescriptorBlockHdr); - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk", - adapter, RcvBlock, Length, 0); - return STATUS_SUCCESS; -fail: - /* Free any allocated resources */ - if (RcvBlock) { - temp_RcvBlock = RcvBlock; - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; - i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) { - RcvDataBufferHdr = - (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock; - SXG_FREE_RCV_PACKET(RcvDataBufferHdr); - } - pci_free_consistent(adapter->pcidev, - Length, RcvBlock, PhysicalAddress); - } - DBG_ERROR("%s: OUT OF RESOURCES\n", __func__); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail", - adapter, adapter->FreeRcvBufferCount, - adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount); - adapter->Stats.NoMem++; - /* As allocation failed, free all previously allocated blocks..*/ - //sxg_free_rcvblocks(adapter); - - return STATUS_RESOURCES; -} - -/* - * sxg_allocate_sgl_buffer_complete - Complete a SGL buffer allocation - * - * Arguments - - * adapter - A pointer to our adapter structure - * SxgSgl - struct sxg_scatter_gather buffer - * PhysicalAddress - Physical address - * Length - Memory length - * - * Return - */ -static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter, - struct sxg_scatter_gather *SxgSgl, - dma_addr_t PhysicalAddress, - u32 Length) -{ - unsigned long sgl_flags; - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp", - adapter, SxgSgl, Length, 0); - spin_lock_irqsave(&adapter->SglQLock, sgl_flags); - adapter->AllSglBufferCount++; - /* PhysicalAddress; */ - SxgSgl->PhysicalAddress = PhysicalAddress; - /* Initialize backpointer once */ - SxgSgl->adapter = adapter; - InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList); - spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags); - SxgSgl->State = SXG_BUFFER_BUSY; - SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl", - adapter, SxgSgl, Length, 0); -} - - -static int sxg_adapter_set_hwaddr(struct adapter_t *adapter) -{ - /* - * DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] \ - * funct#[%d]\n", __func__, card->config_set, - * adapter->port, adapter->physport, adapter->functionnumber); - * - * sxg_dbg_macaddrs(adapter); - */ - /* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", - * __func__); - */ - - /* sxg_dbg_macaddrs(adapter); */ - - struct net_device * dev = adapter->netdev; - if(!dev) - { - printk("sxg: Dev is Null\n"); - } - - DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name); - - if (netif_running(dev)) { - return -EBUSY; - } - if (!adapter) { - return -EBUSY; - } - - if (!(adapter->currmacaddr[0] || - adapter->currmacaddr[1] || - adapter->currmacaddr[2] || - adapter->currmacaddr[3] || - adapter->currmacaddr[4] || adapter->currmacaddr[5])) { - memcpy(adapter->currmacaddr, adapter->macaddr, 6); - } - if (adapter->netdev) { - memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6); - memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6); - } - /* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */ - sxg_dbg_macaddrs(adapter); - - return 0; -} - -#if XXXTODO -static int sxg_mac_set_address(struct net_device *dev, void *ptr) -{ - struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); - struct sockaddr *addr = ptr; - - DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name); - - if (netif_running(dev)) { - return -EBUSY; - } - if (!adapter) { - return -EBUSY; - } - DBG_ERROR("sxg: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - __func__, adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len); - DBG_ERROR("sxg: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - __func__, adapter->netdev->name, adapter->currmacaddr[0], - adapter->currmacaddr[1], adapter->currmacaddr[2], - adapter->currmacaddr[3], adapter->currmacaddr[4], - adapter->currmacaddr[5]); - - sxg_config_set(adapter, TRUE); - return 0; -} -#endif - -/* - * SXG DRIVER FUNCTIONS (below) - * - * sxg_initialize_adapter - Initialize adapter - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - int - */ -static int sxg_initialize_adapter(struct adapter_t *adapter) -{ - u32 RssIds, IsrCount; - u32 i; - int status; - int sxg_rcv_ring_size = SXG_RCV_RING_SIZE; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt", - adapter, 0, 0, 0); - - RssIds = 1; /* XXXTODO SXG_RSS_CPU_COUNT(adapter); */ - IsrCount = adapter->msi_enabled ? RssIds : 1; - - /* - * Sanity check SXG_UCODE_REGS structure definition to - * make sure the length is correct - */ - ASSERT(sizeof(struct sxg_ucode_regs) == SXG_REGISTER_SIZE_PER_CPU); - - /* Disable interrupts */ - SXG_DISABLE_ALL_INTERRUPTS(adapter); - - /* Set MTU */ - ASSERT((adapter->FrameSize == ETHERMAXFRAME) || - (adapter->FrameSize == JUMBOMAXFRAME)); - WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE); - - /* Set event ring base address and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0); - WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE); - - /* Per-ISR initialization */ - for (i = 0; i < IsrCount; i++) { - u64 Addr; - /* Set interrupt status pointer */ - Addr = adapter->PIsr + (i * sizeof(u32)); - WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i); - } - - /* XMT ring zero index */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].SPSendIndex, - adapter->PXmtRingZeroIndex, 0); - - /* Per-RSS initialization */ - for (i = 0; i < RssIds; i++) { - /* Release all event ring entries to the Microcode */ - WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE, - TRUE); - } - - /* Transmit ring base and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0); - WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE); - - /* Receive ring base and size */ - WRITE_REG64(adapter, - adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0); - if (adapter->JumboEnabled == TRUE) - sxg_rcv_ring_size = SXG_JUMBO_RCV_RING_SIZE; - WRITE_REG(adapter->UcodeRegs[0].RcvSize, sxg_rcv_ring_size, TRUE); - - /* Populate the card with receive buffers */ - sxg_stock_rcv_buffers(adapter); - - /* - * Initialize checksum offload capabilities. At the moment we always - * enable IP and TCP receive checksums on the card. Depending on the - * checksum configuration specified by the user, we can choose to - * report or ignore the checksum information provided by the card. - */ - WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum, - SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE); - - adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED ); - - /* Initialize the MAC, XAUI */ - DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__); - status = sxg_initialize_link(adapter); - DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __func__, - status); - if (status != STATUS_SUCCESS) { - return (status); - } - /* - * Initialize Dead to FALSE. - * SlicCheckForHang or SlicDumpThread will take it from here. - */ - adapter->Dead = FALSE; - adapter->PingOutstanding = FALSE; - adapter->XmtFcEnabled = TRUE; - adapter->RcvFcEnabled = TRUE; - - adapter->State = SXG_STATE_RUNNING; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit", - adapter, 0, 0, 0); - return (STATUS_SUCCESS); -} - -/* - * sxg_fill_descriptor_block - Populate a descriptor block and give it to - * the card. The caller should hold the RcvQLock - * - * Arguments - - * adapter - A pointer to our adapter structure - * RcvDescriptorBlockHdr - Descriptor block to fill - * - * Return - * status - */ -static int sxg_fill_descriptor_block(struct adapter_t *adapter, - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr) -{ - u32 i; - struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo; - struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr; - struct sxg_rcv_descriptor_block *RcvDescriptorBlock; - struct sxg_cmd *RingDescriptorCmd; - struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0]; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - - ASSERT(RcvDescriptorBlockHdr); - - /* - * If we don't have the resources to fill the descriptor block, - * return failure - */ - if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) || - SXG_RING_FULL(RcvRingInfo)) { - adapter->Stats.NoMem++; - return (STATUS_FAILURE); - } - /* Get a ring descriptor command */ - SXG_GET_CMD(RingZero, - RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr); - ASSERT(RingDescriptorCmd); - RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD; - RcvDescriptorBlock = (struct sxg_rcv_descriptor_block *) - RcvDescriptorBlockHdr->VirtualAddress; - - /* Fill in the descriptor block */ - for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) { - SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - ASSERT(RcvDataBufferHdr); -// ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket); - if (!RcvDataBufferHdr->SxgDumbRcvPacket) { - SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, - adapter->ReceiveBufferSize); - if(RcvDataBufferHdr->skb) - RcvDataBufferHdr->SxgDumbRcvPacket = - RcvDataBufferHdr->skb; - else - goto no_memory; - } - SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket); - RcvDataBufferHdr->State = SXG_BUFFER_ONCARD; - RcvDescriptorBlock->Descriptors[i].VirtualAddress = - (void *)RcvDataBufferHdr; - - RcvDescriptorBlock->Descriptors[i].PhysicalAddress = - RcvDataBufferHdr->PhysicalAddress; - } - /* Add the descriptor block to receive descriptor ring 0 */ - RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress; - - /* - * RcvBuffersOnCard is not protected via the receive lock (see - * sxg_process_event_queue) We don't want to grap a lock every time a - * buffer is returned to us, so we use atomic interlocked functions - * instead. - */ - adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk", - RcvDescriptorBlockHdr, - RingDescriptorCmd, RcvRingInfo->Head, RcvRingInfo->Tail); - - WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 1, true); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlk", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - return (STATUS_SUCCESS); -no_memory: - for (; i >= 0 ; i--) { - if (RcvDescriptorBlock->Descriptors[i].VirtualAddress) { - RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) - RcvDescriptorBlock->Descriptors[i]. - VirtualAddress; - RcvDescriptorBlock->Descriptors[i].PhysicalAddress = - (dma_addr_t)NULL; - RcvDescriptorBlock->Descriptors[i].VirtualAddress=NULL; - } - SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr); - } - RcvDescriptorBlockHdr->State = SXG_BUFFER_FREE; - SXG_RETURN_CMD(RingZero, RcvRingInfo, RingDescriptorCmd, - RcvDescriptorBlockHdr); - - return (-ENOMEM); -} - -/* - * sxg_stock_rcv_buffers - Stock the card with receive buffers - * - * Arguments - - * adapter - A pointer to our adapter structure - * - * Return - * None - */ -static void sxg_stock_rcv_buffers(struct adapter_t *adapter) -{ - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS; - int sxg_min_rcv_data_buffers = SXG_MIN_RCV_DATA_BUFFERS; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); - /* - * First, see if we've got less than our minimum threshold of - * receive buffers, there isn't an allocation in progress, and - * we haven't exceeded our maximum.. get another block of buffers - * None of this needs to be SMP safe. It's round numbers. - */ - if (adapter->JumboEnabled == TRUE) - sxg_min_rcv_data_buffers = SXG_MIN_JUMBO_RCV_DATA_BUFFERS; - if ((adapter->FreeRcvBufferCount < sxg_min_rcv_data_buffers) && - (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) && - (atomic_read(&adapter->pending_allocations) == 0)) { - sxg_allocate_buffer_memory(adapter, - SXG_RCV_BLOCK_SIZE - (SXG_RCV_DATA_HDR_SIZE), - SXG_BUFFER_TYPE_RCV); - } - /* Now grab the RcvQLock lock and proceed */ - spin_lock(&adapter->RcvQLock); - if (adapter->JumboEnabled) - sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS; - while (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) { - struct list_entry *_ple; - - /* Get a descriptor block */ - RcvDescriptorBlockHdr = NULL; - if (adapter->FreeRcvBlockCount) { - _ple = RemoveHeadList(&adapter->FreeRcvBlocks); - RcvDescriptorBlockHdr = - container_of(_ple, struct sxg_rcv_descriptor_block_hdr, - FreeList); - adapter->FreeRcvBlockCount--; - RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY; - } - - if (RcvDescriptorBlockHdr == NULL) { - /* Bail out.. */ - adapter->Stats.NoMem++; - break; - } - /* Fill in the descriptor block and give it to the card */ - if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) == - STATUS_FAILURE) { - /* Free the descriptor block */ - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, - RcvDescriptorBlockHdr); - break; - } - } - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlks", - adapter, adapter->RcvBuffersOnCard, - adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount); -} - -/* - * sxg_complete_descriptor_blocks - Return descriptor blocks that have been - * completed by the microcode - * - * Arguments - - * adapter - A pointer to our adapter structure - * Index - Where the microcode is up to - * - * Return - * None - */ -static void sxg_complete_descriptor_blocks(struct adapter_t *adapter, - unsigned char Index) -{ - struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0]; - struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo; - struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr; - struct sxg_cmd *RingDescriptorCmd; - - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks", - adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail); - - /* Now grab the RcvQLock lock and proceed */ - spin_lock(&adapter->RcvQLock); - ASSERT(Index != RcvRingInfo->Tail); - while (sxg_ring_get_forward_diff(RcvRingInfo, Index, - RcvRingInfo->Tail) > 3) { - /* - * Locate the current Cmd (ring descriptor entry), and - * associated receive descriptor block, and advance - * the tail - */ - SXG_RETURN_CMD(RingZero, - RcvRingInfo, - RingDescriptorCmd, RcvDescriptorBlockHdr); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlk", - RcvRingInfo->Head, RcvRingInfo->Tail, - RingDescriptorCmd, RcvDescriptorBlockHdr); - - /* Clear the SGL field */ - RingDescriptorCmd->Sgl = 0; - /* - * Attempt to refill it and hand it right back to the - * card. If we fail to refill it, free the descriptor block - * header. The card will be restocked later via the - * RcvBuffersOnCard test - */ - if (sxg_fill_descriptor_block(adapter, - RcvDescriptorBlockHdr) == STATUS_FAILURE) - SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, - RcvDescriptorBlockHdr); - } - spin_unlock(&adapter->RcvQLock); - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks", - adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail); -} - -/* - * Read the statistics which the card has been maintaining. - */ -void sxg_collect_statistics(struct adapter_t *adapter) -{ - if(adapter->ucode_stats) - WRITE_REG64(adapter, adapter->UcodeRegs[0].GetUcodeStats, - adapter->pucode_stats, 0); - adapter->stats.rx_fifo_errors = adapter->ucode_stats->ERDrops; - adapter->stats.rx_over_errors = adapter->ucode_stats->NBDrops; - adapter->stats.tx_fifo_errors = adapter->ucode_stats->XDrops; -} - -static struct net_device_stats *sxg_get_stats(struct net_device * dev) -{ - struct adapter_t *adapter = netdev_priv(dev); - - sxg_collect_statistics(adapter); - return (&adapter->stats); -} - -static void sxg_watchdog(unsigned long data) -{ - struct adapter_t *adapter = (struct adapter_t *) data; - - if (adapter->state != ADAPT_DOWN) { - sxg_link_event(adapter); - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ)); - } -} - -static void sxg_update_link_status (struct work_struct *work) -{ - struct adapter_t *adapter = (struct adapter_t *)container_of - (work, struct adapter_t, update_link_status); - if (likely(adapter->link_status_changed)) { - sxg_link_event(adapter); - adapter->link_status_changed = 0; - } -} - -static struct pci_driver sxg_driver = { - .name = sxg_driver_name, - .id_table = sxg_pci_tbl, - .probe = sxg_entry_probe, - .remove = __devexit_p(sxg_entry_remove), -#if SXG_POWER_MANAGEMENT_ENABLED - .suspend = sxgpm_suspend, - .resume = sxgpm_resume, -#endif - /* .shutdown = slic_shutdown, MOOK_INVESTIGATE */ -}; - -static int __init sxg_module_init(void) -{ - sxg_init_driver(); - - if (debug >= 0) - sxg_debug = debug; - - return pci_register_driver(&sxg_driver); -} - -static void __exit sxg_module_cleanup(void) -{ - pci_unregister_driver(&sxg_driver); -} - -module_init(sxg_module_init); -module_exit(sxg_module_cleanup); diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h deleted file mode 100644 index 110096a5c52..00000000000 --- a/drivers/staging/sxg/sxg.h +++ /dev/null @@ -1,787 +0,0 @@ -/************************************************************************** - * - * Copyright © 2000-2008 Alacritech, Inc. All rights reserved. - * - * $Id: sxg.h,v 1.3 2008/07/24 17:25:08 chris Exp $ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg.h - * - * This is the base set of header definitions for the SXG driver. - */ -#ifndef __SXG_DRIVER_H__ -#define __SXG_DRIVER_H__ - -#define SLIC_DUMP_ENABLED 0 - -#define SXG_DRV_NAME "sxg" /* TBD: This might be removed eventually */ -#define SXG_DRV_VERSION "1.0.1" - -extern char sxg_driver_name[]; - -#define SXG_NETDEV_WEIGHT 64 - -/* - * struct sxg_stats - Probably move these to someplace where - * the slicstat (sxgstat?) program can get them. - */ -struct sxg_stats { - /* Xmt */ - u64 DumbXmtUcastPkts; /* directed packets */ - u64 DumbXmtMcastPkts; /* Multicast packets */ - u64 DumbXmtBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */ - u64 DumbXmtUcastBytes; /* OID_GEN_DIRECTED_BYTES_XMIT */ - u64 DumbXmtMcastBytes; /* OID_GEN_MULTICAST_BYTES_XMIT */ - u64 DumbXmtBcastBytes; /* OID_GEN_BROADCAST_BYTES_XMIT */ - u64 XmtQLen; /* OID_GEN_TRANSMIT_QUEUE_LENGTH */ - u64 XmtZeroFull; /* Transmit ring zero full */ - /* Rcv */ - u64 DumbRcvUcastBytes; /* OID_GEN_DIRECTED_BYTES_RCV */ - u64 DumbRcvMcastBytes; /* OID_GEN_MULTICAST_BYTES_RCV */ - u64 DumbRcvBcastBytes; /* OID_GEN_BROADCAST_BYTES_RCV */ - u64 DumbRcvUcastPkts; /* directed packets */ - u64 DumbRcvMcastPkts; /* Multicast packets */ - u64 DumbRcvBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */ - u64 PdqFull; /* Processed Data Queue Full */ - u64 EventRingFull; /* Event ring full */ - /* Verbose stats */ - u64 NoSglBuf; /* SGL buffer allocation failure */ - u64 NoMem; /* Memory allocation failure */ - u64 NumInts; /* Interrupts */ - u64 FalseInts; /* Interrupt with ISR == 0 */ - /* Sahara receive status */ - u64 TransportCsum; /* SXG_RCV_STATUS_TRANSPORT_CSUM */ - u64 TransportUflow; /* SXG_RCV_STATUS_TRANSPORT_UFLOW */ - u64 TransportHdrLen; /* SXG_RCV_STATUS_TRANSPORT_HDRLEN */ - u64 NetworkCsum; /* SXG_RCV_STATUS_NETWORK_CSUM: */ - u64 NetworkUflow; /* SXG_RCV_STATUS_NETWORK_UFLOW: */ - u64 NetworkHdrLen; /* SXG_RCV_STATUS_NETWORK_HDRLEN: */ - u64 Parity; /* SXG_RCV_STATUS_PARITY */ - u64 LinkParity; /* SXG_RCV_STATUS_LINK_PARITY: */ - u64 LinkEarly; /* SXG_RCV_STATUS_LINK_EARLY: */ - u64 LinkBufOflow; /* SXG_RCV_STATUS_LINK_BUFOFLOW: */ - u64 LinkCode; /* SXG_RCV_STATUS_LINK_CODE: */ - u64 LinkDribble; /* SXG_RCV_STATUS_LINK_DRIBBLE: */ - u64 LinkCrc; /* SXG_RCV_STATUS_LINK_CRC: */ - u64 LinkOflow; /* SXG_RCV_STATUS_LINK_OFLOW: */ - u64 LinkUflow; /* SXG_RCV_STATUS_LINK_UFLOW: */ -}; - - -/* DUMB-NIC Send path definitions */ - -#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) { \ - ASSERT(_skb); \ - pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE); \ - dev_kfree_skb_irq(_skb); \ -} - -#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \ - ASSERT(_skb); \ -} - -/* - * Locate current receive header buffer location. Use this - * instead of RcvDataHdr->VirtualAddress since the data - * may have been offset by SXG_ADVANCE_MDL_OFFSET - */ -#define SXG_RECEIVE_DATA_LOCATION(_RcvDataHdr) (_RcvDataHdr)->skb->data - -/* Dumb-NIC receive processing */ -/* Define an SXG_PACKET as an NDIS_PACKET */ -#define PSXG_PACKET struct sk_buff * -/* Indications array size */ -#define SXG_RCV_ARRAYSIZE 64 - -#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr, BufferSize) {\ - struct sk_buff * skb; \ - skb = netdev_alloc_skb(_pAdapt->netdev, BufferSize); \ - if (skb) { \ - (_RcvDataBufferHdr)->skb = skb; \ - skb->next = NULL; \ - _RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,\ - _RcvDataBufferHdr->skb->data, BufferSize, PCI_DMA_FROMDEVICE); \ - if (SXG_INVALID_SGL(_RcvDataBufferHdr->PhysicalAddress,BufferSize)) \ - printk(KERN_EMERG "SXG_ALLOCATE_RCV_PACKET: RCV packet" \ - "non-64k boundary aligned\n"); \ - } else { \ - (_RcvDataBufferHdr)->skb = NULL; \ - } \ -} - -#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \ - if((_RcvDataBufferHdr)->skb) { \ - dev_kfree_skb((_RcvDataBufferHdr)->skb); \ - } \ -} - -/* - * Macro to add a NDIS_PACKET to an indication array - * If we fill up our array of packet pointers, then indicate this - * block up now and start on a new one. - */ -#define SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, \ - _NumPackets) { \ - (_IndicationList)[_NumPackets] = (_Packet); \ - (_NumPackets)++; \ - if((_NumPackets) == SXG_RCV_ARRAYSIZE) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \ - (_NumPackets), 0, 0, 0); \ - netif_rx((_IndicationList),(_NumPackets)); \ - (_NumPackets) = 0; \ - } \ -} - -#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) { \ - if(_NumPackets) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \ - (_NumPackets), 0, 0, 0); \ - netif_rx((_IndicationList),(_NumPackets)); \ - (_NumPackets) = 0; \ - } \ -} - -#define SXG_REINIATIALIZE_PACKET(_Packet) \ - {} /*_NdisReinitializePacket(_Packet)*/ - /* this is not necessary with an skb */ - -/* Definitions to initialize Dumb-nic Receive NBLs */ -#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((struct sxg_rcv_nbl_reserved *)\ - ((_Packet)->MiniportReservedEx))->RcvDataBufferHdr) - -#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi) \ - NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), \ - TcpIpChecksumPacketInfo) = (PVOID)(_Cpi) - -#define SXG_RCV_SET_TOEPLITZ(_Packet, _Toeplitz, _Type, _Function) { \ - NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz)); \ - NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type)); \ - NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function)); \ -} - -#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) { \ - NDIS_PACKET_8021Q_INFO _Packet8021qInfo; \ - _Packet8021qInfo.TagHeader.VlanId = (_VlanId); \ - _Packet8021qInfo.TagHeader.UserPriority = (_Priority); \ - NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), Ieee8021QNetBufferListInfo) = \ - _Packet8021qInfo.Value; \ -} - -#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv", \ - (_RcvDataBufferHdr), (_Packet), \ - (_Event)->Status, 0); \ - /* ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); */ \ - skb_put(Packet, (_Event)->Length); \ -} - -/* - * Macros to free a receive data buffer and receive data descriptor block - * NOTE - Lock must be held with RCV macros - */ -#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \ - struct list_entry *_ple; \ - _Hdr = NULL; \ - if((_pAdapt)->FreeRcvBufferCount) { \ - ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \ - _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \ - (_Hdr) = container_of(_ple, struct sxg_rcv_data_buffer_hdr, \ - FreeList); \ - (_pAdapt)->FreeRcvBufferCount--; \ - ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \ - } \ -} - -#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \ - SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \ - (_Hdr), (_pAdapt)->FreeRcvBufferCount, \ - (_Hdr)->State, 0/*(_Hdr)->VirtualAddress*/); \ -/* SXG_RESTORE_MDL_OFFSET(_Hdr); */ \ - (_pAdapt)->FreeRcvBufferCount++; \ - ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) \ - >= (_pAdapt)->FreeRcvBufferCount); \ - ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \ - (_Hdr)->State = SXG_BUFFER_FREE; \ - InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList)); \ -} - -#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) { \ - ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \ - (_Hdr)->State = SXG_BUFFER_FREE; \ - (_pAdapt)->FreeRcvBlockCount++; \ - ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount); \ - InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList); \ -} - -/* SGL macros */ -#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - (_pAdapt)->FreeSglBufferCount++; \ - ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount); \ - ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \ - (_Sgl)->State = SXG_BUFFER_FREE; \ - InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags); \ -} - -/* - * Get an SGL buffer from the free queue. The first part of this macro - * attempts to keep ahead of buffer depletion by allocating more when - * we hit a minimum threshold. Note that we don't grab the lock - * until after that. We're dealing with round numbers here, so we don't need to, - * and not grabbing it avoids a possible double-trip. - */ -#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl, _irq) { \ - struct list_entry *_ple; \ - if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \ - (_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \ - (atomic_read(&_pAdapt->pending_allocations) == 0)) { \ - sxg_allocate_buffer_memory(_pAdapt, \ - (sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\ - SXG_BUFFER_TYPE_SGL); \ - } \ - _Sgl = NULL; \ - if(!_irq) \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - else \ - spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \ - if((_pAdapt)->FreeSglBufferCount) { \ - ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \ - _ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \ - (_Sgl) = container_of(_ple, struct sxg_scatter_gather, \ - FreeList); \ - (_pAdapt)->FreeSglBufferCount--; \ - ASSERT((_Sgl)->State == SXG_BUFFER_FREE); \ - (_Sgl)->State = SXG_BUFFER_BUSY; \ - (_Sgl)->pSgl = NULL; \ - } \ - if(!_irq) \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\ - else \ - spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\ -} - -/* - * struct sxg_multicast_address - * Linked list of multicast addresses. - */ -struct sxg_multicast_address { - unsigned char Address[6]; - struct sxg_multicast_address *Next; -}; - -/* - * Structure to maintain chimney send and receive buffer queues. - * This structure maintains NET_BUFFER_LIST queues that are - * given to us via the Chimney MiniportTcpOffloadSend and - * MiniportTcpOffloadReceive routines. This structure DOES NOT - * manage our data buffer queue - */ -struct sxg_buffer_queue { - u32 Type; /* Slow or fast - See below */ - u32 Direction; /* Xmt or Rcv */ - u32 Bytes; /* Byte count */ - u32 * Head; /* Send queue head */ - u32 * Tail; /* Send queue tail */ -/* PNET_BUFFER_LIST NextNBL;*/ /* Short cut - next NBL */ -/* PNET_BUFFER NextNB; */ /* Short cut - next NB */ -}; - -#define SXG_SLOW_SEND_BUFFER 0 -#define SXG_FAST_SEND_BUFFER 1 -#define SXG_RECEIVE_BUFFER 2 - -#define SXG_INIT_BUFFER(_Buffer, _Type) { \ - (_Buffer)->Type = (_Type); \ - if((_Type) == SXG_RECEIVE_BUFFER) { \ - (_Buffer)->Direction = 0; \ - } else { \ - (_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE; \ - } \ - (_Buffer)->Bytes = 0; \ - (_Buffer)->Head = NULL; \ - (_Buffer)->Tail = NULL; \ -} - - -#define SXG_RSS_CPU_COUNT(_pAdapt) \ - ((_pAdapt)->RssEnabled ? NR_CPUS : 1) - -/* DRIVER and ADAPTER structures */ - -/* - * Adapter states - These states closely match the adapter states - * documented in the DDK (with a few exceptions). - */ -enum SXG_STATE { - SXG_STATE_INITIALIZING, /* Initializing */ - SXG_STATE_BOOTDIAG, /* Boot-Diagnostic mode */ - SXG_STATE_PAUSING, /* Pausing */ - SXG_STATE_PAUSED, /* Paused */ - SXG_STATE_RUNNING, /* Running */ - SXG_STATE_RESETTING, /* Reset in progress */ - SXG_STATE_SLEEP, /* Sleeping */ - SXG_STATE_DIAG, /* Diagnostic mode */ - SXG_STATE_HALTING, /* Halting */ - SXG_STATE_HALTED, /* Down or not-initialized */ - SXG_STATE_SHUTDOWN /* shutdown */ -}; - -/* Link state */ -enum SXG_LINK_STATE { - SXG_LINK_DOWN, - SXG_LINK_UP -}; - -/* Link initialization timeout in 100us units */ -#define SXG_LINK_TIMEOUT 100000 /* 10 Seconds - REDUCE! */ - - -/* Microcode file selection codes */ -enum SXG_UCODE_SEL { - SXG_UCODE_SYSTEM, /* System (operational) uucode */ - SXG_UCODE_SDIAGCPU, /* System CPU diagnostic ucode */ - SXG_UCODE_SDIAGSYS /* System diagnostic ucode */ -}; - - -#define SXG_DISABLE_ALL_INTERRUPTS(_padapt) sxg_disable_interrupt(_padapt) -#define SXG_ENABLE_ALL_INTERRUPTS(_padapt) sxg_enable_interrupt(_padapt) - -/* This probably lives in a proto.h file. Move later */ -#define SXG_MULTICAST_PACKET(_pether) ((_pether)->ether_dhost[0] & 0x01) -#define SXG_BROADCAST_PACKET(_pether) \ - ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \ - (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF)) - -/* For DbgPrints */ -#define SXG_ID DPFLTR_IHVNETWORK_ID -#define SXG_ERROR DPFLTR_ERROR_LEVEL - -/* - * struct sxg_driver structure - - * - * contains information about the sxg driver. There is only - * one of these, and it is defined as a global. - */ - -struct sxg_driver { - struct adapter_t *Adapters; /* Linked list of adapters */ - ushort AdapterID; /* Maintain unique adapter ID */ -}; - -#ifdef STATUS_SUCCESS -#undef STATUS_SUCCESS -#endif - -/* TODO: We need to try and use NETDEV_TX_* before posting this out */ -#define STATUS_SUCCESS 0 -#define STATUS_PENDING 0 -#define STATUS_FAILURE -1 -#define STATUS_ERROR -2 -#define STATUS_NOT_SUPPORTED -3 -#define STATUS_BUFFER_TOO_SHORT -4 -#define STATUS_RESOURCES -5 - -#define SLIC_MAX_CARDS 32 -#define SLIC_MAX_PORTS 4 /* Max # of ports per card */ -#if SLIC_DUMP_ENABLED - -/* - * Dump buffer size - * This cannot be bigger than the max DMA size the card supports, - * given the current code structure in the host and ucode. - * Mojave supports 16K, Oasis supports 16K-1, so - * just set this at 15K, shouldnt make that much of a diff. - */ -#define DUMP_BUF_SIZE 0x3C00 -#endif - -#define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b)) -#define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b)) - -struct mcast_address { - unsigned char address[6]; - struct mcast_address *next; -}; - -#define CARD_DOWN 0x00000000 -#define CARD_UP 0x00000001 -#define CARD_FAIL 0x00000002 -#define CARD_DIAG 0x00000003 -#define CARD_SLEEP 0x00000004 - -#define ADAPT_DOWN 0x00 -#define ADAPT_UP 0x01 -#define ADAPT_FAIL 0x02 -#define ADAPT_RESET 0x03 -#define ADAPT_SLEEP 0x04 - -#define ADAPT_FLAGS_BOOTTIME 0x0001 -#define ADAPT_FLAGS_IS64BIT 0x0002 -#define ADAPT_FLAGS_PENDINGLINKDOWN 0x0004 -#define ADAPT_FLAGS_FIBERMEDIA 0x0008 -#define ADAPT_FLAGS_LOCKS_ALLOCED 0x0010 -#define ADAPT_FLAGS_INT_REGISTERED 0x0020 -#define ADAPT_FLAGS_LOAD_TIMER_SET 0x0040 -#define ADAPT_FLAGS_STATS_TIMER_SET 0x0080 -#define ADAPT_FLAGS_RESET_TIMER_SET 0x0100 - -#define LINK_DOWN 0x00 -#define LINK_CONFIG 0x01 -#define LINK_UP 0x02 - -#define LINK_10MB 0x00 -#define LINK_100MB 0x01 -#define LINK_AUTOSPEED 0x02 -#define LINK_1000MB 0x03 -#define LINK_10000MB 0x04 - -#define LINK_HALFD 0x00 -#define LINK_FULLD 0x01 -#define LINK_AUTOD 0x02 - -#define MAC_DIRECTED 0x00000001 -#define MAC_BCAST 0x00000002 -#define MAC_MCAST 0x00000004 -#define MAC_PROMISC 0x00000008 -#define MAC_LOOPBACK 0x00000010 -#define MAC_ALLMCAST 0x00000020 - -#define SLIC_DUPLEX(x) ((x==LINK_FULLD) ? "FDX" : "HDX") -#define SLIC_SPEED(x) ((x==LINK_100MB) ? "100Mb" : \ - ((x==LINK_1000MB) ? "1000Mb" : " 10Mb")) -#define SLIC_LINKSTATE(x) ((x==LINK_DOWN) ? "Down" : "Up ") -#define SLIC_ADAPTER_STATE(x) ((x==ADAPT_UP) ? "UP" : "Down") -#define SLIC_CARD_STATE(x) ((x==CARD_UP) ? "UP" : "Down") - - -struct ether_header { - unsigned char ether_dhost[6]; - unsigned char ether_shost[6]; - ushort ether_type; -}; - - -#define NUM_CFG_SPACES 2 -#define NUM_CFG_REGS 64 - -/* - * We split LSS sends across four microcode queues derived from - * destination TCP port (if TCP/IP). - */ -#define SXG_LARGE_SEND_QUEUE_MASK 0x3 -#define ISCSI_PORT 0xbc0c /* 3260 */ - -struct physcard { - struct adapter_t *adapter[SLIC_MAX_PORTS]; - struct physcard *next; - unsigned int adapters_allocd; -}; - -struct sxgbase_driver { - spinlock_t driver_lock; - unsigned long flags; /* irqsave for spinlock */ - u32 num_sxg_cards; - u32 num_sxg_ports; - u32 num_sxg_ports_active; - u32 dynamic_intagg; - struct physcard *phys_card; -}; - - -struct adapter_t { - void * ifp; - unsigned int port; - struct napi_struct napi; - struct physcard *physcard; - unsigned int physport; - unsigned int slotnumber; - unsigned int functionnumber; - ushort vendid; - ushort devid; - ushort subsysid; - u32 irq; - - void __iomem * base_addr; - u32 memorylength; - u32 drambase; - u32 dramlength; - enum asic_type asictype; /* type of ASIC (chip) */ - unsigned int activated; - u32 intrregistered; - unsigned int isp_initialized; - unsigned char state; - unsigned char linkstate; - unsigned int flags; - unsigned char macaddr[6]; - unsigned char currmacaddr[6]; - u32 macopts; - ushort devflags_prev; - u64 mcastmask; - struct mcast_address *mcastaddrs; - struct timer_list pingtimer; - u32 pingtimerset; - struct timer_list statstimer; - u32 statstimerset; - struct timer_list vpci_timer; - u32 vpci_timerset; - struct timer_list loadtimer; - u32 loadtimerset; - - u32 xmitq_full; - u32 all_reg_writes; - u32 icr_reg_writes; - u32 isr_reg_writes; - u32 error_interrupts; - u32 error_rmiss_interrupts; - u32 rx_errors; - u32 rcv_drops; - u32 rcv_interrupts; - u32 xmit_interrupts; - u32 linkevent_interrupts; - u32 upr_interrupts; - u32 num_isrs; - u32 false_interrupts; - u32 tx_packets; - u32 xmit_completes; - u32 tx_drops; - u32 rcv_broadcasts; - u32 rcv_multicasts; - u32 rcv_unicasts; - u32 max_isr_rcvs; - u32 max_isr_xmits; - u32 rcv_interrupt_yields; - u32 intagg_period; - struct net_device_stats stats; - u32 * MiniportHandle; /* Our miniport handle */ - enum SXG_STATE State; /* Adapter state */ - enum SXG_LINK_STATE LinkState; /* Link state */ - u64 LinkSpeed; /* Link Speed */ - u32 PowerState; /* NDIS power state */ - struct adapter_t *Next; /* Linked list */ - ushort AdapterID; /* 1..n */ - struct net_device * netdev; - struct net_device * next_netdevice; - struct pci_dev *pcidev; - - struct sxg_multicast_address *MulticastAddrs; /* Multicast list */ - u64 MulticastMask; /* Multicast mask */ - u32 *InterruptHandle; /* Register Interrupt handle */ - u32 InterruptLevel; /* From Resource list */ - u32 InterruptVector; /* From Resource list */ - spinlock_t AdapterLock; /* Serialize access adapter routines */ - spinlock_t Bit64RegLock; /* For writing 64-bit addresses */ - struct sxg_hw_regs *HwRegs; /* Sahara HW Register Memory (BAR0/1) */ - struct sxg_ucode_regs *UcodeRegs; /* Microcode Register Memory (BAR2/3) */ - struct sxg_tcb_regs *TcbRegs; /* Same as Ucode regs - See sxghw.h */ - ushort FrameSize; /* Maximum frame size */ - u32 * DmaHandle; /* NDIS DMA handle */ - u32 * PacketPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */ - u32 * BufferPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */ - u32 MacFilter; /* NDIS MAC Filter */ - struct sxg_event_ring *EventRings; /* Host event rings. 1/CPU to 16 max */ - dma_addr_t PEventRings; /* Physical address */ - u32 NextEvent[SXG_MAX_RSS]; /* Current location in ring */ - dma_addr_t PTcbBuffers; /* TCB Buffers - physical address */ - dma_addr_t PTcbCompBuffers; /* TCB Composite Buffers - phys addr */ - struct sxg_xmt_ring *XmtRings; /* Transmit rings */ - dma_addr_t PXmtRings; /* Transmit rings - physical address */ - struct sxg_ring_info XmtRingZeroInfo; /* Transmit ring 0 info */ - - spinlock_t XmtZeroLock; /* Transmit ring 0 lock */ - u32 * XmtRingZeroIndex; /* Shared XMT ring 0 index */ - dma_addr_t PXmtRingZeroIndex; /* Shared XMT ring 0 index - physical */ - struct list_entry FreeProtocolHeaders;/* Free protocol headers */ - u32 FreeProtoHdrCount; /* Count */ - void * ProtocolHeaders; /* Block of protocol header */ - dma_addr_t PProtocolHeaders; /* Block of protocol headers - phys */ - - struct sxg_rcv_ring *RcvRings; /* Receive rings */ - dma_addr_t PRcvRings; /* Receive rings - physical address */ - struct sxg_ucode_stats *ucode_stats; /* Ucode Stats */ - /* Ucode Stats - physical address */ - dma_addr_t pucode_stats; - - struct sxg_ring_info RcvRingZeroInfo; /* Receive ring 0 info */ - - u32 * Isr; /* Interrupt status register */ - dma_addr_t PIsr; /* ISR - physical address */ - u32 IsrCopy[SXG_MAX_RSS]; /* Copy of ISR */ - ushort InterruptsEnabled; /* Bitmask of enabled vectors */ - unsigned char *IndirectionTable; /* RSS indirection table */ - dma_addr_t PIndirectionTable; /* Physical address */ - ushort RssTableSize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */ - ushort HashKeySize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */ - unsigned char HashSecretKey[40]; /* rss key */ - u32 HashInformation; - /* Receive buffer queues */ - spinlock_t RcvQLock; /* Receive Queue Lock */ - struct list_entry FreeRcvBuffers; /* Free SXG_DATA_BUFFER queue */ - struct list_entry FreeRcvBlocks; /* Free SXG_RCV_DESCRIPTOR_BLOCK Q */ - struct list_entry AllRcvBlocks; /* All SXG_RCV_BLOCKs */ - ushort FreeRcvBufferCount; /* Number of free rcv data buffers */ - ushort FreeRcvBlockCount; /* # of free rcv descriptor blocks */ - ushort AllRcvBlockCount; /* Number of total receive blocks */ - ushort ReceiveBufferSize; /* SXG_RCV_DATA/JUMBO_BUFFER_SIZE only */ - /* Converted this to a atomic variable - u32 AllocationsPending; */ - atomic_t pending_allocations; - u32 AllocationsPending; /* Receive allocation pending */ - u32 RcvBuffersOnCard; /* SXG_DATA_BUFFERS owned by card */ - /* SGL buffers */ - spinlock_t SglQLock; /* SGL Queue Lock */ - struct list_entry FreeSglBuffers; /* Free struct sxg_scatter_gather */ - struct list_entry AllSglBuffers; /* All struct sxg_scatter_gather */ - ushort FreeSglBufferCount; /* Number of free SGL buffers */ - ushort AllSglBufferCount; /* Number of total SGL buffers */ - u32 CurrentTime; /* Tick count */ - u32 FastpathConnections;/* # of fastpath connections */ - /* Various single-bit flags: */ - u32 BasicAllocations:1; /* Locks and listheads */ - u32 IntRegistered:1; /* Interrupt registered */ - u32 PingOutstanding:1; /* Ping outstanding to card */ - u32 Dead:1; /* Card dead */ - u32 DumpDriver:1; /* OID_SLIC_DRIVER_DUMP request */ - u32 DumpCard:1; /* OID_SLIC_CARD_DUMP request */ - u32 DumpCmdRunning:1; /* Dump command in progress */ - u32 DebugRunning:1; /* AGDB debug in progress */ - u32 JumboEnabled:1; /* Jumbo frames enabled */ - u32 msi_enabled:1; /* MSI interrupt enabled */ - u32 RssEnabled:1; /* RSS Enabled */ - u32 FailOnBadEeprom:1; /* Fail on Bad Eeprom */ - u32 DiagStart:1; /* Init adapter for diagnostic start */ - u32 XmtFcEnabled:1; - u32 RcvFcEnabled:1; - /* Stats */ - u32 PendingRcvCount; /* Outstanding rcv indications */ - u32 PendingXmtCount; /* Outstanding send requests */ - struct sxg_stats Stats; /* Statistics */ - u32 ReassBufs; /* Number of reassembly buffers */ - /* Card Crash Info */ - ushort CrashLocation; /* Microcode crash location */ - unsigned char CrashCpu; /* Sahara CPU ID */ - /* Diagnostics */ - /* PDIAG_CMD DiagCmds; */ /* List of free diagnostic commands */ - /* PDIAG_BUFFER DiagBuffers; */ /* List of free diagnostic buffers */ - /* PDIAG_REQ DiagReqQ; */ /* List of outstanding (asynchronous) diag requests */ - /* u32 DiagCmdTimeout; */ /* Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var? */ - /* unsigned char DiagDmaDesc[DMA_CPU_CTXS]; */ /* Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx) */ - /* - * Put preprocessor-conditional fields at the end so we don't - * have to recompile sxgdbg everytime we reconfigure the driver - */ -#if defined(CONFIG_X86) - u32 AddrUpper; /* Upper 32 bits of 64-bit register */ -#endif - unsigned short max_aggregation; - unsigned short min_aggregation; - /*#if SXG_FAILURE_DUMP */ - /* NDIS_EVENT DumpThreadEvent; */ /* syncronize dump thread */ - /* BOOLEAN DumpThreadRunning; */ /* termination flag */ - /* PSXG_DUMP_CMD DumpBuffer; */ /* 68k - Cmd and Buffer */ - /* dma_addr_t PDumpBuffer; */ /* Physical address */ - /*#endif */ /* SXG_FAILURE_DUMP */ - /*MSI-X related data elements*/ - u32 nr_msix_entries; - struct msix_entry *msi_entries; - struct timer_list watchdog_timer; - struct work_struct update_link_status; - u32 link_status_changed; -}; - -#if SLIC_DUMP_ENABLED -#define SLIC_DUMP_REQUESTED 1 -#define SLIC_DUMP_IN_PROGRESS 2 -#define SLIC_DUMP_DONE 3 - -/* - * Microcode crash information structure. This - * structure is written out to the card's SRAM when the microcode panic's. - */ -struct slic_crash_info { - ushort cpu_id; - ushort crash_pc; -}; - -#define CRASH_INFO_OFFSET 0x155C - -#endif - -#define UPDATE_STATS(largestat, newstat, oldstat) \ -{ \ - if ((newstat) < (oldstat)) \ - (largestat) += ((newstat) + (0xFFFFFFFF - oldstat + 1)); \ - else \ - (largestat) += ((newstat) - (oldstat)); \ -} - -#define UPDATE_STATS_GB(largestat, newstat, oldstat) \ -{ \ - (largestat) += ((newstat) - (oldstat)); \ -} - -#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \ -{ \ - _Result = TRUE; \ - if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \ - _Result = FALSE; \ - if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \ - _Result = FALSE; \ -} - -#define ETHERMAXFRAME 1514 -#define JUMBOMAXFRAME 9014 - -#define SXG_JUMBO_MTU 9000 -#define SXG_DEFAULT_MTU 1500 - -#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) -#define SXG_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & 0x00000000FFFFFFFF) -#define SXG_GET_ADDR_HIGH(_addr) \ - (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF) -#else -#define SXG_GET_ADDR_LOW(_addr) (u32)_addr -#define SXG_GET_ADDR_HIGH(_addr) (u32)0 -#endif - -#define FLUSH TRUE -#define DONT_FLUSH FALSE - -#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9) -#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10) -#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11) - -extern const struct ethtool_ops sxg_nic_ethtool_ops; -#define SXG_COMPLETE_SLOW_SEND_LIMIT 128 -#endif /* __SXG_DRIVER_H__ */ diff --git a/drivers/staging/sxg/sxg_ethtool.c b/drivers/staging/sxg/sxg_ethtool.c deleted file mode 100644 index f5a0706478d..00000000000 --- a/drivers/staging/sxg/sxg_ethtool.c +++ /dev/null @@ -1,328 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg_ethtool.c - * - * The ethtool support for SXG driver for Alacritech's 10Gbe products. - * - * NOTE: This is the standard, non-accelerated version of Alacritech's - * IS-NIC driver. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sxg_os.h" -#include "sxghw.h" -#include "sxghif.h" -#include "sxg.h" - -struct sxg_nic_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; - -#define SXG_NIC_STATS(m) sizeof(((struct adapter_t *)0)->m), \ - offsetof(struct adapter_t, m) - -#define USER_VIEWABLE_EEPROM_SIZE 28 - -static struct sxg_nic_stats sxg_nic_gstrings_stats[] = { - {"xmit_ring_0_full", SXG_NIC_STATS(Stats.XmtZeroFull)}, - - /* May be will need in future */ -/* {"dumb_xmit_broadcast_packets", SXG_NIC_STATS(Stats.DumbXmtBcastPkts)}, - {"dumb_xmit_broadcast_bytes", SXG_NIC_STATS(Stats.DumbXmtBcastBytes)}, - {"dumb_xmit_unicast_packets", SXG_NIC_STATS(Stats.DumbXmtUcastPkts)}, - {"dumb_xmit_unicast_bytes", SXG_NIC_STATS(Stats.DumbXmtUcastBytes)}, -*/ - {"xmit_queue_length", SXG_NIC_STATS(Stats.XmtQLen)}, - {"memory_allocation_failure", SXG_NIC_STATS(Stats.NoMem)}, - {"Interrupts", SXG_NIC_STATS(Stats.NumInts)}, - {"false_interrupts", SXG_NIC_STATS(Stats.FalseInts)}, - {"processed_data_queue_full", SXG_NIC_STATS(Stats.PdqFull)}, - {"event_ring_full", SXG_NIC_STATS(Stats.EventRingFull)}, - {"transport_checksum_error", SXG_NIC_STATS(Stats.TransportCsum)}, - {"transport_underflow_error", SXG_NIC_STATS(Stats.TransportUflow)}, - {"transport_header_length_error", SXG_NIC_STATS(Stats.TransportHdrLen)}, - {"network_checksum_error", SXG_NIC_STATS(Stats.NetworkCsum)}, - {"network_underflow_error", SXG_NIC_STATS(Stats.NetworkUflow)}, - {"network_header_length_error", SXG_NIC_STATS(Stats.NetworkHdrLen)}, - {"receive_parity_error", SXG_NIC_STATS(Stats.Parity)}, - {"link_parity_error", SXG_NIC_STATS(Stats.LinkParity)}, - {"link/data early_error", SXG_NIC_STATS(Stats.LinkEarly)}, - {"buffer_overflow_error", SXG_NIC_STATS(Stats.LinkBufOflow)}, - {"link_code_error", SXG_NIC_STATS(Stats.LinkCode)}, - {"dribble nibble", SXG_NIC_STATS(Stats.LinkDribble)}, - {"CRC_error", SXG_NIC_STATS(Stats.LinkCrc)}, - {"link_overflow_error", SXG_NIC_STATS(Stats.LinkOflow)}, - {"link_underflow_error", SXG_NIC_STATS(Stats.LinkUflow)}, - - /* May be need in future */ -/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)}, - {"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)}, -*/ {"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)}, - {"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)}, -/* {"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)}, - {"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)}, -*/ - {"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)}, -}; - -#define SXG_NIC_STATS_LEN ARRAY_SIZE(sxg_nic_gstrings_stats) - -static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush) -{ - writel(value, reg); - if (flush) - mb(); -} - -static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg, - u64 value, u32 cpu) -{ - u32 value_high = (u32) (value >> 32); - u32 value_low = (u32) (value & 0x00000000FFFFFFFF); - unsigned long flags; - - spin_lock_irqsave(&adapter->Bit64RegLock, flags); - writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper)); - writel(value_low, reg); - spin_unlock_irqrestore(&adapter->Bit64RegLock, flags); -} - -static void -sxg_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) -{ - struct adapter_t *adapter = netdev_priv(dev); - strncpy(drvinfo->driver, sxg_driver_name, 32); - strncpy(drvinfo->version, SXG_DRV_VERSION, 32); -// strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32); - /* TODO : Read the major and minor number of firmware. Is this - * from the FLASH/EEPROM or download file ? - */ - /* LINSYS : Check if this is correct or if not find the right value - * Also check what is the right EEPROM length : EEPROM_SIZE_XFMR or EEPROM_SIZE_NO_XFMR - */ -} - -static int sxg_nic_set_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - /* No settings are applicable as we support only 10Gb/FIBRE_media */ - return -EOPNOTSUPP; -} - -static void -sxg_nic_get_strings(struct net_device *netdev, u32 stringset, u8 * data) -{ - int index; - - switch(stringset) { - case ETH_SS_TEST: - break; - case ETH_SS_STATS: - for (index = 0; index < SXG_NIC_STATS_LEN; index++) { - memcpy(data + index * ETH_GSTRING_LEN, - sxg_nic_gstrings_stats[index].stat_string, - ETH_GSTRING_LEN); - } - break; - } -} - -static void -sxg_nic_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 * data) -{ - struct adapter_t *adapter = netdev_priv(netdev); - int index; - for (index = 0; index < SXG_NIC_STATS_LEN; index++) { - char *p = (char *)adapter + - sxg_nic_gstrings_stats[index].stat_offset; - data[index] = (sxg_nic_gstrings_stats[index].sizeof_stat == - sizeof(u64)) ? *(u64 *) p : *(u32 *) p; - } -} - -static int sxg_nic_get_sset_count(struct net_device *netdev, int sset) -{ - switch (sset) { - case ETH_SS_STATS: - return SXG_NIC_STATS_LEN; - default: - return -EOPNOTSUPP; - } -} - -static int sxg_nic_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct adapter_t *adapter = netdev_priv(netdev); - - ecmd->supported = SUPPORTED_10000baseT_Full; - ecmd->autoneg = AUTONEG_ENABLE; //VSS check This - ecmd->transceiver = XCVR_EXTERNAL; //VSS check This - - /* For Fibre Channel */ - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; - - - /* Link Speed */ - if(adapter->LinkState & SXG_LINK_UP) { - ecmd->speed = SPEED_10000; //adapter->LinkSpeed; - ecmd->duplex = DUPLEX_FULL; - } - return 0; -} - -static u32 sxg_nic_get_rx_csum(struct net_device *netdev) -{ - struct adapter_t *adapter = netdev_priv(netdev); - return ((adapter->flags & SXG_RCV_IP_CSUM_ENABLED) && - (adapter->flags & SXG_RCV_TCP_CSUM_ENABLED)); -} - -static int sxg_nic_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct adapter_t *adapter = netdev_priv(netdev); - if (data) - adapter->flags |= SXG_RCV_IP_CSUM_ENABLED; - else - adapter->flags &= ~SXG_RCV_IP_CSUM_ENABLED; - /* - * We dont need to write to the card to do checksums. - * It does it anyways. - */ - return 0; -} - -static int sxg_nic_get_regs_len(struct net_device *dev) -{ - return (SXG_HWREG_MEMSIZE + SXG_UCODEREG_MEMSIZE); -} - -static void sxg_nic_get_regs(struct net_device *netdev, - struct ethtool_regs *regs, void *p) -{ - struct adapter_t *adapter = netdev_priv(netdev); - struct sxg_hw_regs *HwRegs = adapter->HwRegs; - struct sxg_ucode_regs *UcodeRegs = adapter->UcodeRegs; - u32 *buff = p; - - memset(p, 0, (sizeof(struct sxg_hw_regs)+sizeof(struct sxg_ucode_regs))); - memcpy(buff, HwRegs, sizeof(struct sxg_hw_regs)); - memcpy((buff+sizeof(struct sxg_hw_regs)), UcodeRegs, sizeof(struct sxg_ucode_regs)); -} - -static int sxg_nic_get_eeprom_len(struct net_device *netdev) -{ - return (USER_VIEWABLE_EEPROM_SIZE); -} - -static int sxg_nic_get_eeprom(struct net_device *netdev, - struct ethtool_eeprom *eeprom, u8 *bytes) -{ - struct adapter_t *adapter = netdev_priv(netdev); - struct sw_cfg_data *data; - unsigned long i, status; - dma_addr_t p_addr; - - data = pci_alloc_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), - &p_addr); - if(!data) { - /* - * We cant get even this much memory. Raise a hell - * Get out of here - */ - printk(KERN_ERR"%s : Could not allocate memory for reading \ - EEPROM\n", __func__); - return -ENOMEM; - } - - WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE); - WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0); - for(i=0; i<1000; i++) { - READ_REG(adapter->UcodeRegs[0].ConfigStat, status); - if (status != SXG_CFG_TIMEOUT) - break; - mdelay(1); /* Do we really need this */ - } - - memset(bytes, 0, eeprom->len); - memcpy(bytes, data->MacAddr[0].MacAddr, sizeof(struct sxg_config_mac)); - memcpy(bytes+6, data->AtkFru.PartNum, 6); - memcpy(bytes+12, data->AtkFru.Revision, 2); - memcpy(bytes+14, data->AtkFru.Serial, 14); - - return 0; -} - -const struct ethtool_ops sxg_nic_ethtool_ops = { - .get_settings = sxg_nic_get_settings, - .set_settings = sxg_nic_set_settings, - .get_drvinfo = sxg_nic_get_drvinfo, - .get_regs_len = sxg_nic_get_regs_len, - .get_regs = sxg_nic_get_regs, - .get_link = ethtool_op_get_link, -// .get_wol = sxg_nic_get_wol, - .get_eeprom_len = sxg_nic_get_eeprom_len, - .get_eeprom = sxg_nic_get_eeprom, -// .get_pauseparam = sxg_nic_get_pauseparam, -// .set_pauseparam = sxg_nic_set_pauseparam, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, -// .get_tso = sxg_nic_get_tso, -// .set_tso = sxg_nic_set_tso, -// .self_test = sxg_nic_diag_test, - .get_strings = sxg_nic_get_strings, - .get_ethtool_stats = sxg_nic_get_ethtool_stats, - .get_sset_count = sxg_nic_get_sset_count, - .get_rx_csum = sxg_nic_get_rx_csum, - .set_rx_csum = sxg_nic_set_rx_csum, -// .get_coalesce = sxg_nic_get_intr_coalesce, -// .set_coalesce = sxg_nic_set_intr_coalesce, -}; diff --git a/drivers/staging/sxg/sxg_os.h b/drivers/staging/sxg/sxg_os.h deleted file mode 100644 index 68e1a04b61f..00000000000 --- a/drivers/staging/sxg/sxg_os.h +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxg_os.h - * - * These are the Linux-specific definitions required for the SLICOSS - * driver, which should allow for greater portability to other OSes. - */ -#ifndef _SLIC_OS_SPECIFIC_H_ -#define _SLIC_OS_SPECIFIC_H_ - -#define FALSE (0) -#define TRUE (1) - -struct list_entry { - struct list_entry *nle_flink; - struct list_entry *nle_blink; -}; - -#define InitializeListHead(l) \ - (l)->nle_flink = (l)->nle_blink = (l) - -#define IsListEmpty(h) \ - ((h)->nle_flink == (h)) - -#define RemoveEntryList(e) \ - do { \ - list_entry *b; \ - list_entry *f; \ - \ - f = (e)->nle_flink; \ - b = (e)->nle_blink; \ - b->nle_flink = f; \ - f->nle_blink = b; \ - } while (0) - -/* These two have to be inlined since they return things. */ - -static inline struct list_entry *RemoveHeadList(struct list_entry *l) -{ - struct list_entry *f; - struct list_entry *e; - - e = l->nle_flink; - f = e->nle_flink; - l->nle_flink = f; - f->nle_blink = l; - - return (e); -} - -static inline struct list_entry *RemoveTailList(struct list_entry *l) -{ - struct list_entry *b; - struct list_entry *e; - - e = l->nle_blink; - b = e->nle_blink; - l->nle_blink = b; - b->nle_flink = l; - - return (e); -} - -#define InsertTailList(l, e) \ - do { \ - struct list_entry *b; \ - \ - b = (l)->nle_blink; \ - (e)->nle_flink = (l); \ - (e)->nle_blink = b; \ - b->nle_flink = (e); \ - (l)->nle_blink = (e); \ - } while (0) - -#define InsertHeadList(l, e) \ - do { \ - struct list_entry *f; \ - \ - f = (l)->nle_flink; \ - (e)->nle_flink = f; \ - (e)->nle_blink = l; \ - f->nle_blink = (e); \ - (l)->nle_flink = (e); \ - } while (0) - -#define ATK_DEBUG 1 - -#if ATK_DEBUG -#define SLIC_TIMESTAMP(value) { \ - struct timeval timev; \ - do_gettimeofday(&timev); \ - value = timev.tv_sec*1000000 + timev.tv_usec; \ -} -#else -#define SLIC_TIMESTAMP(value) -#endif - -/* SXG DEFINES */ - -#ifdef ATKDBG -#define SXG_TIMESTAMP(value) { \ - struct timeval timev; \ - do_gettimeofday(&timev); \ - value = timev.tv_sec*1000000 + timev.tv_usec; \ -} -#else -#define SXG_TIMESTAMP(value) -#endif - -#define WRITE_REG(reg,value,flush) \ - sxg_reg32_write((®), (value), (flush)) -#define WRITE_REG64(a,reg,value,cpu) \ - sxg_reg64_write((a),(®),(value),(cpu)) -#define READ_REG(reg,value) (value) = readl((void __iomem *)(®)) - -#endif /* _SLIC_OS_SPECIFIC_H_ */ diff --git a/drivers/staging/sxg/sxgdbg.h b/drivers/staging/sxg/sxgdbg.h deleted file mode 100644 index e613a972b3d..00000000000 --- a/drivers/staging/sxg/sxgdbg.h +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - * - * Copyright © 2000-2008 Alacritech, Inc. All rights reserved. - * - * $Id: sxgdbg.h,v 1.1 2008/06/27 12:49:28 mook Exp $ - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Alacritech, Inc. - * - **************************************************************************/ - -/* - * FILENAME: sxgdbg.h - * - * All debug and assertion-based definitions and macros are included - * in this file for the SXGOSS driver. - */ -#ifndef _SXG_DEBUG_H_ -#define _SXG_DEBUG_H_ - -#define ATKDBG 1 -#define ATK_TRACE_ENABLED 0 - -#define DBG_ERROR(n, args...) printk(KERN_WARNING n, ##args) - -#ifdef ASSERT -#undef ASSERT -#endif - -#define SXG_ASSERT_ENABLED -#ifdef SXG_ASSERT_ENABLED -#ifndef ASSERT -#define ASSERT(a) \ - { \ - if (!(a)) { \ - DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n", \ - __FILE__, __func__, __LINE__); \ - } \ - } -#endif -#else -#ifndef ASSERT -#define ASSERT(a) -#endif -#endif /* SXG_ASSERT_ENABLED */ - - -#ifdef ATKDBG -/* - * Global for timer granularity; every driver must have an instance - * of this initialized to 0 - */ - -extern ulong ATKTimerDiv; - -/* - * trace_entry - - * - * This structure defines an entry in the trace buffer. The - * first few fields mean the same from entry to entry, while - * the meaning of last several fields change to suit the - * needs of the trace entry. Typically they are function call - * parameters. - */ -struct trace_entry { - char name[8];/* 8 character name - like 's'i'm'b'a'r'c'v' */ - u32 time; /* Current clock tic */ - unsigned char cpu; /* Current CPU */ - unsigned char irql; /* Current IRQL */ - unsigned char driver;/* The driver which added the trace call */ - /* pad to 4 byte boundary - will probably get used */ - unsigned char pad2; - u32 arg1; /* Caller arg1 */ - u32 arg2; /* Caller arg2 */ - u32 arg3; /* Caller arg3 */ - u32 arg4; /* Caller arg4 */ -}; - -/* Driver types for driver field in struct trace_entry */ -#define TRACE_SXG 1 -#define TRACE_VPCI 2 -#define TRACE_SLIC 3 - -#define TRACE_ENTRIES 1024 - -struct sxg_trace_buffer { - /* aid for windbg extension */ - unsigned int size; - unsigned int in; /* Where to add */ - unsigned int level; /* Current Trace level */ - spinlock_t lock; /* For MP tracing */ - struct trace_entry entries[TRACE_ENTRIES];/* The circular buffer */ -}; - -/* - * The trace levels - * - * XXX At the moment I am only defining critical, important, and noisy. - * I am leaving room for more if anyone wants them. - */ -#define TRACE_NONE 0 /* For trace level - if no tracing wanted */ -#define TRACE_CRITICAL 1 /* minimal tracing - only critical stuff */ -#define TRACE_IMPORTANT 5 /* more tracing - anything important */ -#define TRACE_NOISY 10 /* Everything in the world */ - - -/* The macros themselves */ -#if ATK_TRACE_ENABLED -#define SXG_TRACE_INIT(buffer, tlevel) \ -{ \ - memset((buffer), 0, sizeof(struct sxg_trace_buffer)); \ - (buffer)->level = (tlevel); \ - (buffer)->size = TRACE_ENTRIES; \ - spin_lock_init(&(buffer)->lock); \ -} -#else -#define SXG_TRACE_INIT(buffer, tlevel) -#endif - -/*The trace macro. This is active only if ATK_TRACE_ENABLED is set. */ -#if ATK_TRACE_ENABLED -#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) { \ - if ((buffer) && ((buffer)->level >= (tlevel))) { \ - unsigned int trace_irql = 0;/* ?????? FIX THIS */\ - unsigned int trace_len; \ - struct trace_entry *trace_entry; \ - struct timeval timev; \ - if(spin_trylock(&(buffer)->lock)) { \ - trace_entry = &(buffer)->entries[(buffer)->in]; \ - do_gettimeofday(&timev); \ - \ - memset(trace_entry->name, 0, 8); \ - trace_len = strlen(tname); \ - trace_len = trace_len > 8 ? 8 : trace_len; \ - memcpy(trace_entry->name, (tname), trace_len); \ - trace_entry->time = timev.tv_usec; \ - trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF);\ - trace_entry->driver = (tdriver); \ - trace_entry->irql = trace_irql; \ - trace_entry->arg1 = (ulong)(a1); \ - trace_entry->arg2 = (ulong)(a2); \ - trace_entry->arg3 = (ulong)(a3); \ - trace_entry->arg4 = (ulong)(a4); \ - \ - (buffer)->in++; \ - if ((buffer)->in == TRACE_ENTRIES) \ - (buffer)->in = 0; \ - \ - spin_unlock(&(buffer)->lock); \ - } \ - } \ -} -#else -#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) -#endif - -#endif - -#endif /* _SXG_DEBUG_H_ */ diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h deleted file mode 100644 index e190d6add29..00000000000 --- a/drivers/staging/sxg/sxghif.h +++ /dev/null @@ -1,1014 +0,0 @@ -/******************************************************************* - * Copyright © 1997-2007 Alacritech, Inc. All rights reserved - * - * $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $ - * - * sxghif.h: - * - * This file contains structures and definitions for the - * Alacritech Sahara host interface - ******************************************************************/ - -#define DBG 1 - -/* UCODE Registers */ -struct sxg_ucode_regs { - /* Address 0 - 0x3F = Command codes 0-15 for TCB 0. Excode 0 */ - u32 Icr; /* Code = 0 (extended), ExCode = 0 - Int control */ - u32 RsvdReg1; /* Code = 1 - TOE -NA */ - u32 RsvdReg2; /* Code = 2 - TOE -NA */ - u32 RsvdReg3; /* Code = 3 - TOE -NA */ - u32 RsvdReg4; /* Code = 4 - TOE -NA */ - u32 RsvdReg5; /* Code = 5 - TOE -NA */ - u32 CardUp; /* Code = 6 - Microcode initialized when 1 */ - u32 RsvdReg7; /* Code = 7 - TOE -NA */ - u32 ConfigStat; /* Code = 8 - Configuration data load status */ - u32 RsvdReg9; /* Code = 9 - TOE -NA */ - u32 CodeNotUsed[6]; /* Codes 10-15 not used. ExCode = 0 */ - /* This brings us to ExCode 1 at address 0x40 = Interrupt status pointer */ - u32 Isp; /* Code = 0 (extended), ExCode = 1 */ - u32 PadEx1[15]; /* Codes 1-15 not used with extended codes */ - /* ExCode 2 = Interrupt Status Register */ - u32 Isr; /* Code = 0 (extended), ExCode = 2 */ - u32 PadEx2[15]; - /* ExCode 3 = Event base register. Location of event rings */ - u32 EventBase; /* Code = 0 (extended), ExCode = 3 */ - u32 PadEx3[15]; - /* ExCode 4 = Event ring size */ - u32 EventSize; /* Code = 0 (extended), ExCode = 4 */ - u32 PadEx4[15]; - /* ExCode 5 = TCB Buffers base address */ - u32 TcbBase; /* Code = 0 (extended), ExCode = 5 */ - u32 PadEx5[15]; - /* ExCode 6 = TCB Composite Buffers base address */ - u32 TcbCompBase; /* Code = 0 (extended), ExCode = 6 */ - u32 PadEx6[15]; - /* ExCode 7 = Transmit ring base address */ - u32 XmtBase; /* Code = 0 (extended), ExCode = 7 */ - u32 PadEx7[15]; - /* ExCode 8 = Transmit ring size */ - u32 XmtSize; /* Code = 0 (extended), ExCode = 8 */ - u32 PadEx8[15]; - /* ExCode 9 = Receive ring base address */ - u32 RcvBase; /* Code = 0 (extended), ExCode = 9 */ - u32 PadEx9[15]; - /* ExCode 10 = Receive ring size */ - u32 RcvSize; /* Code = 0 (extended), ExCode = 10 */ - u32 PadEx10[15]; - /* ExCode 11 = Read EEPROM/Flash Config */ - u32 Config; /* Code = 0 (extended), ExCode = 11 */ - u32 PadEx11[15]; - /* ExCode 12 = Multicast bits 31:0 */ - u32 McastLow; /* Code = 0 (extended), ExCode = 12 */ - u32 PadEx12[15]; - /* ExCode 13 = Multicast bits 63:32 */ - u32 McastHigh; /* Code = 0 (extended), ExCode = 13 */ - u32 PadEx13[15]; - /* ExCode 14 = Ping */ - u32 Ping; /* Code = 0 (extended), ExCode = 14 */ - u32 PadEx14[15]; - /* ExCode 15 = Link MTU */ - u32 LinkMtu; /* Code = 0 (extended), ExCode = 15 */ - u32 PadEx15[15]; - /* ExCode 16 = Download synchronization */ - u32 LoadSync; /* Code = 0 (extended), ExCode = 16 */ - u32 PadEx16[15]; - /* ExCode 17 = Upper DRAM address bits on 32-bit systems */ - u32 Upper; /* Code = 0 (extended), ExCode = 17 */ - u32 PadEx17[15]; - /* ExCode 18 = Slowpath Send Index Address */ - u32 SPSendIndex; /* Code = 0 (extended), ExCode = 18 */ - u32 PadEx18[15]; - /* ExCode 19 = Get ucode statistics */ - u32 GetUcodeStats; /* Code = 0 (extended), ExCode = 19 */ - u32 PadEx19[15]; - /* ExCode 20 = Aggregation - See sxgmisc.c:SxgSetInterruptAggregation */ - u32 Aggregation; /* Code = 0 (extended), ExCode = 20 */ - u32 PadEx20[15]; - /* ExCode 21 = Receive MDL push timer */ - u32 PushTicks; /* Code = 0 (extended), ExCode = 21 */ - u32 PadEx21[15]; - /* ExCode 22 = ACK Frequency */ - u32 AckFrequency; /* Code = 0 (extended), ExCode = 22 */ - u32 PadEx22[15]; - /* ExCode 23 = TOE NA */ - u32 RsvdReg23; - u32 PadEx23[15]; - /* ExCode 24 = TOE NA */ - u32 RsvdReg24; - u32 PadEx24[15]; - /* ExCode 25 = TOE NA */ - u32 RsvdReg25; /* Code = 0 (extended), ExCode = 25 */ - u32 PadEx25[15]; - /* ExCode 26 = Receive checksum requirements */ - u32 ReceiveChecksum; /* Code = 0 (extended), ExCode = 26 */ - u32 PadEx26[15]; - /* ExCode 27 = RSS Requirements */ - u32 Rss; /* Code = 0 (extended), ExCode = 27 */ - u32 PadEx27[15]; - /* ExCode 28 = RSS Table */ - u32 RssTable; /* Code = 0 (extended), ExCode = 28 */ - u32 PadEx28[15]; - /* ExCode 29 = Event ring release entries */ - u32 EventRelease; /* Code = 0 (extended), ExCode = 29 */ - u32 PadEx29[15]; - /* ExCode 30 = Number of receive bufferlist commands on ring 0 */ - u32 RcvCmd; /* Code = 0 (extended), ExCode = 30 */ - u32 PadEx30[15]; - /* ExCode 31 = slowpath transmit command - Data[31:0] = 1 */ - u32 XmtCmd; /* Code = 0 (extended), ExCode = 31 */ - u32 PadEx31[15]; - /* ExCode 32 = Dump command */ - u32 DumpCmd; /* Code = 0 (extended), ExCode = 32 */ - u32 PadEx32[15]; - /* ExCode 33 = Debug command */ - u32 DebugCmd; /* Code = 0 (extended), ExCode = 33 */ - u32 PadEx33[15]; - /* - * There are 128 possible extended commands - each of account for 16 - * words (including the non-relevent base command codes 1-15). - * Pad for the remainder of these here to bring us to the next CPU - * base. As extended codes are added, reduce the first array value in - * the following field - */ - u32 PadToNextCpu[94][16]; /* 94 = 128 - 34 (34 = Excodes 0 - 33)*/ -}; - -/* Interrupt control register (0) values */ -#define SXG_ICR_DISABLE 0x00000000 -#define SXG_ICR_ENABLE 0x00000001 -#define SXG_ICR_MASK 0x00000002 -#define SXG_ICR_MSGID_MASK 0xFFFF0000 -#define SXG_ICR_MSGID_SHIFT 16 -#define SXG_ICR(_MessageId, _Data) \ - ((((_MessageId) << SXG_ICR_MSGID_SHIFT) & \ - SXG_ICR_MSGID_MASK) | (_Data)) - -#define SXG_MIN_AGG_DEFAULT 0x0010 /* Minimum aggregation default */ -#define SXG_MAX_AGG_DEFAULT 0x0040 /* Maximum aggregation default */ -#define SXG_MAX_AGG_SHIFT 16 /* Maximum in top 16 bits of register */ -/* Disable interrupt aggregation on xmt */ -#define SXG_AGG_XMT_DISABLE 0x80000000 - -/* The Microcode supports up to 16 RSS queues (RevB) */ -#define SXG_MAX_RSS 16 -#define SXG_MAX_RSS_REVA 8 - -#define SXG_MAX_RSS_TABLE_SIZE 256 /* 256-byte max */ - -#define SXG_RSS_REVA_TCP6 0x00000001 /* RSS TCP over IPv6 */ -#define SXG_RSS_REVA_TCP4 0x00000002 /* RSS TCP over IPv4 */ -#define SXG_RSS_IP 0x00000001 /* RSS TCP over IPv6 */ -#define SXG_RSS_TCP 0x00000002 /* RSS TCP over IPv4 */ -#define SXG_RSS_LEGACY 0x00000004 /* Line-base interrupts */ -#define SXG_RSS_TABLE_SIZE 0x0000FF00 /* Table size mask */ - -#define SXG_RSS_TABLE_SHIFT 8 -#define SXG_RSS_BASE_CPU 0x00FF0000 /* Base CPU (not used) */ -#define SXG_RSS_BASE_SHIFT 16 - -#define SXG_RCV_IP_CSUM_ENABLED 0x00000001 /* ExCode 26 (ReceiveChecksum) */ -#define SXG_RCV_TCP_CSUM_ENABLED 0x00000002 /* ExCode 26 (ReceiveChecksum) */ - -#define SXG_XMT_CPUID_SHIFT 16 - -/* - * Status returned by ucode in the ConfigStat reg (see above) when attempted - * to load configuration data from the EEPROM/Flash. - */ -#define SXG_CFG_TIMEOUT 1 /* init value - timeout if unchanged */ -#define SXG_CFG_LOAD_EEPROM 2 /* config data loaded from EEPROM */ -#define SXG_CFG_LOAD_FLASH 3 /* config data loaded from flash */ -#define SXG_CFG_LOAD_INVALID 4 /* no valid config data found */ -#define SXG_CFG_LOAD_ERROR 5 /* hardware error */ - -#define SXG_CHECK_FOR_HANG_TIME 5 - -/* - * TCB registers - This is really the same register memory area as UCODE_REGS - * above, but defined differently. Bits 17:06 of the address define the TCB, - * which means each TCB area occupies 0x40 (64) bytes, or 16 u32S. What really - * is happening is that these registers occupy the "PadEx[15]" areas in the - * struct sxg_ucode_regs definition above - */ -struct sxg_tcb_regs { - u32 ExCode; /* Extended codes - see SXG_UCODE_REGS */ - u32 Xmt; /* Code = 1 - # of Xmt descriptors added to ring */ - u32 Rcv; /* Code = 2 - # of Rcv descriptors added to ring */ - u32 Rsvd1; /* Code = 3 - TOE NA */ - u32 Rsvd2; /* Code = 4 - TOE NA */ - u32 Rsvd3; /* Code = 5 - TOE NA */ - u32 Invalid1; /* Code = 6 - Reserved for "CardUp" see above */ - u32 Rsvd4; /* Code = 7 - TOE NA */ - u32 Invalid2; /* Code = 8 - Reserved for "ConfigStat" see above */ - u32 Rsvd5; /* Code = 9 - TOE NA */ - u32 Pad[6]; /* Codes 10-15 - Not used. */ -}; - -/*************************************************************************** - * ISR Format - * 31 0 - * _______________________________________ - * | | | | | | | | | - * |____|____|____|____|____|____|____|____| - * ^^^^ ^^^^ ^^^^ ^^^^ \ / - * ERR --|||| |||| |||| |||| ----------------- - * EVENT ---||| |||| |||| |||| | - * ----|| |||| |||| |||| |-- Crash Address - * UPC -----| |||| |||| |||| - * LEVENT -------|||| |||| |||| - * PDQF --------||| |||| |||| - * RMISS ---------|| |||| |||| - * BREAK ----------| |||| |||| - * HBEATOK ------------|||| |||| - * NOHBEAT -------------||| |||| - * ERFULL --------------|| |||| - * XDROP ---------------| |||| - * -----------------|||| - * -----------------||||--\ - * ||---|-CpuId of crash - * |----/ - ***************************************************************************/ -#define SXG_ISR_ERR 0x80000000 /* Error */ -#define SXG_ISR_EVENT 0x40000000 /* Event ring event */ -#define SXG_ISR_NONE1 0x20000000 /* Not used */ -#define SXG_ISR_UPC 0x10000000 /* Dump/debug command complete*/ -#define SXG_ISR_LINK 0x08000000 /* Link event */ -#define SXG_ISR_PDQF 0x04000000 /* Processed data queue full */ -#define SXG_ISR_RMISS 0x02000000 /* Drop - no host buf */ -#define SXG_ISR_BREAK 0x01000000 /* Breakpoint hit */ -#define SXG_ISR_PING 0x00800000 /* Heartbeat response */ -#define SXG_ISR_DEAD 0x00400000 /* Card crash */ -#define SXG_ISR_ERFULL 0x00200000 /* Event ring full */ -#define SXG_ISR_XDROP 0x00100000 /* XMT Drop - no DRAM bufs or XMT err */ -#define SXG_ISR_SPSEND 0x00080000 /* Slow send complete */ -#define SXG_ISR_CPU 0x00070000 /* Dead CPU mask */ -#define SXG_ISR_CPU_SHIFT 16 /* Dead CPU shift */ -#define SXG_ISR_CRASH 0x0000FFFF /* Crash address mask */ - -/*************************************************************************** - * Event Ring entry - * - * 31 15 0 - * .___________________.___________________. - * |<------------ Pad 0 ------------>| - * |_________|_________|_________|_________|0 0x00 - * |<------------ Pad 1 ------------>| - * |_________|_________|_________|_________|4 0x04 - * |<------------ Pad 2 ------------>| - * |_________|_________|_________|_________|8 0x08 - * |<----------- Event Word 0 ------------>| - * |_________|_________|_________|_________|12 0x0c - * |<----------- Event Word 1 ------------>| - * |_________|_________|_________|_________|16 0x10 - * |<------------- Toeplitz ------------>| - * |_________|_________|_________|_________|20 0x14 - * |<----- Length ---->|<------ TCB Id --->| - * |_________|_________|_________|_________|24 0x18 - * |<----- Status ---->|Evnt Code|Flsh Code| - * |_________|_________|_________|_________|28 0x1c - * ^ ^^^^ ^^^^ - * |- VALID |||| ||||- RBUFC - * |||| |||-- SLOWR - * |||| ||--- UNUSED - * |||| |---- FASTC - * ||||------ FASTR - * |||------- - * ||-------- - * |--------- - * - * Slowpath status: - * _______________________________________ - * |<----- Status ---->|Evnt Code|Flsh Code| - * |_________|Cmd Index|_________|_________|28 0x1c - * ^^^ ^^^^ - * ||| ||||- ISTCPIP6 - * ||| |||-- IPONLY - * ||| ||--- RCVERR - * ||| |---- IPCBAD - * |||------ TCPCBAD - * ||------- ISTCPIP - * |-------- SCERR - * - ************************************************************************/ -#pragma pack(push, 1) -struct sxg_event { - u32 Pad[1]; /* not used */ - u32 SndUna; /* SndUna value */ - u32 Resid; /* receive MDL resid */ - union { - void * HostHandle; /* Receive host handle */ - u32 Rsvd1; /* TOE NA */ - struct { - u32 NotUsed; - u32 Rsvd2; /* TOE NA */ - } Flush; - }; - u32 Toeplitz; /* RSS Toeplitz hash */ - union { - ushort Rsvd3; /* TOE NA */ - ushort HdrOffset; /* Slowpath */ - }; - ushort Length; - unsigned char Rsvd4; /* TOE NA */ - unsigned char Code; /* Event code */ - unsigned char CommandIndex; /* New ring index */ - unsigned char Status; /* Event status */ -}; -#pragma pack(pop) - -/* Event code definitions */ -#define EVENT_CODE_BUFFERS 0x01 /* Receive buffer list command (ring 0) */ -#define EVENT_CODE_SLOWRCV 0x02 /* Slowpath receive */ -#define EVENT_CODE_UNUSED 0x04 /* Was slowpath commands complete */ - -/* Status values */ -#define EVENT_STATUS_VALID 0x80 /* Entry valid */ - -/* Slowpath status */ -#define EVENT_STATUS_ERROR 0x40 /* Completed with error. Index in next byte */ -#define EVENT_STATUS_TCPIP4 0x20 /* TCPIPv4 frame */ -#define EVENT_STATUS_TCPBAD 0x10 /* Bad TCP checksum */ -#define EVENT_STATUS_IPBAD 0x08 /* Bad IP checksum */ -#define EVENT_STATUS_RCVERR 0x04 /* Slowpath receive error */ -#define EVENT_STATUS_IPONLY 0x02 /* IP frame */ -#define EVENT_STATUS_TCPIP6 0x01 /* TCPIPv6 frame */ -#define EVENT_STATUS_TCPIP 0x21 /* Combination of v4 and v6 */ - -/* - * Event ring - * Size must be power of 2, between 128 and 16k - */ -#define EVENT_RING_SIZE 4096 -#define EVENT_RING_BATCH 16 /* Hand entries back 16 at a time. */ -/* Stop processing events after 4096 (256 * 16) */ -#define EVENT_BATCH_LIMIT 256 - -struct sxg_event_ring { - struct sxg_event Ring[EVENT_RING_SIZE]; -}; - -/* TCB Buffers */ -/* Maximum number of TCBS supported by hardware/microcode */ -#define SXG_MAX_TCB 4096 -/* Minimum TCBs before we fail initialization */ -#define SXG_MIN_TCB 512 -/* - * TCB Hash - * The bucket is determined by bits 11:4 of the toeplitz if we support 4k - * offloaded connections, 10:4 if we support 2k and so on. - */ -#define SXG_TCB_BUCKET_SHIFT 4 -#define SXG_TCB_PER_BUCKET 16 -#define SXG_TCB_BUCKET_MASK 0xFF0 /* Bucket portion of TCB ID */ -#define SXG_TCB_ELEMENT_MASK 0x00F /* Element within bucket */ -#define SXG_TCB_BUCKETS 256 /* 256 * 16 = 4k */ - -#define SXG_TCB_BUFFER_SIZE 512 /* ASSERT format is correct */ - -#define SXG_TCB_RCVQ_SIZE 736 - -#define SXG_TCB_COMPOSITE_BUFFER_SIZE 1024 - -#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6) \ - (((_TcpObject)->VlanId) ? \ - ((_IPv6) ? /* Vlan frame header = yes */ \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp: \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp): \ - ((_IPv6) ? /* Vlan frame header = No */ \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp : \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp)) - -#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject) \ - (_TcpObject)->VlanId ? \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip: \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.Ip - -#define SXG_LOCATE_IP6_FRAME_HDR(TcpObject) \ - (_TcpObject)->VlanId ? \ - &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip: \ - &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip - -#if DBG -/* - * Horrible kludge to distinguish dumb-nic, slowpath, and - * fastpath traffic. Decrement the HopLimit by one - * for slowpath, two for fastpath. This assumes the limit is measurably - * greater than two, which I think is reasonable. - * Obviously this is DBG only. Maybe remove later, or #if 0 so we - * can set it when needed - */ -#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) { \ - PIPV6_HDR _Ip6FrameHdr; \ - if ((_TcpObject)->IPv6) { \ - _Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject)); \ - if (_FastPath) { \ - _Ip6FrameHdr->HopLimit = \ - (_TcpObject)->Cached.TtlOrHopLimit - 2; \ - } else { \ - _Ip6FrameHdr->HopLimit = \ - (_TcpObject)->Cached.TtlOrHopLimit - 1; \ - } \ - } \ -} -#else -/* Do nothing with free build */ -#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) -#endif - -/* Receive and transmit rings */ -#define SXG_MAX_RING_SIZE 256 -#define SXG_XMT_RING_SIZE 128 /* Start with 128 */ -#define SXG_RCV_RING_SIZE 128 /* Start with 128 */ -#define SXG_MAX_ENTRIES 4096 -#define SXG_JUMBO_RCV_RING_SIZE 32 - -/* Structure and macros to manage a ring */ -struct sxg_ring_info { - /* Where we add entries - Note unsigned char:RING_SIZE */ - unsigned char Head; - unsigned char Tail; /* Where we pull off completed entries */ - ushort Size; /* Ring size - Must be multiple of 2 */ - void * Context[SXG_MAX_RING_SIZE]; /* Shadow ring */ -}; - -#define SXG_INITIALIZE_RING(_ring, _size) { \ - (_ring).Head = 0; \ - (_ring).Tail = 0; \ - (_ring).Size = (_size); \ -} - -#define SXG_ADVANCE_INDEX(_index, _size) \ - ((_index) = ((_index) + 1) & ((_size) - 1)) -#define SXG_PREVIOUS_INDEX(_index, _size) \ - (((_index) - 1) &((_size) - 1)) -#define SXG_RING_EMPTY(_ring) ((_ring)->Head == (_ring)->Tail) -#define SXG_RING_FULL(_ring) \ - ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail) -#define SXG_RING_ADVANCE_HEAD(_ring) \ - SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size)) -#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head = \ - SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size)) -#define SXG_RING_ADVANCE_TAIL(_ring) { \ - ASSERT((_ring)->Tail != (_ring)->Head); \ - SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size)); \ -} -/* - * Set cmd to the next available ring entry, set the shadow context - * entry and advance the ring. - * The appropriate lock must be held when calling this macro - */ -#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) { \ - if(SXG_RING_FULL(_ringinfo)) { \ - (_cmd) = NULL; \ - } else { \ - (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head]; \ - (_ringinfo)->Context[(_ringinfo)->Head] = (void *)(_context);\ - SXG_RING_ADVANCE_HEAD(_ringinfo); \ - } \ -} - -/* - * Abort the previously allocated command by retreating the head. - * NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD - * and SXG_ABORT_CMD calls. - */ -#define SXG_ABORT_CMD(_ringinfo) { \ - ASSERT(!(SXG_RING_EMPTY(_ringinfo))); \ - SXG_RING_RETREAT_HEAD(_ringinfo); \ - (_ringinfo)->Context[(_ringinfo)->Head] = NULL; \ -} - -/* - * For the given ring, return a pointer to the tail cmd and context, - * clear the context and advance the tail - */ -#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) { \ - (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail]; \ - (_context) = (_ringinfo)->Context[(_ringinfo)->Tail]; \ - (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \ - SXG_RING_ADVANCE_TAIL(_ringinfo); \ -} - -/* - * For a given ring find out how much the first pointer is ahead of - * the second pointer. "ahead" recognises the fact that the ring can wrap - */ -static inline int sxg_ring_get_forward_diff (struct sxg_ring_info *ringinfo, - int a, int b) { - if ((a < 0 || a > ringinfo->Size ) || (b < 0 || b > ringinfo->Size)) - return -1; - if (a > b) /* _a is lagging _b and _b has not wrapped around */ - return (a - b); - else - return ((ringinfo->Size - (b - a))); -} - -/*************************************************************** - * Host Command Buffer - commands to INIC via the Cmd Rings - * - * 31 15 0 - * .___________________.___________________. - * |<-------------- Sgl Low -------------->| - * |_________|_________|_________|_________|0 0x00 - * |<-------------- Sgl High ------------->| - * |_________|_________|_________|_________|4 0x04 - * |<------------- Sge 0 Low ----------->| - * |_________|_________|_________|_________|8 0x08 - * |<------------- Sge 0 High ----------->| - * |_________|_________|_________|_________|12 0x0c - * |<------------ Sge 0 Length ---------->| - * |_________|_________|_________|_________|16 0x10 - * |<----------- Window Update ----------->| - * |<-------- SP 1st SGE offset ---------->| - * |_________|_________|_________|_________|20 0x14 - * |<----------- Total Length ------------>| - * |_________|_________|_________|_________|24 0x18 - * |<----- LCnt ------>|<----- Flags ----->| - * |_________|_________|_________|_________|28 0x1c - ****************************************************************/ -#pragma pack(push, 1) -struct sxg_cmd { - dma64_addr_t Sgl; /* Physical address of SGL */ - union { - struct { - dma64_addr_t FirstSgeAddress; /* Address of first SGE */ - u32 FirstSgeLength; /* Length of first SGE */ - union { - u32 Rsvd1; /* TOE NA */ - u32 SgeOffset; /* Slowpath - 2nd SGE offset */ - /* MDL completion - clobbers update */ - u32 Resid; - }; - union { - u32 TotalLength; /* Total transfer length */ - u32 Mss; /* LSO MSS */ - }; - } Buffer; - }; - union { - struct { - unsigned char Flags:4; /* slowpath flags */ - unsigned char IpHl:4; /* Ip header length (>>2) */ - unsigned char MacLen; /* Mac header len */ - } CsumFlags; - struct { - ushort Flags:4; /* slowpath flags */ - ushort TcpHdrOff:7; /* TCP */ - ushort MacLen:5; /* Mac header len */ - } LsoFlags; - ushort Flags; /* flags */ - }; - union { - ushort SgEntries; /* SG entry count including first sge */ - struct { - unsigned char Status; /* Copied from event status */ - unsigned char NotUsed; - } Status; - }; -}; -#pragma pack(pop) - -#pragma pack(push, 1) -struct vlan_hdr { - ushort VlanTci; - ushort VlanTpid; -}; -#pragma pack(pop) - -/******************************************************************** - * Slowpath Flags: - * - * - * LSS Flags: - * .--- - * /.--- TCP Large segment send - * //.--- - * ///.--- - * 3 1 1 //// - * 1 5 0 |||| - * .___________________.____________vvvv. - * | |MAC | TCP | | - * | LCnt |hlen|hdroff|Flgs| - * |___________________|||||||||||||____| - * - * - * Checksum Flags - * - * .--- - * /.--- - * //.--- Checksum TCP - * ///.--- Checksum IP - * 3 1 //// No bits - normal send - * 1 5 7 |||| - * .___________________._______________vvvv. - * | | Offload | IP | | - * | LCnt |MAC hlen |Hlen|Flgs| - * |___________________|____|____|____|____| - * - *****************************************************************/ -/* Slowpath CMD flags */ -#define SXG_SLOWCMD_CSUM_IP 0x01 /* Checksum IP */ -#define SXG_SLOWCMD_CSUM_TCP 0x02 /* Checksum TCP */ -#define SXG_SLOWCMD_LSO 0x04 /* Large segment send */ - -struct sxg_xmt_ring { - struct sxg_cmd Descriptors[SXG_XMT_RING_SIZE]; -}; - -struct sxg_rcv_ring { - struct sxg_cmd Descriptors[SXG_RCV_RING_SIZE]; -}; - -/* - * Share memory buffer types - Used to identify asynchronous - * shared memory allocation - */ -enum sxg_buffer_type { - SXG_BUFFER_TYPE_RCV, /* Receive buffer */ - SXG_BUFFER_TYPE_SGL /* SGL buffer */ -}; - -/* State for SXG buffers */ -#define SXG_BUFFER_FREE 0x01 -#define SXG_BUFFER_BUSY 0x02 -#define SXG_BUFFER_ONCARD 0x04 -#define SXG_BUFFER_UPSTREAM 0x08 - -/* - * Receive data buffers - * - * Receive data buffers are given to the Sahara card 128 at a time. - * This is accomplished by filling in a "receive descriptor block" - * with 128 "receive descriptors". Each descriptor consists of - * a physical address, which the card uses as the address to - * DMA data into, and a virtual address, which is given back - * to the host in the "HostHandle" portion of an event. - * The receive descriptor data structure is defined below - * as sxg_rcv_data_descriptor, and the corresponding block - * is defined as sxg_rcv_descriptor_block. - * - * This receive descriptor block is given to the card by filling - * in the Sgl field of a sxg_cmd entry from pAdapt->RcvRings[0] - * with the physical address of the receive descriptor block. - * - * Both the receive buffers and the receive descriptor blocks - * require additional data structures to maintain them - * on a free queue and contain other information associated with them. - * Those data structures are defined as the sxg_rcv_data_buffer_hdr - * and sxg_rcv_descriptor_block_hdr respectively. - * - * Since both the receive buffers and the receive descriptor block - * must be accessible by the card, both must be allocated out of - * shared memory. To ensure that we always have a descriptor - * block available for every 128 buffers, we allocate all of - * these resources together in a single block. This entire - * block is managed by a struct sxg_rcv_block_hdr, who's sole purpose - * is to maintain address information so that the entire block - * can be free later. - * - * Further complicating matters is the fact that the receive - * buffers must be variable in length in order to accomodate - * jumbo frame configurations. We configure the buffer - * length so that the buffer and it's corresponding struct - * sxg_rcv_data_buffer_hdr structure add up to an even - * boundary. Then we place the remaining data structures after 128 - * of them as shown in the following diagram: - * - * _________________________________________ - * | | - * | Variable length receive buffer #1 | - * |_________________________________________| - * | | - * | sxg_rcv_data_buffer_hdr #1 | - * |_________________________________________| <== Even 2k or 10k boundary - * | | - * | ... repeat 2-128 .. | - * |_________________________________________| - * | | - * | struct sxg_rcv_descriptor_block | - * | Contains sxg_rcv_data_descriptor * 128 | - * |_________________________________________| - * | | - * | struct sxg_rcv_descriptor_block_hdr | - * |_________________________________________| - * | | - * | struct sxg_rcv_block_hdr | - * |_________________________________________| - * - * Memory consumption: - * Non-jumbo: - * Buffers and sxg_rcv_data_buffer_hdr = 2k * 128 = 256k - * + struct sxg_rcv_descriptor_block = 2k - * + struct sxg_rcv_descriptor_block_hdr = ~32 - * + struct sxg_rcv_block_hdr = ~32 - * => Total = ~258k/block - * - * Jumbo: - * Buffers and sxg_rcv_data_buffer_hdr = 10k * 128 = 1280k - * + struct sxg_rcv_descriptor_block = 2k - * + struct sxg_rcv_descriptor_block_hdr = ~32 - * + struct sxg_rcv_block_hdr = ~32 - * => Total = ~1282k/block - * - */ -#define SXG_RCV_DATA_BUFFERS 8192 /* Amount to give to the card */ -#define SXG_INITIAL_RCV_DATA_BUFFERS 16384 /* Initial pool of buffers */ -/* Minimum amount and when to get more */ -#define SXG_MIN_RCV_DATA_BUFFERS 4096 -#define SXG_MAX_RCV_BLOCKS 256 /* = 32k receive buffers */ -/* Amount to give to the card in case of jumbo frames */ -#define SXG_JUMBO_RCV_DATA_BUFFERS 2048 -/* Initial pool of buffers in case of jumbo buffers */ -#define SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS 4096 -#define SXG_MIN_JUMBO_RCV_DATA_BUFFERS 1024 - -/* Receive buffer header */ -struct sxg_rcv_data_buffer_hdr { - dma64_addr_t PhysicalAddress; /* Buffer physical address */ - /* - * Note - DO NOT USE the VirtualAddress field to locate data. - * Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead. - */ - struct list_entry FreeList; /* Free queue of buffers */ - unsigned char State; /* See SXG_BUFFER state above */ - struct sk_buff * skb; /* Double mapped (nbl and pkt)*/ -}; - -/* - * SxgSlowReceive uses the PACKET (skb) contained - * in the struct sxg_rcv_data_buffer_hdr when indicating dumb-nic data - */ -#define SxgDumbRcvPacket skb - -/* Space for struct sxg_rcv_data_buffer_hdr */ -#define SXG_RCV_DATA_HDR_SIZE sizeof(struct sxg_rcv_data_buffer_hdr) -/* Non jumbo = 2k including HDR */ -#define SXG_RCV_DATA_BUFFER_SIZE 2048 -/* jumbo = 10k including HDR */ -#define SXG_RCV_JUMBO_BUFFER_SIZE 10240 - -/* Receive data descriptor */ -struct sxg_rcv_data_descriptor { - union { - struct sk_buff *VirtualAddress; /* Host handle */ - u64 ForceTo8Bytes; /*Force x86 to 8-byte boundary*/ - }; - dma64_addr_t PhysicalAddress; -}; - -/* Receive descriptor block */ -#define SXG_RCV_DESCRIPTORS_PER_BLOCK 128 -#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 /* For sanity check */ - -struct sxg_rcv_descriptor_block { - struct sxg_rcv_data_descriptor Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK]; -}; - -/* Receive descriptor block header */ -struct sxg_rcv_descriptor_block_hdr { - void *VirtualAddress; /* start of 2k buffer */ - dma64_addr_t PhysicalAddress;/* and it's physical address */ - struct list_entry FreeList;/* free queue of descriptor blocks */ - unsigned char State; /* see sxg_buffer state above */ -}; - -/* Receive block header */ -struct sxg_rcv_block_hdr { - void *VirtualAddress; /* Start of virtual memory */ - dma64_addr_t PhysicalAddress;/* ..and it's physical address*/ - struct list_entry AllList; /* Queue of all SXG_RCV_BLOCKS*/ -}; - -/* Macros to determine data structure offsets into receive block */ -#define SXG_RCV_BLOCK_SIZE(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block)) + \ - (sizeof(struct sxg_rcv_descriptor_block_hdr)) + \ - (sizeof(struct sxg_rcv_block_hdr))) -#define SXG_RCV_BUFFER_DATA_SIZE(_Buffersize) \ - ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE) -#define SXG_RCV_DATA_BUFFER_HDR_OFFSET(_Buffersize) \ - ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE) -#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \ - ((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) -#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block))) -#define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize) \ - (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \ - (sizeof(struct sxg_rcv_descriptor_block)) + \ - (sizeof(struct sxg_rcv_descriptor_block_hdr))) - -/* Scatter gather list buffer */ -#define SXG_INITIAL_SGL_BUFFERS 8192 /* Initial pool of SGL buffers */ -#define SXG_MIN_SGL_BUFFERS 2048 /* Minimum amount and when to get more*/ -/* Maximum to allocate (note ADAPT:ushort) */ -#define SXG_MAX_SGL_BUFFERS 16384 - -/* - * SXG_SGL_POOL_PROPERTIES - This structure is used to define a pool of SGL - * buffers. These buffers are allocated out of shared memory and used to - * contain a physical scatter gather list structure that is shared - * with the card. - * - * We split our SGL buffers into multiple pools based on size. The motivation - * is that some applications perform very large I/Os (1MB for example), so - * we need to be able to allocate an SGL to accommodate such a request. - * But such an SGL would require 256 24-byte SG entries - ~6k. - * Given that the vast majority of I/Os are much smaller than 1M, allocating - * a single pool of SGL buffers would be a horribly inefficient use of - * memory. - * - * The following structure includes two fields relating to its size. - * The NBSize field specifies the largest NET_BUFFER that can be handled - * by the particular pool. The SGEntries field defines the size, in - * entries, of the SGL for that pool. The SGEntries is determined by - * dividing the NBSize by the expected page size (4k), and then padding - * it by some appropriate amount as insurance (20% or so..??). - */ -struct sxg_sgl_pool_properties { - u32 NBSize; /* Largest NET_BUFFER size for this pool */ - ushort SGEntries; /* Number of entries in SGL */ - ushort InitialBuffers; /* Number to allocate at initializationtime */ - ushort MinBuffers; /* When to get more */ - ushort MaxBuffers; /* When to stop */ - ushort PerCpuThreshold;/* See sxgh.h:SXG_RESOURCES */ -}; - -/* - * At the moment I'm going to statically initialize 4 pools: - * 100k buffer pool: The vast majority of the expected buffers are expected - * to be less than or equal to 100k. At 30 entries per and - * 8k initial buffers amounts to ~4MB of memory - * NOTE - This used to be 64K with 20 entries, but during - * WHQL NDIS 6.0 Testing (2c_mini6stress) MS does their - * best to send absurd NBL's with ridiculous SGLs, we - * have received 400byte sends contained in SGL's that - * have 28 entries - * 1M buffer pool: Buffers between 64k and 1M. Allocate 256 initial - * buffers with 300 entries each => ~2MB of memory - * 5M buffer pool: Not expected often, if at all. 32 initial buffers - * at 1500 entries each => ~1MB of memory - * 10M buffer pool: Not expected at all, except under pathelogical conditions. - * Allocate one at initialization time. - * Note - 10M is the current limit of what we can realistically - * support due to the sahara SGL bug described in the - * SAHARA SGL WORKAROUND below. We will likely adjust the - * number of pools and/or pool properties over time. - */ -#define SXG_NUM_SGL_POOLS 4 -#define INITIALIZE_SGL_POOL_PROPERTIES \ -struct sxg_sgl_pool_properties SxgSglPoolProperties[SXG_NUM_SGL_POOLS] =\ -{ \ - { 102400, 30, 8192, 2048, 16384, 256}, \ - { 1048576, 300, 256, 128, 1024, 16}, \ - { 5252880, 1500, 32, 16, 512, 0}, \ - {10485760, 2700, 2, 4, 32, 0}, \ -}; - -extern struct sxg_sgl_pool_properties SxgSglPoolProperties[]; - -#define SXG_MAX_SGL_BUFFER_SIZE \ - SxgSglPoolProperties[SXG_NUM_SGL_POOLS - 1].NBSize - -/* - * SAHARA SGL WORKAROUND!! - * The current Sahara card uses a 16-bit counter when advancing - * SGL address locations. This means that if an SGL crosses - * a 64k boundary, the hardware will actually skip back to - * the start of the previous 64k boundary, with obviously - * undesirable results. - * - * We currently workaround this issue by allocating SGL buffers - * in 64k blocks and skipping over buffers that straddle the boundary. - */ -#define SXG_INVALID_SGL(phys_addr,len) \ - (((phys_addr >> 16) != ( (phys_addr + len) >> 16 ))) - -/* - * Allocate SGLs in blocks so we can skip over invalid entries. - * We allocation 64k worth of SGL buffers, including the - * struct sxg_sgl_block_hdr, plus one for padding - */ -#define SXG_SGL_BLOCK_SIZE 65536 -#define SXG_SGL_ALLOCATION_SIZE(_Pool) \ - SXG_SGL_BLOCK_SIZE + SXG_SGL_SIZE(_Pool) - -struct sxg_sgl_block_hdr { - ushort Pool; /* Associated SGL pool */ - /* struct sxg_scatter_gather blocks */ - struct list_entry List; - dma64_addr_t PhysicalAddress;/* physical address */ -}; - -/* - * The following definition denotes the maximum block of memory that the - * card can DMA to.It is specified in the call to NdisMRegisterScatterGatherDma. - * For now, use the same value as used in the Slic/Oasis driver, which - * is 128M. That should cover any expected MDL that I can think of. - */ -#define SXG_MAX_PHYS_MAP (1024 * 1024 * 128) - -/* Self identifying structure type */ -enum SXG_SGL_TYPE { - SXG_SGL_DUMB, /* Dumb NIC SGL */ - SXG_SGL_SLOW, /* Slowpath protocol header - see below */ - SXG_SGL_CHIMNEY /* Chimney offload SGL */ -}; - -/* - * The ucode expects an NDIS SGL structure that - * is formatted for an x64 system. When running - * on an x64 system, we can simply hand the NDIS SGL - * to the card directly. For x86 systems we must reconstruct - * the SGL. The following structure defines an x64 - * formatted SGL entry - */ -struct sxg_x64_sge { - dma64_addr_t Address; /* same as wdm.h */ - u32 Length; /* same as wdm.h */ - u32 CompilerPad; /* The compiler pads to 8-bytes */ - u64 Reserved; /* u32 * in wdm.h. Force to 8 bytes */ -}; - -/* - * Our SGL structure - Essentially the same as - * wdm.h:SCATTER_GATHER_LIST. Note the variable number of - * elements based on the pool specified above - */ -struct sxg_x64_sgl { - u32 NumberOfElements; - u32 *Reserved; - struct sxg_x64_sge Elements[1]; /* Variable */ -}; - -struct sxg_scatter_gather { - enum SXG_SGL_TYPE Type; /* FIRST! Dumb-nic or offload */ - ushort Pool; /* Associated SGL pool */ - ushort Entries; /* SGL total entries */ - void * adapter; /* Back pointer to adapter */ - /* Free struct sxg_scatter_gather blocks */ - struct list_entry FreeList; - /* All struct sxg_scatter_gather blocks */ - struct list_entry AllList; - dma64_addr_t PhysicalAddress;/* physical address */ - unsigned char State; /* See SXG_BUFFER state above */ - unsigned char CmdIndex; /* Command ring index */ - struct sk_buff *DumbPacket; /* Associated Packet */ - /* For asynchronous completions */ - u32 Direction; - u32 CurOffset; /* Current SGL offset */ - u32 SglRef; /* SGL reference count */ - struct vlan_hdr VlanTag; /* VLAN tag to be inserted into SGL */ - struct sxg_x64_sgl *pSgl; /* SGL Addr. Possibly &Sgl */ - struct sxg_x64_sgl Sgl; /* SGL handed to card */ -}; - -/* - * Note - the "- 1" is because struct sxg_scatter_gather=>struct sxg_x64_sgl - * includes 1 SGE.. - */ -#define SXG_SGL_SIZE(_Pool) \ - (sizeof(struct sxg_scatter_gather) + \ - ((SxgSglPoolProperties[_Pool].SGEntries - 1) * \ - sizeof(struct sxg_x64_sge))) - -/* Force NDIS to give us it's own buffer so we can reformat to our own */ -#define SXG_SGL_BUFFER(_SxgSgl) NULL -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0 -#define SXG_SGL_BUF_SIZE 0 - -/* -#if defined(CONFIG_X86_64) -#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl) -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) ((_SxgSgl)->Entries * \ - sizeof(struct sxg_x64_sge)) -#define SXG_SGL_BUF_SIZE sizeof(struct sxg_x64_sgl) -#elif defined(CONFIG_X86) -// Force NDIS to give us it's own buffer so we can reformat to our own -#define SXG_SGL_BUFFER(_SxgSgl) NULL -#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0 -#define SXG_SGL_BUF_SIZE 0 -#else -#error staging: sxg: driver is for X86 only! -#endif -*/ -/* Microcode statistics */ -struct sxg_ucode_stats { - u32 RPDQOflow; /* PDQ overflow (unframed ie dq & drop 1st) */ - u32 XDrops; /* Xmt drops due to no xmt buffer */ - u32 ERDrops; /* Rcv drops due to ER full */ - u32 NBDrops; /* Rcv drops due to out of host buffers */ - u32 PQDrops; /* Rcv drops due to PDQ full */ - /* Rcv drops due to bad frame: no link addr match, frlen > max */ - u32 BFDrops; - u32 UPDrops; /* Rcv drops due to UPFq full */ - u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */ -}; - -/* - * Macros for handling the Offload engine values - */ -/* Number of positions to shift Network Header Length before passing to card */ -#define SXG_NW_HDR_LEN_SHIFT 2 diff --git a/drivers/staging/sxg/sxghw.h b/drivers/staging/sxg/sxghw.h deleted file mode 100644 index 81f81d4b0ad..00000000000 --- a/drivers/staging/sxg/sxghw.h +++ /dev/null @@ -1,1020 +0,0 @@ -/************************************************************* - * Copyright © 1997-2007 Alacritech, Inc. All rights reserved - * - * $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $ - * - * sxghw.h: - * - * This file contains structures and definitions for the - * Alacritech Sahara hardware - * - **********************************************************/ - - -/* PCI Configuration space */ -/* PCI Vendor ID */ -#define SXG_VENDOR_ID 0x139A /* Alacritech's Vendor ID */ - -/* PCI Device ID */ -#define SXG_DEVICE_ID 0x0009 /* Sahara Device ID */ - - -/* Type of ASIC in use */ -enum asic_type { - SAHARA_REV_A, - SAHARA_REV_B -}; - -/* Type of Xcvr in fiber card */ -enum xcvr_type { - XCVR_UNKNOWN, - XCVR_NONE, - XCVR_SR, - XCVR_LR, - XCVR_LRM, - XCVR_CR -}; -/* - * Subsystem IDs. - * - * The subsystem ID value is broken into bit fields as follows: - * Bits [15:12] - Function - * Bits [11:8] - OEM and/or operating system. - * Bits [7:0] - Base SID. - */ - -/* SSID field (bit) masks */ -#define SSID_BASE_MASK 0x00FF /* Base subsystem ID mask */ -#define SSID_OEM_MASK 0x0F00 /* Subsystem OEM mask */ -#define SSID_FUNC_MASK 0xF000 /* Subsystem function mask */ - -/* Base SSID's */ -/* 100022 Sahara prototype (XenPak) board */ -#define SSID_SAHARA_PROTO 0x0018 -#define SSID_SAHARA_FIBER 0x0019 /* 100023 Sahara 1-port fiber board */ -#define SSID_SAHARA_COPPER 0x001A /* 100024 Sahara 1-port copper board */ - -/* Useful SSID macros */ -/* isolate base SSID bits */ -#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK) -/* isolate SSID OEM bits */ -#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK) -/* isolate SSID function bits */ -#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK) - - -/* HW Register Space */ -#define SXG_HWREG_MEMSIZE 0x4000 /* 16k */ - -#pragma pack(push, 1) -struct sxg_hw_regs { - u32 Reset; /* Write 0xdead to invoke soft reset */ - u32 Pad1; /* No register defined at offset 4 */ - u32 InterruptMask0; /* Deassert legacy interrupt on function 0 */ - u32 InterruptMask1; /* Deassert legacy interrupt on function 1 */ - u32 UcodeDataLow; /* Store microcode instruction bits 31-0 */ - u32 UcodeDataMiddle; /* Store microcode instruction bits 63-32 */ - u32 UcodeDataHigh; /* Store microcode instruction bits 95-64 */ - u32 UcodeAddr; /* Store microcode address - See flags below */ - u32 PadTo0x80[24]; /* Pad to Xcv configuration registers */ - u32 MacConfig0; /* 0x80 - AXGMAC Configuration Register 0 */ - u32 MacConfig1; /* 0x84 - AXGMAC Configuration Register 1 */ - u32 MacConfig2; /* 0x88 - AXGMAC Configuration Register 2 */ - u32 MacConfig3; /* 0x8C - AXGMAC Configuration Register 3 */ - u32 MacAddressLow; /* 0x90 - AXGMAC MAC Station Address - octets 1-4 */ - u32 MacAddressHigh; /* 0x94 - AXGMAC MAC Station Address - octets 5-6 */ - u32 MacReserved1[2]; /* 0x98 - AXGMAC Reserved */ - u32 MacMaxFrameLen; /* 0xA0 - AXGMAC Maximum Frame Length */ - u32 MacReserved2[2]; /* 0xA4 - AXGMAC Reserved */ - u32 MacRevision; /* 0xAC - AXGMAC Revision Level Register */ - u32 MacReserved3[4]; /* 0xB0 - AXGMAC Reserved */ - u32 MacAmiimCmd; /* 0xC0 - AXGMAC AMIIM Command Register */ - u32 MacAmiimField; /* 0xC4 - AXGMAC AMIIM Field Register */ - u32 MacAmiimConfig; /* 0xC8 - AXGMAC AMIIM Configuration Register */ - u32 MacAmiimLink; /* 0xCC - AXGMAC AMIIM Link Fail Vector Register */ - u32 MacAmiimIndicator; /* 0xD0 - AXGMAC AMIIM Indicator Registor */ - u32 PadTo0x100[11]; /* 0xD4 - 0x100 - Pad */ - u32 XmtConfig; /* 0x100 - Transmit Configuration Register */ - u32 RcvConfig; /* 0x104 - Receive Configuration Register 1 */ - u32 LinkAddress0Low; /* 0x108 - Link address 0 */ - u32 LinkAddress0High; /* 0x10C - Link address 0 */ - u32 LinkAddress1Low; /* 0x110 - Link address 1 */ - u32 LinkAddress1High; /* 0x114 - Link address 1 */ - u32 LinkAddress2Low; /* 0x118 - Link address 2 */ - u32 LinkAddress2High; /* 0x11C - Link address 2 */ - u32 LinkAddress3Low; /* 0x120 - Link address 3 */ - u32 LinkAddress3High; /* 0x124 - Link address 3 */ - u32 ToeplitzKey[10]; /* 0x128 - 0x150 - Toeplitz key */ - u32 SocketKey[10]; /* 0x150 - 0x178 - Socket Key */ - u32 LinkStatus; /* 0x178 - Link status */ - u32 ClearStats; /* 0x17C - Clear Stats */ - u32 XmtErrorsLow; /* 0x180 - Transmit stats - errors */ - u32 XmtErrorsHigh; /* 0x184 - Transmit stats - errors */ - u32 XmtFramesLow; /* 0x188 - Transmit stats - frame count */ - u32 XmtFramesHigh; /* 0x18C - Transmit stats - frame count */ - u32 XmtBytesLow; /* 0x190 - Transmit stats - byte count */ - u32 XmtBytesHigh; /* 0x194 - Transmit stats - byte count */ - u32 XmtTcpSegmentsLow; /* 0x198 - Transmit stats - TCP segments */ - u32 XmtTcpSegmentsHigh; /* 0x19C - Transmit stats - TCP segments */ - u32 XmtTcpBytesLow; /* 0x1A0 - Transmit stats - TCP bytes */ - u32 XmtTcpBytesHigh; /* 0x1A4 - Transmit stats - TCP bytes */ - u32 RcvErrorsLow; /* 0x1A8 - Receive stats - errors */ - u32 RcvErrorsHigh; /* 0x1AC - Receive stats - errors */ - u32 RcvFramesLow; /* 0x1B0 - Receive stats - frame count */ - u32 RcvFramesHigh; /* 0x1B4 - Receive stats - frame count */ - u32 RcvBytesLow; /* 0x1B8 - Receive stats - byte count */ - u32 RcvBytesHigh; /* 0x1BC - Receive stats - byte count */ - u32 RcvTcpSegmentsLow; /* 0x1C0 - Receive stats - TCP segments */ - u32 RcvTcpSegmentsHigh; /* 0x1C4 - Receive stats - TCP segments */ - u32 RcvTcpBytesLow; /* 0x1C8 - Receive stats - TCP bytes */ - u32 RcvTcpBytesHigh; /* 0x1CC - Receive stats - TCP bytes */ - u32 PadTo0x200[12]; /* 0x1D0 - 0x200 - Pad */ - u32 Software[1920]; /* 0x200 - 0x2000 - Software defined (not used) */ - u32 MsixTable[1024]; /* 0x2000 - 0x3000 - MSIX Table */ - u32 MsixBitArray[1024]; /* 0x3000 - 0x4000 - MSIX Pending Bit Array */ -}; -#pragma pack(pop) - -/* Microcode Address Flags */ -#define MICROCODE_ADDRESS_GO 0x80000000 /* Start microcode */ -#define MICROCODE_ADDRESS_WRITE 0x40000000 /* Store microcode */ -#define MICROCODE_ADDRESS_READ 0x20000000 /* Read microcode */ -#define MICROCODE_ADDRESS_PARITY 0x10000000/* Parity error detected */ -#define MICROCODE_ADDRESS_MASK 0x00001FFF /* Address bits */ - -/* Link Address Registers */ -/* Applied to link address high */ -#define LINK_ADDRESS_ENABLE 0x80000000 - -/* Microsoft register space size */ -#define SXG_UCODEREG_MEMSIZE 0x40000 /* 256k */ - -/* - * Sahara microcode register address format. The command code, - * extended command code, and associated processor are encoded in - * the address bits as follows - */ -#define SXG_ADDRESS_CODE_SHIFT 2 /* Base command code */ -#define SXG_ADDRESS_CODE_MASK 0x0000003C -/* Extended (or sub) command code */ -#define SXG_ADDRESS_EXCODE_SHIFT 6 -#define SXG_ADDRESS_EXCODE_MASK 0x00001FC0 -#define SXG_ADDRESS_CPUID_SHIFT 13 /* CPU */ -#define SXG_ADDRESS_CPUID_MASK 0x0003E000 -/* Used to sanity check UCODE_REGS structure */ -#define SXG_REGISTER_SIZE_PER_CPU 0x00002000 - -/* Sahara receive sequencer status values */ -#define SXG_RCV_STATUS_ATTN 0x80000000 /* Attention */ -#define SXG_RCV_STATUS_TRANSPORT_MASK 0x3F000000 /* Transport mask */ -#define SXG_RCV_STATUS_TRANSPORT_ERROR 0x20000000 /* Transport error */ -/* Transport cksum error */ -#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000 -/* Transport underflow */ -#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000 - /* Transport header length */ -#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000 -/* Transport flags detected */ -#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000 - /* Transport options detected */ -#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000 -#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK 0x07000000 /* Transport DDP */ -#define SXG_RCV_STATUS_TRANSPORT_DDP 0x06000000 /* Transport DDP */ -#define SXG_RCV_STATUS_TRANSPORT_iSCSI 0x05000000 /* Transport iSCSI */ -#define SXG_RCV_STATUS_TRANSPORT_NFS 0x04000000 /* Transport NFS */ -#define SXG_RCV_STATUS_TRANSPORT_FTP 0x03000000 /* Transport FTP */ -#define SXG_RCV_STATUS_TRANSPORT_HTTP 0x02000000 /* Transport HTTP */ -#define SXG_RCV_STATUS_TRANSPORT_SMB 0x01000000 /* Transport SMB */ -#define SXG_RCV_STATUS_NETWORK_MASK 0x00FF0000 /* Network mask */ -#define SXG_RCV_STATUS_NETWORK_ERROR 0x00800000 /* Network error */ -/* Network cksum error */ -#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000 -/* Network underflow error */ -#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000 - /* Network header length */ -#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000 - /* Network overflow detected */ -#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000 -/* Network multicast detected */ -#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000 -/* Network options detected */ -#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000 -/* Network offset detected */ -#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000 -/* Network fragment detected */ -#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000 -/* Network transport type mask */ -#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000 -#define SXG_RCV_STATUS_NETWORK_UDP 0x00020000 /* UDP */ -#define SXG_RCV_STATUS_NETWORK_TCP 0x00010000 /* TCP */ -#define SXG_RCV_STATUS_IPONLY 0x00008000 /* IP-only not TCP */ -/* Receive priority */ -#define SXG_RCV_STATUS_PKT_PRI 0x00006000 -/* Receive priority shift */ -#define SXG_RCV_STATUS_PKT_PRI_SHFT 13 -/* MAC Receive RAM parity error */ -#define SXG_RCV_STATUS_PARITY 0x00001000 -/* Link address detection mask */ -#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00 - -#define SXG_RCV_STATUS_ADDRESS_D 0x00000B00 /* Link address D */ -#define SXG_RCV_STATUS_ADDRESS_C 0x00000A00 /* Link address C */ -#define SXG_RCV_STATUS_ADDRESS_B 0x00000900 /* Link address B */ -#define SXG_RCV_STATUS_ADDRESS_A 0x00000800 /* Link address A */ -/* Link address broadcast */ -#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300 - /* Link address multicast */ -#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200 -/* Link control multicast */ -#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100 -/* Link status mask */ -#define SXG_RCV_STATUS_LINK_MASK 0x000000FF -#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 /* Link error */ -/* Link status mask */ -#define SXG_RCV_STATUS_LINK_MASK 0x000000FF -/* RcvMacQ parity error */ -#define SXG_RCV_STATUS_LINK_PARITY 0x00000087 -#define SXG_RCV_STATUS_LINK_EARLY 0x00000086 /* Data early */ -#define SXG_RCV_STATUS_LINK_BUFOFLOW 0x00000085 /* Buffer overflow */ -#define SXG_RCV_STATUS_LINK_CODE 0x00000084 /* Link code error */ -#define SXG_RCV_STATUS_LINK_DRIBBLE 0x00000083 /* Dribble nibble */ -#define SXG_RCV_STATUS_LINK_CRC 0x00000082 /* CRC error */ -#define SXG_RCV_STATUS_LINK_OFLOW 0x00000081 /* Link overflow */ -#define SXG_RCV_STATUS_LINK_UFLOW 0x00000080 /* Link underflow */ -#define SXG_RCV_STATUS_LINK_8023 0x00000020 /* 802.3 */ -#define SXG_RCV_STATUS_LINK_SNAP 0x00000010 /* Snap */ -#define SXG_RCV_STATUS_LINK_VLAN 0x00000008 /* VLAN */ -/* Network type mask */ -#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007 -#define SXG_RCV_STATUS_LINK_CONTROL 0x00000003 /* Control packet */ -#define SXG_RCV_STATUS_LINK_IPV6 0x00000002 /* IPv6 packet */ -#define SXG_RCV_STATUS_LINK_IPV4 0x00000001 /* IPv4 packet */ - -/* Sahara receive and transmit configuration registers */ -/* RcvConfig register reset */ -#define RCV_CONFIG_RESET 0x80000000 -/* Enable the receive logic */ -#define RCV_CONFIG_ENABLE 0x40000000 -/* Enable the receive parser */ -#define RCV_CONFIG_ENPARSE 0x20000000 -/* Enable the socket detector */ -#define RCV_CONFIG_SOCKET 0x10000000 -#define RCV_CONFIG_RCVBAD 0x08000000 /* Receive all bad frames */ -/* Receive all control frames */ -#define RCV_CONFIG_CONTROL 0x04000000 -/* Enable pause transmit when attn */ -#define RCV_CONFIG_RCVPAUSE 0x02000000 -/* Include TCP port w/ IPv6 toeplitz */ -#define RCV_CONFIG_TZIPV6 0x01000000 -/* Include TCP port w/ IPv4 toeplitz */ -#define RCV_CONFIG_TZIPV4 0x00800000 -#define RCV_CONFIG_FLUSH 0x00400000 /* Flush buffers */ -#define RCV_CONFIG_PRIORITY_MASK 0x00300000 /* Priority level */ -#define RCV_CONFIG_CONN_MASK 0x000C0000 /* Number of connections */ -#define RCV_CONFIG_CONN_4K 0x00000000 /* 4k connections */ -#define RCV_CONFIG_CONN_2K 0x00040000 /* 2k connections */ -#define RCV_CONFIG_CONN_1K 0x00080000 /* 1k connections */ -#define RCV_CONFIG_CONN_512 0x000C0000 /* 512 connections */ -#define RCV_CONFIG_HASH_MASK 0x00030000 /* Hash depth */ -#define RCV_CONFIG_HASH_8 0x00000000 /* Hash depth 8 */ -#define RCV_CONFIG_HASH_16 0x00010000 /* Hash depth 16 */ -#define RCV_CONFIG_HASH_4 0x00020000 /* Hash depth 4 */ -#define RCV_CONFIG_HASH_2 0x00030000 /* Hash depth 2 */ -/* Buffer length bits 15:4. ie multiple of 16. */ -#define RCV_CONFIG_BUFLEN_MASK 0x0000FFE0 -/* Disable socket detection on attn */ -#define RCV_CONFIG_SKT_DIS 0x00000008 -#define RCV_CONFIG_HIPRICTL 0x00000002 /* Ctrl frames on high-prioirty RcvQ */ -#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */ -/* - * Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size. - * We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC, - * and round up to nearest 32 byte boundary - */ -#define RCV_CONFIG_BUFSIZE(_MaxFrame) \ - ((((_MaxFrame) + 22) + 31) & RCV_CONFIG_BUFLEN_MASK) - -/* XmtConfig register reset */ -#define XMT_CONFIG_RESET 0x80000000 -#define XMT_CONFIG_ENABLE 0x40000000 /* Enable transmit logic */ -/* Inhibit MAC RAM parity error */ -#define XMT_CONFIG_MAC_PARITY 0x20000000 -/* Inhibit D2F buffer parity error */ -#define XMT_CONFIG_BUF_PARITY 0x10000000 -/* Inhibit 1T SRAM parity error */ -#define XMT_CONFIG_MEM_PARITY 0x08000000 -#define XMT_CONFIG_INVERT_PARITY 0x04000000 /* Invert MAC RAM parity */ -#define XMT_CONFIG_INITIAL_IPID 0x0000FFFF /* Initial IPID */ - -/* - * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the struct sxg_hw_regs - * - * Full register descriptions can be found in axgmac.pdf - */ -/* A-XGMAC Configuration Register 0 */ -#define AXGMAC_CFG0_SUB_RESET 0x80000000 /* Sub module reset */ -#define AXGMAC_CFG0_RCNTRL_RESET 0x00400000 /* Receive control reset */ -#define AXGMAC_CFG0_RFUNC_RESET 0x00200000 /* Receive function reset */ -#define AXGMAC_CFG0_TCNTRL_RESET 0x00040000 /* Transmit control reset */ -#define AXGMAC_CFG0_TFUNC_RESET 0x00020000 /* Transmit function reset */ -#define AXGMAC_CFG0_MII_RESET 0x00010000 /* MII Management reset */ - -/* A-XGMAC Configuration Register 1 */ -/* Allow the sending of Pause frames */ -#define AXGMAC_CFG1_XMT_PAUSE 0x80000000 -#define AXGMAC_CFG1_XMT_EN 0x40000000 /* Enable transmit */ -/* Allow the detection of Pause frames */ -#define AXGMAC_CFG1_RCV_PAUSE 0x20000000 -#define AXGMAC_CFG1_RCV_EN 0x10000000 /* Enable receive */ -/* Current transmit state - READ ONLY */ -#define AXGMAC_CFG1_XMT_STATE 0x04000000 -/* Current receive state - READ ONLY */ -#define AXGMAC_CFG1_RCV_STATE 0x01000000 -/* Only pause for 64 slot on XOFF */ -#define AXGMAC_CFG1_XOFF_SHORT 0x00001000 -/* Delay transmit FCS 1 4-byte word */ -#define AXGMAC_CFG1_XMG_FCS1 0x00000400 -/* Delay transmit FCS 2 4-byte words */ -#define AXGMAC_CFG1_XMG_FCS2 0x00000800 -/* Delay transmit FCS 3 4-byte words */ -#define AXGMAC_CFG1_XMG_FCS3 0x00000C00 -/* Delay receive FCS 1 4-byte word */ -#define AXGMAC_CFG1_RCV_FCS1 0x00000100 -/* Delay receive FCS 2 4-byte words */ -#define AXGMAC_CFG1_RCV_FCS2 0x00000200 -/* Delay receive FCS 3 4-byte words */ -#define AXGMAC_CFG1_RCV_FCS3 0x00000300 -/* Per-packet override enable */ -#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080 -#define AXGMAC_CFG1_SWAP 0x00000040 /* Byte swap enable */ -/* ASSERT srdrpfrm on short frame (<64) */ -#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020 -/* RCV only 802.3AE when CLEAR */ -#define AXGMAC_CFG1_RCV_STRICT 0x00000010 -#define AXGMAC_CFG1_CHECK_LEN 0x00000008 /* Verify frame length */ -#define AXGMAC_CFG1_GEN_FCS 0x00000004 /* Generate FCS */ -#define AXGMAC_CFG1_PAD_MASK 0x00000003 /* Mask for pad bits */ -#define AXGMAC_CFG1_PAD_64 0x00000001 /* Pad frames to 64 bytes */ -/* Detect VLAN and pad to 68 bytes */ -#define AXGMAC_CFG1_PAD_VLAN 0x00000002 -#define AXGMAC_CFG1_PAD_68 0x00000003 /* Pad to 68 bytes */ - -/* A-XGMAC Configuration Register 2 */ -/* Generate single pause frame (test) */ -#define AXGMAC_CFG2_GEN_PAUSE 0x80000000 -/* Manual link fault sequence */ -#define AXGMAC_CFG2_LF_MANUAL 0x08000000 -/* Auto link fault sequence */ -#define AXGMAC_CFG2_LF_AUTO 0x04000000 -/* Remote link fault (READ ONLY) */ -#define AXGMAC_CFG2_LF_REMOTE 0x02000000 -/* Local link fault (READ ONLY) */ -#define AXGMAC_CFG2_LF_LOCAL 0x01000000 -#define AXGMAC_CFG2_IPG_MASK 0x001F0000 /* Inter packet gap */ -#define AXGMAC_CFG2_IPG_SHIFT 16 -#define AXGMAC_CFG2_PAUSE_XMT 0x00008000 /* Pause transmit module */ -/* Enable IPG extension algorithm */ -#define AXGMAC_CFG2_IPG_EXTEN 0x00000020 -#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F /* IPG extension */ - -/* A-XGMAC Configuration Register 3 */ -/* Receive frame drop filter */ -#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000 -/* Receive frame don't care filter */ -#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF - -/* A-XGMAC Station Address Register - Octets 1-4 */ -#define AXGMAC_SARLOW_OCTET_ONE 0xFF000000 /* First octet */ -#define AXGMAC_SARLOW_OCTET_TWO 0x00FF0000 /* Second octet */ -#define AXGMAC_SARLOW_OCTET_THREE 0x0000FF00 /* Third octet */ -#define AXGMAC_SARLOW_OCTET_FOUR 0x000000FF /* Fourth octet */ - -/* A-XGMAC Station Address Register - Octets 5-6 */ -#define AXGMAC_SARHIGH_OCTET_FIVE 0xFF000000 /* Fifth octet */ -#define AXGMAC_SARHIGH_OCTET_SIX 0x00FF0000 /* Sixth octet */ - -/* A-XGMAC Maximum frame length register */ -/* Maximum transmit frame length */ -#define AXGMAC_MAXFRAME_XMT 0x3FFF0000 -#define AXGMAC_MAXFRAME_XMT_SHIFT 16 -/* Maximum receive frame length */ -#define AXGMAC_MAXFRAME_RCV 0x0000FFFF -/* - * This register doesn't need to be written for standard MTU. - * For jumbo, I'll just statically define the value here. This - * value sets the receive byte count to 9036 (0x234C) and the - * transmit WORD count to 2259 (0x8D3). These values include 22 - * bytes of padding beyond the jumbo MTU of 9014 - */ -#define AXGMAC_MAXFRAME_JUMBO 0x08D3234C - -/* A-XGMAC Revision level */ -#define AXGMAC_REVISION_MASK 0x0000FFFF /* Revision level */ - -/* A-XGMAC AMIIM Command Register */ -#define AXGMAC_AMIIM_CMD_START 0x00000008 /* Command start */ -#define AXGMAC_AMIIM_CMD_MASK 0x00000007 /* Command */ -/* 10/100/1000 Mbps Phy Write */ -#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1 -/* 10/100/1000 Mbps Phy Read */ -#define AXGMAC_AMIIM_CMD_LEGACY_READ 2 -#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 /* Monitor single PHY */ -/* Monitor multiple contiguous PHYs */ -#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4 -/* Present AMIIM Field Reg */ -#define AXGMAC_AMIIM_CMD_10G_OPERATION 5 -/* Clear Link Fail Bit in MIIM */ -#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6 - -/* A-XGMAC AMIIM Field Register */ -#define AXGMAC_AMIIM_FIELD_ST 0xC0000000 /* 2-bit ST field */ -#define AXGMAC_AMIIM_FIELD_ST_SHIFT 30 -#define AXGMAC_AMIIM_FIELD_OP 0x30000000 /* 2-bit OP field */ -#define AXGMAC_AMIIM_FIELD_OP_SHIFT 28 -/* Port address field (hstphyadx in spec) */ -#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000 -#define AXGMAC_AMIIM_FIELD_PORT_SHIFT 23 -/* Device address field (hstregadx in spec) */ -#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000 -#define AXGMAC_AMIIM_FIELD_DEV_SHIFT 18 -#define AXGMAC_AMIIM_FIELD_TA 0x00030000 /* 2-bit TA field */ -#define AXGMAC_AMIIM_FIELD_TA_SHIFT 16 -#define AXGMAC_AMIIM_FIELD_DATA 0x0000FFFF /* Data field */ - -/* Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register */ -#define MIIM_OP_ADDR 0 /* MIIM Address set operation */ -#define MIIM_OP_WRITE 1 /* MIIM Write register operation */ -#define MIIM_OP_READ 2 /* MIIM Read register operation */ -#define MIIM_OP_ADDR_SHIFT (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) - -/* - * Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM - * Field Register - */ -#define MIIM_PORT_NUM 1 /* All Sahara MIIM modules use port 1 */ - -/* - * Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM - * Field Register - */ -/* PHY PMA/PMD module MIIM device number */ -#define MIIM_DEV_PHY_PMA 1 -/* PHY PCS module MIIM device number */ -#define MIIM_DEV_PHY_PCS 3 -/* PHY XS module MIIM device number */ -#define MIIM_DEV_PHY_XS 4 -#define MIIM_DEV_XGXS 5 /* XGXS MIIM device number */ - -/* - * Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field - * Register - */ -#define MIIM_TA_10GB 2 /* set to 2 for 10 GB operation */ - -/* A-XGMAC AMIIM Configuration Register */ -/* Bypass preamble of mngmt frame */ -#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080 -/* half-clock duration of MDC output */ -#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F - -/* A-XGMAC AMIIM Indicator Register */ -/* Link status from legacy PHY or MMD */ -#define AXGMAC_AMIIM_INDC_LINK 0x00000010 -/* Multiple phy operation in progress */ -#define AXGMAC_AMIIM_INDC_MPHY 0x00000008 -/* Single phy operation in progress */ -#define AXGMAC_AMIIM_INDC_SPHY 0x00000004 -/* Single or multiple monitor cmd */ -#define AXGMAC_AMIIM_INDC_MON 0x00000002 -/* Set until cmd operation complete */ -#define AXGMAC_AMIIM_INDC_BUSY 0x00000001 - -/* Link Status and Control Register */ -#define LS_PHY_CLR_RESET 0x80000000 /* Clear reset signal to PHY */ -#define LS_SERDES_POWER_DOWN 0x40000000 /* Power down the Sahara Serdes */ -#define LS_XGXS_ENABLE 0x20000000 /* Enable the XAUI XGXS logic */ -/* Hold XAUI XGXS logic reset until Serdes is up */ -#define LS_XGXS_CTL 0x10000000 -/* When 0, XAUI Serdes is up and initialization is complete */ -#define LS_SERDES_DOWN 0x08000000 -/* When 0, Trace Serdes is up and initialization is complete */ -#define LS_TRACE_DOWN 0x04000000 -/* Set PHY clock to 25 MHz (else 156.125 MHz) */ -#define LS_PHY_CLK_25MHZ 0x02000000 -#define LS_PHY_CLK_EN 0x01000000 /* Enable clock to PHY */ -#define LS_XAUI_LINK_UP 0x00000010 /* XAUI link is up */ -/* XAUI link status has changed */ -#define LS_XAUI_LINK_CHNG 0x00000008 -#define LS_LINK_ALARM 0x00000004 /* Link alarm pin */ -/* Mask link attention control bits */ -#define LS_ATTN_CTRL_MASK 0x00000003 -#define LS_ATTN_ALARM 0x00000000 /* 00 => Attn on link alarm */ -/* 01 => Attn on link alarm or status change */ -#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001 -/* 10 => Attn on link status change */ -#define LS_ATTN_STAT_CHNG 0x00000002 -#define LS_ATTN_NONE 0x00000003 /* 11 => no Attn */ - -/* Link Address High Registers */ -#define LINK_ADDR_ENABLE 0x80000000 /* Enable this link address */ - - -/* - * XGXS XAUI XGMII Extender registers - * - * Full register descriptions can be found in mxgxs.pdf - */ -/* XGXS Register Map */ -#define XGXS_ADDRESS_CONTROL1 0x0000 /* XS Control 1 */ -#define XGXS_ADDRESS_STATUS1 0x0001 /* XS Status 1 */ -#define XGXS_ADDRESS_DEVID_LOW 0x0002 /* XS Device ID (low) */ -#define XGXS_ADDRESS_DEVID_HIGH 0x0003 /* XS Device ID (high) */ -#define XGXS_ADDRESS_SPEED 0x0004 /* XS Speed ability */ -#define XGXS_ADDRESS_DEV_LOW 0x0005 /* XS Devices in package */ -#define XGXS_ADDRESS_DEV_HIGH 0x0006 /* XS Devices in package */ -#define XGXS_ADDRESS_STATUS2 0x0008 /* XS Status 2 */ -#define XGXS_ADDRESS_PKGID_lOW 0x000E /* XS Package Identifier */ -#define XGXS_ADDRESS_PKGID_HIGH 0x000F /* XS Package Identifier */ -#define XGXS_ADDRESS_LANE_STATUS 0x0018 /* 10G XGXS Lane Status */ -#define XGXS_ADDRESS_TEST_CTRL 0x0019 /* 10G XGXS Test Control */ -#define XGXS_ADDRESS_RESET_LO1 0x8000 /* Vendor-Specific Reset Lo 1 */ -#define XGXS_ADDRESS_RESET_LO2 0x8001 /* Vendor-Specific Reset Lo 2 */ -#define XGXS_ADDRESS_RESET_HI1 0x8002 /* Vendor-Specific Reset Hi 1 */ -#define XGXS_ADDRESS_RESET_HI2 0x8003 /* Vendor-Specific Reset Hi 2 */ - -/* XS Control 1 register bit definitions */ -#define XGXS_CONTROL1_RESET 0x8000 /* Reset - self clearing */ -#define XGXS_CONTROL1_LOOPBACK 0x4000 /* Enable loopback */ -#define XGXS_CONTROL1_SPEED1 0x2000 /* 0 = unspecified, 1 = 10Gb+ */ -#define XGXS_CONTROL1_LOWPOWER 0x0400 /* 1 = Low power mode */ -#define XGXS_CONTROL1_SPEED2 0x0040 /* Same as SPEED1 (?) */ -/* Everything reserved except zero (?) */ -#define XGXS_CONTROL1_SPEED 0x003C - -/* XS Status 1 register bit definitions */ -#define XGXS_STATUS1_FAULT 0x0080 /* Fault detected */ -#define XGXS_STATUS1_LINK 0x0004 /* 1 = Link up */ -#define XGXS_STATUS1_LOWPOWER 0x0002 /* 1 = Low power supported */ - -/* XS Speed register bit definitions */ -#define XGXS_SPEED_10G 0x0001 /* 1 = 10G capable */ - -/* XS Devices register bit definitions */ -#define XGXS_DEVICES_DTE 0x0020 /* DTE XS Present */ -#define XGXS_DEVICES_PHY 0x0010 /* PHY XS Present */ -#define XGXS_DEVICES_PCS 0x0008 /* PCS Present */ -#define XGXS_DEVICES_WIS 0x0004 /* WIS Present */ -#define XGXS_DEVICES_PMD 0x0002 /* PMD/PMA Present */ -#define XGXS_DEVICES_CLAUSE22 0x0001 /* Clause 22 registers present*/ - -/* XS Devices High register bit definitions */ -#define XGXS_DEVICES_VENDOR2 0x8000 /* Vendor specific device 2 */ -#define XGXS_DEVICES_VENDOR1 0x4000 /* Vendor specific device 1 */ - -/* XS Status 2 register bit definitions */ -#define XGXS_STATUS2_DEV_MASK 0xC000 /* Device present mask */ -#define XGXS_STATUS2_DEV_RESPOND 0x8000 /* Device responding */ -#define XGXS_STATUS2_XMT_FAULT 0x0800 /* Transmit fault */ -#define XGXS_STATUS2_RCV_FAULT 0x0400 /* Receive fault */ - -/* XS Package ID High register bit definitions */ -#define XGXS_PKGID_HIGH_ORG 0xFC00 /* Organizationally Unique */ -#define XGXS_PKGID_HIGH_MFG 0x03F0 /* Manufacturer Model */ -#define XGXS_PKGID_HIGH_REV 0x000F /* Revision Number */ - -/* XS Lane Status register bit definitions */ -#define XGXS_LANE_PHY 0x1000 /* PHY/DTE lane alignment status */ -#define XGXS_LANE_PATTERN 0x0800 /* Pattern testing ability */ -#define XGXS_LANE_LOOPBACK 0x0400 /* PHY loopback ability */ -#define XGXS_LANE_SYNC3 0x0008 /* Lane 3 sync */ -#define XGXS_LANE_SYNC2 0x0004 /* Lane 2 sync */ -#define XGXS_LANE_SYNC1 0x0002 /* Lane 1 sync */ -#define XGXS_LANE_SYNC0 0x0001 /* Lane 0 sync */ - -/* XS Test Control register bit definitions */ -#define XGXS_TEST_PATTERN_ENABLE 0x0004 /* Test pattern enabled */ -#define XGXS_TEST_PATTERN_MASK 0x0003 /* Test patterns */ -#define XGXS_TEST_PATTERN_RSVD 0x0003 /* Test pattern - reserved */ -#define XGXS_TEST_PATTERN_MIX 0x0002 /* Test pattern - mixed */ -#define XGXS_TEST_PATTERN_LOW 0x0001 /* Test pattern - low */ -#define XGXS_TEST_PATTERN_HIGH 0x0001 /* Test pattern - high */ - -/* - * External MDIO Bus Registers - * - * Full register descriptions can be found in PHY/XENPAK/IEEE specs - */ -/* - * LASI (Link Alarm Status Interrupt) Registers (located in - * MIIM_DEV_PHY_PMA device) - */ -#define LASI_RX_ALARM_CONTROL 0x9000 /* LASI RX_ALARM Control */ -#define LASI_TX_ALARM_CONTROL 0x9001 /* LASI TX_ALARM Control */ -#define LASI_CONTROL 0x9002 /* LASI Control */ -#define LASI_RX_ALARM_STATUS 0x9003 /* LASI RX_ALARM Status */ -#define LASI_TX_ALARM_STATUS 0x9004 /* LASI TX_ALARM Status */ -#define LASI_STATUS 0x9005 /* LASI Status */ - -/* LASI_CONTROL bit definitions */ -/* Enable RX_ALARM interrupts */ -#define LASI_CTL_RX_ALARM_ENABLE 0x0004 -/* Enable TX_ALARM interrupts */ -#define LASI_CTL_TX_ALARM_ENABLE 0x0002 -/* Enable Link Status interrupts */ -#define LASI_CTL_LS_ALARM_ENABLE 0x0001 - -/* LASI_STATUS bit definitions */ -#define LASI_STATUS_RX_ALARM 0x0004 /* RX_ALARM status */ -#define LASI_STATUS_TX_ALARM 0x0002 /* TX_ALARM status */ -#define LASI_STATUS_LS_ALARM 0x0001 /* Link Status */ - -/* PHY registers - PMA/PMD (device 1) */ -#define PHY_PMA_CONTROL1 0x0000 /* PMA/PMD Control 1 */ -#define PHY_PMA_STATUS1 0x0001 /* PMA/PMD Status 1 */ -#define PHY_PMA_RCV_DET 0x000A /* PMA/PMD Receive Signal Detect */ - /* other PMA/PMD registers exist and can be defined as needed */ - -/* PHY registers - PCS (device 3) */ -#define PHY_PCS_CONTROL1 0x0000 /* PCS Control 1 */ -#define PHY_PCS_STATUS1 0x0001 /* PCS Status 1 */ -#define PHY_PCS_10G_STATUS1 0x0020 /* PCS 10GBASE-R Status 1 */ - /* other PCS registers exist and can be defined as needed */ - -/* PHY registers - XS (device 4) */ -#define PHY_XS_CONTROL1 0x0000 /* XS Control 1 */ -#define PHY_XS_STATUS1 0x0001 /* XS Status 1 */ -#define PHY_XS_LANE_STATUS 0x0018 /* XS Lane Status */ - /* other XS registers exist and can be defined as needed */ - -/* PHY_PMA_CONTROL1 register bit definitions */ -#define PMA_CONTROL1_RESET 0x8000 /* PMA/PMD reset */ - -/* PHY_PMA_RCV_DET register bit definitions */ -#define PMA_RCV_DETECT 0x0001 /* PMA/PMD receive signal detect */ - -/* PHY_PCS_10G_STATUS1 register bit definitions */ -#define PCS_10B_BLOCK_LOCK 0x0001 /* PCS 10GBASE-R locked to receive blocks */ - -/* PHY_XS_LANE_STATUS register bit definitions */ -#define XS_LANE_ALIGN 0x1000 /* XS transmit lanes aligned */ - -#define XCVR_VENDOR_LEN 16 /* xcvr vendor len */ -#define XCVR_MODEL_LEN 16 /* xcvr model len */ - -/* PHY Microcode download data structure */ -struct phy_ucode { - ushort Addr; - ushort Data; -}; - -/* Slow Bus Register Definitions */ - -/* Module 0 registers */ -#define GPIO_L_IN 0x15 /* GPIO input (low) */ -#define GPIO_L_OUT 0x16 /* GPIO output (low) */ -#define GPIO_L_DIR 0x17 /* GPIO direction (low) */ -#define GPIO_H_IN 0x19 /* GPIO input (high) */ -#define GPIO_H_OUT 0x1A /* GPIO output (high) */ -#define GPIO_H_DIR 0x1B /* GPIO direction (high) */ - -/* Definitions for other slow bus registers can be added as needed */ - - -/* - * Transmit Sequencer Command Descriptor definitions - * - * This descriptor must be placed in GRAM. The address of this descriptor - * (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ - * (Proxy high or low command queue). This data is read by the Proxy Sequencer, - * which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit - * Sequencer, causing a packet to be transmitted. Not all fields are valid for - * all commands - see the Sahara spec for details. Note that this structure is - * only valid when compiled on a little endian machine. - */ -#pragma pack(push, 1) -struct xmt_desc { - ushort XmtLen; /* word 0, bits [15:0] - transmit length */ - /* word 0, bits [23:16] - transmit control byte */ - unsigned char XmtCtl; - /* word 0, bits [31:24] - transmit command plus misc. */ - unsigned char Cmd; - /* word 1, bits [31:0] - transmit buffer ID */ - u32 XmtBufId; - /* word 2, bits [7:0] - byte address of TCP header */ - unsigned char TcpStrt; - /* word 2, bits [15:8] - byte address of IP header */ - unsigned char IpStrt; - /* word 2, bits [31:16] - partial IP checksum */ - ushort IpCkSum; - /* word 3, bits [15:0] - partial TCP checksum */ - ushort TcpCkSum; - ushort Rsvd1; /* word 3, bits [31:16] - PAD */ - u32 Rsvd2; /* word 4, bits [31:0] - PAD */ - u32 Rsvd3; /* word 5, bits [31:0] - PAD */ - u32 Rsvd4; /* word 6, bits [31:0] - PAD */ - u32 Rsvd5; /* word 7, bits [31:0] - PAD */ -}; -#pragma pack(pop) - -/* struct xmt_desc Cmd byte definitions */ - /* command codes */ -#define XMT_DESC_CMD_RAW_SEND 0 /* raw send descriptor */ -#define XMT_DESC_CMD_CSUM_INSERT 1 /* checksum insert descriptor */ -#define XMT_DESC_CMD_FORMAT 2 /* format descriptor */ -#define XMT_DESC_CMD_PRIME 3 /* prime descriptor */ -/* comand code shift (shift to bits [31:30] in word 0) */ -#define XMT_DESC_CMD_CODE_SHFT 6 - /* shifted command codes */ -#define XMT_RAW_SEND (XMT_DESC_CMD_RAW_SEND << XMT_DESC_CMD_CODE_SHFT) -#define XMT_CSUM_INSERT (XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT) -#define XMT_FORMAT (XMT_DESC_CMD_FORMAT << XMT_DESC_CMD_CODE_SHFT) -#define XMT_PRIME (XMT_DESC_CMD_PRIME << XMT_DESC_CMD_CODE_SHFT) - -/* - * struct xmt_desc Control Byte (XmtCtl) definitions - * NOTE: These bits do not work on Sahara (Rev A)! - */ -/* current frame is a pause control frame (for statistics) */ -#define XMT_CTL_PAUSE_FRAME 0x80 -/* current frame is a control frame (for statistics) */ -#define XMT_CTL_CONTROL_FRAME 0x40 -#define XMT_CTL_PER_PKT_QUAL 0x20 /* per packet qualifier */ -#define XMT_CTL_PAD_MODE_NONE 0x00 /* do not pad frame */ -#define XMT_CTL_PAD_MODE_64 0x08 /* pad frame to 64 bytes */ -/* pad frame to 64 bytes, and VLAN frames to 68 bytes */ -#define XMT_CTL_PAD_MODE_VLAN_68 0x10 -#define XMT_CTL_PAD_MODE_68 0x18 /* pad frame to 68 bytes */ -/* generate FCS (CRC) for this frame */ -#define XMT_CTL_GEN_FCS 0x04 -#define XMT_CTL_DELAY_FCS_0 0x00 /* do not delay FCS calcution */ -/* delay FCS calculation by 1 (4-byte) word */ -#define XMT_CTL_DELAY_FCS_1 0x01 -/* delay FCS calculation by 2 (4-byte) words */ -#define XMT_CTL_DELAY_FCS_2 0x02 -/* delay FCS calculation by 3 (4-byte) words */ -#define XMT_CTL_DELAY_FCS_3 0x03 - -/* struct xmt_desc XmtBufId definition */ -/* - * The Xmt buffer ID is formed by dividing the buffer (DRAM) address - * by 256 (or << 8) - */ - -#define XMT_BUF_ID_SHFT 8 - -/* Receiver Sequencer Definitions */ - -/* Receive Event Queue (queues 3 - 6) bit definitions */ -/* bit mask for the Receive Buffer ID */ -#define RCV_EVTQ_RBFID_MASK 0x0000FFFF - -/* Receive Buffer ID definition */ -/* - * The Rcv buffer ID is formed by dividing the buffer (DRAM) address - * by 32 (or << 5) - */ -#define RCV_BUF_ID_SHFT 5 - -/* - * Format of the 18 byte Receive Buffer returned by the - * Receive Sequencer for received packets - */ -#pragma pack(push, 1) -struct rcv_buf_hdr { - u32 Status; /* Status word from Rcv Seq Parser */ - ushort Length; /* Rcv packet byte count */ - union { - ushort TcpCsum; /* TCP checksum */ - struct { - /* lower 8 bits of the TCP checksum */ - unsigned char TcpCsumL; - /* Link hash (multicast frames only) */ - unsigned char LinkHash; - }; - }; - ushort SktHash; /* Socket hash */ - unsigned char TcpHdrOffset; /* TCP header offset into packet */ - unsigned char IpHdrOffset; /* IP header offset into packet */ - u32 TpzHash; /* Toeplitz hash */ - ushort Reserved; /* Reserved */ -}; -#pragma pack(pop) - -/* Queue definitions */ - -/* Ingress (read only) queue numbers */ -#define PXY_BUF_Q 0 /* Proxy Buffer Queue */ -#define HST_EVT_Q 1 /* Host Event Queue */ -#define XMT_BUF_Q 2 /* Transmit Buffer Queue */ -#define SKT_EVL_Q 3 /* RcvSqr Socket Event Low Priority Queue */ -#define RCV_EVL_Q 4 /* RcvSqr Rcv Event Low Priority Queue */ -#define SKT_EVH_Q 5 /* RcvSqr Socket Event High Priority Queue */ -#define RCV_EVH_Q 6 /* RcvSqr Rcv Event High Priority Queue */ -#define DMA_RSP_Q 7 /* Dma Response Queue - one per CPU context */ -/* Local (read/write) queue numbers */ -#define LOCAL_A_Q 8 /* Spare local Queue */ -#define LOCAL_B_Q 9 /* Spare local Queue */ -#define LOCAL_C_Q 10 /* Spare local Queue */ -#define FSM_EVT_Q 11 /* Finite-State-Machine Event Queue */ -#define SBF_PAL_Q 12 /* System Buffer Physical Address (low) Queue */ -#define SBF_PAH_Q 13 /* System Buffer Physical Address (high) Queue*/ -#define SBF_VAL_Q 14 /* System Buffer Virtual Address (low) Queue */ -#define SBF_VAH_Q 15 /* System Buffer Virtual Address (high) Queue */ -/* Egress (write only) queue numbers */ -#define H2G_CMD_Q 16 /* Host to GlbRam DMA Command Queue */ -#define H2D_CMD_Q 17 /* Host to DRAM DMA Command Queue */ -#define G2H_CMD_Q 18 /* GlbRam to Host DMA Command Queue */ -#define G2D_CMD_Q 19 /* GlbRam to DRAM DMA Command Queue */ -#define D2H_CMD_Q 20 /* DRAM to Host DMA Command Queue */ -#define D2G_CMD_Q 21 /* DRAM to GlbRam DMA Command Queue */ -#define D2D_CMD_Q 22 /* DRAM to DRAM DMA Command Queue */ -#define PXL_CMD_Q 23 /* Low Priority Proxy Command Queue */ -#define PXH_CMD_Q 24 /* High Priority Proxy Command Queue */ -#define RSQ_CMD_Q 25 /* Receive Sequencer Command Queue */ -#define RCV_BUF_Q 26 /* Receive Buffer Queue */ - -/* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */ -/* enable copy of xmt descriptor to xmt command queue */ -#define PXY_COPY_EN 0x00200000 -#define PXY_SIZE_16 0x00000000 /* copy 16 bytes */ -#define PXY_SIZE_32 0x00100000 /* copy 32 bytes */ - -/* SXG EEPROM/Flash Configuration Definitions */ - -/* Location of configuration data in EEPROM or Flash */ -/* start addr for config info in EEPROM */ -#define EEPROM_CONFIG_START_ADDR 0x00 -/* start addr for config info in Flash */ -#define FLASH_CONFIG_START_ADDR 0x80 - -/* Configuration data section defines */ -#define HW_CFG_SECTION_SIZE 512 /* size of H/W section */ -#define HW_CFG_SECTION_SIZE_A 256 /* size of H/W section (Sahara rev A) */ -/* starting location (offset) of S/W section */ -#define SW_CFG_SECTION_START 512 -/* starting location (offset) of S/W section (Sahara rev A) */ -#define SW_CFG_SECTION_START_A 256 -#define SW_CFG_SECTION_SIZE 128 /* size of S/W section */ -/* - * H/W configuration data magic word Goes in Addr field of first - * struct hw_cfg_data entry - */ -#define HW_CFG_MAGIC_WORD 0xA5A5 -/* - * H/W configuration data terminator Goes in Addr field of last - * struct hw_cfg_data entry - */ -#define HW_CFG_TERMINATOR 0xFFFF - -#define SW_CFG_MAGIC_WORD 0x5A5A /* S/W configuration data magic word */ - -#pragma pack(push, 1) -/* - * Structure for an element of H/W configuration data. - * Read by the Sahara hardware - */ -struct hw_cfg_data { - ushort Addr; - ushort Data; -}; - -/* - * Number of struct hw_cfg_data structures to put in the configuration data - * data structure (struct sxg_config or struct sxg_config_a). The number is - * computed to fill the entire H/W config section of the structure. - */ -#define NUM_HW_CFG_ENTRIES \ - (HW_CFG_SECTION_SIZE / sizeof(struct hw_cfg_data)) -#define NUM_HW_CFG_ENTRIES_A \ - (HW_CFG_SECTION_SIZE_A / sizeof(struct hw_cfg_data)) - -/* MAC address structure */ -struct sxg_config_mac { - unsigned char MacAddr[6]; /* MAC Address */ -}; - -/* FRU data structure */ -struct atk_fru { - unsigned char PartNum[6]; - unsigned char Revision[2]; - unsigned char Serial[14]; -}; - -/* OEM FRU Format types */ -#define ATK_FRU_FORMAT 0x0000 -#define CPQ_FRU_FORMAT 0x0001 -#define DELL_FRU_FORMAT 0x0002 -#define HP_FRU_FORMAT 0x0003 -#define IBM_FRU_FORMAT 0x0004 -#define EMC_FRU_FORMAT 0x0005 -#define NO_FRU_FORMAT 0xFFFF - -#define ATK_OEM_ASSY_SIZE 10 /* assy num is 9 chars plus \0 */ - -/* OEM FRU structure for Alacritech */ -struct atk_oem { - unsigned char Assy[ATK_OEM_ASSY_SIZE]; -}; - -#define OEM_EEPROM_FRUSIZE 74 /* size of OEM fru info - size */ -/* chosen to fill out the S/W section */ - -union oem_fru { /* OEM FRU information */ - unsigned char OemFru[OEM_EEPROM_FRUSIZE]; - struct atk_oem AtkOem; -}; - -/* Structure to hold the S/W configuration data. */ -struct sw_cfg_data { - ushort MagicWord; /* Magic word for section 2 */ - ushort Version; /* Format version */ - struct sxg_config_mac MacAddr[4]; /* space for 4 MAC addresses */ - struct atk_fru AtkFru; /* FRU information */ - ushort OemFruFormat; /* OEM FRU format type */ - union oem_fru OemFru; /* OEM FRU information */ - ushort Checksum; /* Checksum of section 2 */ -}; - - -/* EEPROM/Flash Format */ -struct sxg_config { - /* H/W Section - Read by Sahara hardware (512 bytes) */ - struct hw_cfg_data HwCfg[NUM_HW_CFG_ENTRIES]; - /* S/W Section - Other configuration data (128 bytes) */ - struct sw_cfg_data SwCfg; -}; - -#ifdef WINDOWS_COMPILER -/* - * The following macro is something of a kludge, but it is the only way - * that I could find to catch certain programming errors at compile time. - * If the asserted condition is true, then nothing happens. If false, then - * the compiler tries to typedef an array with -1 members, which generates - * an error. Unfortunately, the error message is meaningless, but at least - * it catches the problem. This macro would be unnecessary if the compiler - * allowed the sizeof and offsetof macros to be used in the #if directive. - */ -#define compile_time_assert(cond) \ - typedef char comp_error[(cond) ? 1 : -1] - -/* - * A compiler error on either of the next two lines indicates that the struct sxg_config - * structure was built incorrectly. Unfortunately, the error message produced - * is meaningless. But this is apparently the only way to catch this problem - * at compile time. - */ -compile_time_assert (offsetof(struct sxg_config, SwCfg) == SW_CFG_SECTION_START); -compile_time_assert (sizeof(struct sxg_config) == HW_CFG_SECTION_SIZE - + SW_CFG_SECTION_SIZE); - -compile_time_assert (offsetof(struct sxg_config_a, SwCfg) - == SW_CFG_SECTION_START_A); -compile_time_assert (sizeof(struct sxg_config_a) == HW_CFG_SECTION_SIZE_A - + SW_CFG_SECTION_SIZE); -#endif -/* - * Structure used to pass information between driver and user-mode - * control application - */ -struct adapt_userinfo { - bool LinkUp; - /* use LinkUp - any need for other states? */ - /* u32 LinkState; */ - u32 LinkSpeed; /* not currently needed */ - u32 LinkDuplex; /* not currently needed */ - enum xcvr_type XcvrType; /* type of xcvr on fiber card */ - /* fiber card xcvr vendor */ - unsigned char XcvrVendor[XCVR_VENDOR_LEN]; - unsigned char XcvrMode[XCVR_MODEL_LEN]; - u32 Port; /* not currently needed */ - u32 PhysPort; /* not currently needed */ - ushort PciLanes; - unsigned char MacAddr[6]; - unsigned char CurrMacAddr[6]; - struct atk_fru AtkFru; - ushort OemFruFormat; - union oem_fru OemFru; -}; - -#pragma pack(pop) - -/* Miscellaneous Hardware definitions */ - -/* Hardware Type definitions */ - -/* Sahara (ASIC level) defines */ -#define SAHARA_GRAM_SIZE 0x020000 /* GRAM size - 128 KB */ -#define SAHARA_DRAM_SIZE 0x200000 /* DRAM size - 2 MB */ -/* QRAM size - 16K entries (64 KB) */ -#define SAHARA_QRAM_SIZE 0x004000 -/* WCS - 8K instructions (x 108 bits) */ -#define SAHARA_WCS_SIZE 0x002000 - -/* Arabia (board level) defines */ -#define FLASH_SIZE 0x080000 /* 512 KB (4 Mb) */ -/* EEPROM size (bytes), including xfmr area */ -#define EEPROM_SIZE_XFMR 1024 -/* EEPROM size excluding xfmr area (512 + 128) */ -#define EEPROM_SIZE_NO_XFMR 640 -/* EEPROM size for Sahara rev A */ -#define EEPROM_SIZE_REV_A 512 diff --git a/drivers/staging/sxg/sxgphycode-1.2.h b/drivers/staging/sxg/sxgphycode-1.2.h deleted file mode 100644 index b5448b9b278..00000000000 --- a/drivers/staging/sxg/sxgphycode-1.2.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright ? 1997-2008 Alacritech, Inc. All rights reserved - * - * $Id: sxgphycode.h,v 1.2 2008/10/02 01:44:07 Exp $ - * - * sxgphycode.h: - * - * This file PHY microcode and register initialization data. - */ - -/********************************************************************** - * PHY Microcode - **********************************************************************/ -// -// The following contains both PHY microcode and PHY register -// initialization data. It is specific to both the PHY and the -// type of transceiver. -// - -// Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR) -// AEL2005 SR firmware rev 18 (microInit_mdio_SR_AEL2005C_18.tx). -static struct phy_ucode PhyUcode[] = { - // NOTE: An address of 0 is a special case. When the download routine - // sees an address of 0, it does not write to the PHY. Instead, it delays - // the download. The length of the delay (in ms) is given in the data field. - // Delays are required at certain points. - - // Platform-specific MDIO Patches: - // (include patches for 10G RX polarity flip, 50Mhz Synth, etc) - // Addr Data - {0xc017, 0xfeb0}, // flip RX_LOS polarity (mandatory patch for SFP+ applications) - {0xC001, 0x0428}, // flip RX serial polarity - - {0xc013, 0xf341}, // invert lxmit clock (mandatory patch) - {0xc210, 0x8000}, // reset datapath (mandatory patch) - {0xc210, 0x8100}, // reset datapath (mandatory patch) - {0xc210, 0x8000}, // reset datapath (mandatory patch) - {0xc210, 0x0000}, // reset datapath (mandatory patch) - {0x0000, 0x0032}, // wait for 50ms for datapath reset to complete. (mandatory patch) - - // Transceiver-specific MDIO Patches: - {0xc003, 0x0181}, // (bit 7) enable the CDR inc setting in 1.C005 (mandatory patch for SR code) - {0xc010, 0x448a}, // (bit 14) mask out high BER input from the LOS signal in 1.000A (mandatory patch for SR code) - - // Transceiver-specific Microcontroller Initialization: - {0xc04a, 0x5200}, // activate microcontroller and pause - {0x0000, 0x0032}, // wait 50ms for microcontroller before writing in code. - - // code block starts here: - {0xcc00, 0x2ff4}, {0xcc01, 0x3cd4}, {0xcc02, 0x2015}, {0xcc03, 0x3125}, - {0xcc04, 0x6524}, {0xcc05, 0x27ff}, {0xcc06, 0x300f}, {0xcc07, 0x2c8b}, - {0xcc08, 0x300b}, {0xcc09, 0x4009}, {0xcc0a, 0x400e}, {0xcc0b, 0x2f12}, - {0xcc0c, 0x3002}, {0xcc0d, 0x1002}, {0xcc0e, 0x2112}, {0xcc0f, 0x3012}, - {0xcc10, 0x1002}, {0xcc11, 0x2572}, {0xcc12, 0x3012}, {0xcc13, 0x1002}, - {0xcc14, 0xd01e}, {0xcc15, 0x2772}, {0xcc16, 0x3012}, {0xcc17, 0x1002}, - {0xcc18, 0x2004}, {0xcc19, 0x3c84}, {0xcc1a, 0x6436}, {0xcc1b, 0x2007}, - {0xcc1c, 0x3f87}, {0xcc1d, 0x8676}, {0xcc1e, 0x40b7}, {0xcc1f, 0xa746}, - {0xcc20, 0x4047}, {0xcc21, 0x5673}, {0xcc22, 0x2982}, {0xcc23, 0x3002}, - {0xcc24, 0x13d2}, {0xcc25, 0x8bbd}, {0xcc26, 0x2802}, {0xcc27, 0x3012}, - {0xcc28, 0x1002}, {0xcc29, 0x2032}, {0xcc2a, 0x3012}, {0xcc2b, 0x1002}, - {0xcc2c, 0x5cc3}, {0xcc2d, 0x0314}, {0xcc2e, 0x2942}, {0xcc2f, 0x3002}, - {0xcc30, 0x1002}, {0xcc31, 0xd019}, {0xcc32, 0x2fd2}, {0xcc33, 0x3002}, - {0xcc34, 0x1002}, {0xcc35, 0x2a04}, {0xcc36, 0x3c74}, {0xcc37, 0x6435}, - {0xcc38, 0x2fa4}, {0xcc39, 0x3cd4}, {0xcc3a, 0x6624}, {0xcc3b, 0x5563}, - {0xcc3c, 0x2d42}, {0xcc3d, 0x3002}, {0xcc3e, 0x13d2}, {0xcc3f, 0x464d}, - {0xcc40, 0x2802}, {0xcc41, 0x3012}, {0xcc42, 0x1002}, {0xcc43, 0x2fd2}, - {0xcc44, 0x3002}, {0xcc45, 0x1002}, {0xcc46, 0x2fb4}, {0xcc47, 0x3cd4}, - {0xcc48, 0x6624}, {0xcc49, 0x5563}, {0xcc4a, 0x2d42}, {0xcc4b, 0x3002}, - {0xcc4c, 0x13d2}, {0xcc4d, 0x2e72}, {0xcc4e, 0x3002}, {0xcc4f, 0x1002}, - {0xcc50, 0x2f72}, {0xcc51, 0x3002}, {0xcc52, 0x1002}, {0xcc53, 0x0004}, - {0xcc54, 0x2942}, {0xcc55, 0x3002}, {0xcc56, 0x1002}, {0xcc57, 0x2032}, - {0xcc58, 0x3012}, {0xcc59, 0x1002}, {0xcc5a, 0x5cc3}, {0xcc5b, 0x0317}, - {0xcc5c, 0x2f12}, {0xcc5d, 0x3002}, {0xcc5e, 0x1002}, {0xcc5f, 0x2942}, - {0xcc60, 0x3002}, {0xcc61, 0x1002}, {0xcc62, 0x22cd}, {0xcc63, 0x301d}, - {0xcc64, 0x2802}, {0xcc65, 0x3012}, {0xcc66, 0x1002}, {0xcc67, 0x20b2}, - {0xcc68, 0x3012}, {0xcc69, 0x1002}, {0xcc6a, 0x5aa3}, {0xcc6b, 0x2dc2}, - {0xcc6c, 0x3002}, {0xcc6d, 0x1312}, {0xcc6e, 0x2d02}, {0xcc6f, 0x3002}, - {0xcc70, 0x1002}, {0xcc71, 0x2807}, {0xcc72, 0x31a7}, {0xcc73, 0x20c4}, - {0xcc74, 0x3c24}, {0xcc75, 0x6724}, {0xcc76, 0x1002}, {0xcc77, 0x2807}, - {0xcc78, 0x3187}, {0xcc79, 0x20c4}, {0xcc7a, 0x3c24}, {0xcc7b, 0x6724}, - {0xcc7c, 0x1002}, {0xcc7d, 0x2514}, {0xcc7e, 0x3c64}, {0xcc7f, 0x6436}, - {0xcc80, 0xdff4}, {0xcc81, 0x6436}, {0xcc82, 0x1002}, {0xcc83, 0x40a4}, - {0xcc84, 0x643c}, {0xcc85, 0x4016}, {0xcc86, 0x8c6c}, {0xcc87, 0x2b24}, - {0xcc88, 0x3c24}, {0xcc89, 0x6435}, {0xcc8a, 0x1002}, {0xcc8b, 0x2b24}, - {0xcc8c, 0x3c24}, {0xcc8d, 0x643a}, {0xcc8e, 0x4025}, {0xcc8f, 0x8a5a}, - {0xcc90, 0x1002}, {0xcc91, 0x26d1}, {0xcc92, 0x3011}, {0xcc93, 0x1001}, - {0xcc94, 0xc7a0}, {0xcc95, 0x0100}, {0xcc96, 0xc502}, {0xcc97, 0x53ac}, - {0xcc98, 0xc503}, {0xcc99, 0xd5d5}, {0xcc9a, 0xc600}, {0xcc9b, 0x2a6d}, - {0xcc9c, 0xc601}, {0xcc9d, 0x2a4c}, {0xcc9e, 0xc602}, {0xcc9f, 0x0111}, - {0xcca0, 0xc60c}, {0xcca1, 0x5900}, {0xcca2, 0xc710}, {0xcca3, 0x0700}, - {0xcca4, 0xc718}, {0xcca5, 0x0700}, {0xcca6, 0xc720}, {0xcca7, 0x4700}, - {0xcca8, 0xc801}, {0xcca9, 0x7f50}, {0xccaa, 0xc802}, {0xccab, 0x7760}, - {0xccac, 0xc803}, {0xccad, 0x7fce}, {0xccae, 0xc804}, {0xccaf, 0x5700}, - {0xccb0, 0xc805}, {0xccb1, 0x5f11}, {0xccb2, 0xc806}, {0xccb3, 0x4751}, - {0xccb4, 0xc807}, {0xccb5, 0x57e1}, {0xccb6, 0xc808}, {0xccb7, 0x2700}, - {0xccb8, 0xc809}, {0xccb9, 0x0000}, {0xccba, 0xc821}, {0xccbb, 0x0002}, - {0xccbc, 0xc822}, {0xccbd, 0x0014}, {0xccbe, 0xc832}, {0xccbf, 0x1186}, - {0xccc0, 0xc847}, {0xccc1, 0x1e02}, {0xccc2, 0xc013}, {0xccc3, 0xf341}, - {0xccc4, 0xc01a}, {0xccc5, 0x0446}, {0xccc6, 0xc024}, {0xccc7, 0x1000}, - {0xccc8, 0xc025}, {0xccc9, 0x0a00}, {0xccca, 0xc026}, {0xcccb, 0x0c0c}, - {0xcccc, 0xc027}, {0xcccd, 0x0c0c}, {0xccce, 0xc029}, {0xcccf, 0x00a0}, - {0xccd0, 0xc030}, {0xccd1, 0x0a00}, {0xccd2, 0xc03c}, {0xccd3, 0x001c}, - {0xccd4, 0xc005}, {0xccd5, 0x7a06}, {0xccd6, 0x0000}, {0xccd7, 0x26d1}, - {0xccd8, 0x3011}, {0xccd9, 0x1001}, {0xccda, 0xc620}, {0xccdb, 0x0000}, - {0xccdc, 0xc621}, {0xccdd, 0x003f}, {0xccde, 0xc622}, {0xccdf, 0x0000}, - {0xcce0, 0xc623}, {0xcce1, 0x0000}, {0xcce2, 0xc624}, {0xcce3, 0x0000}, - {0xcce4, 0xc625}, {0xcce5, 0x0000}, {0xcce6, 0xc627}, {0xcce7, 0x0000}, - {0xcce8, 0xc628}, {0xcce9, 0x0000}, {0xccea, 0xc62c}, {0xcceb, 0x0000}, - {0xccec, 0x0000}, {0xcced, 0x2806}, {0xccee, 0x3cb6}, {0xccef, 0xc161}, - {0xccf0, 0x6134}, {0xccf1, 0x6135}, {0xccf2, 0x5443}, {0xccf3, 0x0303}, - {0xccf4, 0x6524}, {0xccf5, 0x000b}, {0xccf6, 0x1002}, {0xccf7, 0x2104}, - {0xccf8, 0x3c24}, {0xccf9, 0x2105}, {0xccfa, 0x3805}, {0xccfb, 0x6524}, - {0xccfc, 0xdff4}, {0xccfd, 0x4005}, {0xccfe, 0x6524}, {0xccff, 0x1002}, - {0xcd00, 0x5dd3}, {0xcd01, 0x0306}, {0xcd02, 0x2ff7}, {0xcd03, 0x38f7}, - {0xcd04, 0x60b7}, {0xcd05, 0xdffd}, {0xcd06, 0x000a}, {0xcd07, 0x1002}, - {0xcd08, 0x0000}, - // end of code block - - // Unpause the microcontroller to start program - {0xca00, 0x0080}, - {0xca12, 0x0000}, - {0x0000, 0x000A}, // wait 10ms just to be safe - - // Configure the LED's - {0xc214, 0x0099}, // configure the LED drivers (for Sahara rev B) - {0xc216, 0x0400}, // configure the one LED - {0xc217, 0x0000}, // don't drive the 2nd LED (if it exists) - - {0xffff, 0xffff} // table terminator -}; -- cgit v1.2.3 From df72f32ae2eebb1d8cd3994ec7b54344f4164c68 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Sep 2009 12:15:15 -0300 Subject: cx25821: Add driver to the building system Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/cx25821/Makefile | 1 + 3 files changed, 4 insertions(+) (limited to 'drivers/staging/Kconfig') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 10d3fcffe91..82b34893e5b 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -47,6 +47,8 @@ source "drivers/staging/slicoss/Kconfig" source "drivers/staging/go7007/Kconfig" +source "drivers/staging/cx25821/Kconfig" + source "drivers/staging/usbip/Kconfig" source "drivers/staging/winbond/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c30093bae62..b1cad0d9ba7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_STAGING) += staging.o obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ +obj-$(CONFIG_VIDEO_CX25821) += cx25821/ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile index 020d8440493..14b3af1e71e 100644 --- a/drivers/staging/cx25821/Makefile +++ b/drivers/staging/cx25821/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_VIDEO_CX25821) += cx25821.o obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -Idrivers/media/common/tuners EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -- cgit v1.2.3